From c5ebd86cd9dacc368ae4b09af04fdac1b66cfb6f Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Thu, 12 Apr 2018 14:30:17 -0500 Subject: [PATCH 0001/1415] MAGETWO-88391: [MFTF CE Tests] EnabledWYSIWYG and DisabledWYSIWYG action groups should not use hardcoded backend name - Updated ActionGroup to use non-hardcoded paths --- .../Config/ActionGroup/ConfigWYSIWYGActionGroup.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml index 11d7acc61d75e..6867efd81c7ba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -9,7 +9,7 @@ - + @@ -20,7 +20,7 @@ - + From bd52ab0f98bc97c0cf7491569a3f5fd9fa86ed49 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 13 Apr 2018 08:17:09 -0500 Subject: [PATCH 0002/1415] MAGETWO-87436: Unstable Mainline Test Magento\SalesRule\Model\Rule\Condition\ProductTest::testValidateCategorySalesRuleIncludesChildren - Unskipped unstable test to try and reproduce on Bamboo --- .../Magento/SalesRule/Model/Rule/Condition/ProductTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php index 158cc3da2d0cd..7fe55499bf26e 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php @@ -28,14 +28,13 @@ protected function setUp() * @magentoAppIsolation enabled * @param int $categoryId * @param bool $expectedResult + * + * @magentoDataFixture Magento/ConfigurableProduct/_files/quote_with_configurable_product.php + * @magentoDataFixture Magento/SalesRule/_files/rules_category.php * @dataProvider validateProductConditionDataProvider */ public function testValidateCategorySalesRuleIncludesChildren($categoryId, $expectedResult) { - //* @magentoDataFixture Magento/ConfigurableProduct/_files/quote_with_configurable_product.php - //* @magentoDataFixture Magento/SalesRule/_files/rules_category.php - $this->markTestSkipped('MAGETWO-87436'); - // Load the quote that contains a child of a configurable product /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class) From 0748adac26f171f8daba87b70d36176ef5b82ade Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar Date: Sat, 12 May 2018 13:28:48 +0200 Subject: [PATCH 0003/1415] Drop foreign key referencing admin_user table from bulk operations. Pass the Web API user id taken from the context object to MassScheduler --- .../AsynchronousOperations/Model/MassSchedule.php | 14 +++++++++++++- .../AsynchronousOperations/etc/db_schema.xml | 4 +--- .../etc/db_schema_whitelist.json | 1 - 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index 2d516e82f4016..f722927e452a9 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -18,6 +18,7 @@ use Magento\Framework\Exception\BulkException; use Psr\Log\LoggerInterface; use Magento\AsynchronousOperations\Model\ResourceModel\Operation\OperationRepository; +use Magento\Authorization\Model\UserContextInterface; /** * Class MassSchedule used for adding multiple entities as Operations to Bulk Management with the status tracking @@ -54,6 +55,11 @@ class MassSchedule */ private $operationRepository; + /** + * @var \Magento\Webapi\Model\Authorization\TokenUserContext + */ + private $userContext; + /** * Initialize dependencies. * @@ -70,7 +76,8 @@ public function __construct( AsyncResponseInterfaceFactory $asyncResponseFactory, BulkManagementInterface $bulkManagement, LoggerInterface $logger, - OperationRepository $operationRepository + OperationRepository $operationRepository, + UserContextInterface $userContext ) { $this->identityService = $identityService; $this->itemStatusInterfaceFactory = $itemStatusInterfaceFactory; @@ -78,6 +85,7 @@ public function __construct( $this->bulkManagement = $bulkManagement; $this->logger = $logger; $this->operationRepository = $operationRepository; + $this->userContext = $userContext; } /** @@ -95,6 +103,10 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $ { $bulkDescription = __('Topic %1', $topicName); + if ($userId == null) { + $userId = $this->userContext->getUserId(); + } + if ($groupId == null) { $groupId = $this->identityService->generateId(); diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 1b99ce9a2805f..a3acb7897580f 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -14,7 +14,7 @@ + comment="ID of the WebAPI user that performed an action"/> @@ -23,8 +23,6 @@ - diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json index 396e443355d8f..6b18ac3e29d43 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json @@ -10,7 +10,6 @@ }, "constraint": { "PRIMARY": true, - "MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID": true, "MAGENTO_BULK_UUID": true } }, From 55fb63667d51f416dd5cf7b31f92a84474fbeb04 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar Date: Sat, 12 May 2018 15:15:32 +0200 Subject: [PATCH 0004/1415] Drop foreign key referencing admin_user table from bulk operations. Pass the Web API user id taken from the context object to MassScheduler --- app/code/Magento/AsynchronousOperations/Model/MassSchedule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index f722927e452a9..5f792d1729ca4 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -56,7 +56,7 @@ class MassSchedule private $operationRepository; /** - * @var \Magento\Webapi\Model\Authorization\TokenUserContext + * @var \Magento\Authorization\Model\UserContextInterface */ private $userContext; From 3feda05339677a30590230745619db035781752d Mon Sep 17 00:00:00 2001 From: Mobecls Date: Fri, 8 Jun 2018 17:16:42 +0300 Subject: [PATCH 0005/1415] 14294 - Fixes 'back' functionality after switching a store view. --- .../Store/view/frontend/templates/switch/languages.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 80152dbb9a08f..6d041a9e22c5d 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ getStores() as $_lang): ?> getId() != $block->getCurrentStoreId()): ?>
  • - + escapeHtml($_lang->getName()) ?>
  • From 4e7c3cbd5d64d299965ff258cab84b11c3d6379d Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Tue, 19 Jun 2018 15:36:06 -0500 Subject: [PATCH 0006/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some --- app/code/Magento/Sales/Model/Order/Item.php | 2 +- app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index d2f5f5ce56692..7fa2f61554563 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -232,7 +232,7 @@ public function getQtyToShip() */ public function getSimpleQtyToShip() { - $qty = $this->getQtyOrdered() - $this->getQtyShipped() - $this->getQtyRefunded() - $this->getQtyCanceled(); + $qty = $this->getQtyOrdered() - $this->getQtyShipped() - $this->getQtyCanceled(); return max(round($qty, 8), 0); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php index 39fffa23dc1ec..956152d2e0858 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php @@ -292,14 +292,14 @@ public function getItemQtyVariants() 'qty_ordered' => 12, 'qty_invoiced' => 5, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 7.0] + 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 7.0] ], 'partially_refunded' => [ 'options' => [ 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 0.0] + 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 0.0] ], 'partially_shipped' => [ 'options' => [ @@ -313,7 +313,7 @@ public function getItemQtyVariants() 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 4, 'qty_canceled' => 0 ], - 'expectedResult' => ['to_ship' => 3.0, 'to_invoice' => 0.0] + 'expectedResult' => ['to_ship' => 8.0, 'to_invoice' => 0.0] ], 'complete' => [ 'options' => [ @@ -334,7 +334,7 @@ public function getItemQtyVariants() 'qty_ordered' => 4.4, 'qty_invoiced' => 0.4, 'qty_refunded' => 0.4, 'qty_shipped' => 4, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 4.0] + 'expectedResult' => ['to_ship' => 0.4, 'to_invoice' => 4.0] ], 'completely_invoiced_using_decimals' => [ 'options' => [ From a73786b1a1342f43977af2f7ad01fd402c77cfd4 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Wed, 27 Jun 2018 16:26:09 -0500 Subject: [PATCH 0007/1415] MAGETWO-60034: Cannot ship remaining items nan order for several of one product if credit memo is made for some - added functional test --- ...inAbleToShipPartiallyInvoicedItemsTest.xml | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml new file mode 100644 index 0000000000000..0f5346e619a09 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -0,0 +1,76 @@ + + + + + + + <description value="Admin should not be able to submit orders without an email address"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-60034"/> + <group value="sales"/> + + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + <!--Create order via Admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <comment userInput="Admin creates order" stepKey="adminCreateOrderComment"/> + <!--<actionGroup ref="navigateToNewOrderPageNewCustomer" stepKey="navigateToNewOrderPage"/>--> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderIndexPage"/> + <waitForPageLoad stepKey="waitForIndexPageLoad"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Orders" stepKey="seeIndexPageTitle"/> + <click selector="{{AdminOrdersGridSection.createNewOrder}}" stepKey="clickCreateNewOrder"/> + <click selector="{{AdminOrderFormActionSection.CreateNewCustomer}}" stepKey="clickCreateCustomer"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Create New Order" stepKey="seeNewOrderPageTitle"/> + <!--<actionGroup ref="checkRequiredFieldsNewOrderForm" stepKey="checkRequiredFieldsNewOrder" after="seeNewOrderPageTitle"/>--> + <!--<scrollToTopOfPage stepKey="scrollToTopOfOrderFormPage" after="checkRequiredFieldsNewOrder"/>--> + <actionGroup ref="addSimpleProductToOrderWithCustomQuantity" stepKey="addSimpleProductToOrderWithUserDefinedQty"> + <argument name="product" value="_defaultProduct"/> + <argument name="quantity" value="10"/> + </actionGroup> + + <!--Fill customer group and customer email which both are now required fields--> + <selectOption selector="{{AdminOrderFormAccountSection.group}}" userInput="{{GeneralCustomerGroup.code}}" stepKey="selectCustomerGroup" after="addSimpleProductToOrder"/> + <fillField selector="{{AdminOrderFormAccountSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail" after="selectCustomerGroup"/> + + <!--Fill customer address information--> + <actionGroup ref="fillOrderCustomerInformation" stepKey="fillCustomerAddress" after="fillCustomerEmail"> + <argument name="customer" value="Simple_US_Customer"/> + <argument name="address" value="US_Address_TX"/> + </actionGroup> + <!-- Select shipping --> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping" after="fillCustomerAddress"/> + + <!--Verify totals on Order page--> + <see selector="{{AdminOrderFormTotalSection.total('Subtotal')}}" userInput="$1230.00" stepKey="seeOrderSubTotal" after="selectFlatRateShipping"/> + <see selector="{{AdminOrderFormTotalSection.total('Shipping')}}" userInput="$50.00" stepKey="seeOrderShipping" after="seeOrderSubTotal"/> + <scrollTo selector="{{AdminOrderFormTotalSection.grandTotal}}" stepKey="scrollToOrderGrandTotal"/> + <see selector="{{AdminOrderFormTotalSection.grandTotal}}" userInput="$1280.00" stepKey="seeCorrectGrandTotal" after="scrollToOrderGrandTotal"/> + + <!--Submit Order and verify information--> + <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="seeCorrectGrandTotal"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPage" after="clickSubmitOrder"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeSuccessMessage" after="seeViewOrderPage"/> + <scrollTo selector="{{AdminOrderItemsOrderedSection.qtyColumn}}" stepKey="scrollToItemsOrdered" after="seeSuccessMessage"/> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Ordered 10" stepKey="seeQtyOfItemsOrdered" after="scrollToItemsOrdered"/> + + + + </test> +</tests> + From 228eaee9f918a136994c54a6e5e3e4eb1269ef4b Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Thu, 28 Jun 2018 15:27:52 -0500 Subject: [PATCH 0008/1415] MAGETWO-60034: Cannot ship remaining items nan order for several of one product if credit memo is made for some - added functional test and updated actionGroup --- .../ActionGroup/AdminOrderActionGroup.xml | 18 +++ ...inAbleToShipPartiallyInvoicedItemsTest.xml | 109 ++++++++++++++++-- .../Section/AdminShipmentItemsSection.xml | 2 +- 3 files changed, 120 insertions(+), 9 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml index 7461d9010a024..a27ee27c0b8c3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml @@ -60,6 +60,24 @@ <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickAddSelectedProducts"/> </actionGroup> + <!--Add a simple product to order with user defined quantity--> + <actionGroup name="addSimpleProductToOrderWithCustomQuantity"> + <arguments> + <argument name="product" defaultValue="_defaultProduct"/> + <argument name="quantity" type="string"/> + </arguments> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMastToDisappear"/> + <waitForElementVisible selector="{{AdminOrderFormItemsSection.addProducts}}" stepKey="waitForAddProductButton"/> + <click selector="{{AdminOrderFormItemsSection.addProducts}}" stepKey="clickAddProducts"/> + <fillField selector="{{AdminOrderFormItemsSection.skuFilter}}" userInput="{{product.sku}}" stepKey="fillSkuFilter"/> + <click selector="{{AdminOrderFormItemsSection.search}}" stepKey="clickSearch"/> + <scrollTo selector="{{AdminOrderFormItemsSection.rowCheck('1')}}" x="0" y="-100" stepKey="scrollToCheckColumn"/> + <checkOption selector="{{AdminOrderFormItemsSection.rowCheck('1')}}" stepKey="selectProduct"/> + <fillField selector="{{AdminOrderFormItemsSection.rowQty('1')}}" userInput="{{quantity}}" stepKey="fillProductQty"/> + <scrollTo selector="{{AdminOrderFormItemsSection.addSelected}}" x="0" y="-100" stepKey="scrollToAddSelectedButton"/> + <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickAddSelectedProducts"/> + </actionGroup> + <!--Add configurable product to order --> <actionGroup name="addConfigurableProductToOrder"> <arguments> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index 0f5346e619a09..c477fabe04828 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -27,25 +27,25 @@ <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> </after> - <!--Create order via Admin--> + + <!--login to Admin--> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <comment userInput="Admin creates order" stepKey="adminCreateOrderComment"/> - <!--<actionGroup ref="navigateToNewOrderPageNewCustomer" stepKey="navigateToNewOrderPage"/>--> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderIndexPage"/> <waitForPageLoad stepKey="waitForIndexPageLoad"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Orders" stepKey="seeIndexPageTitle"/> + + <!--Create new order--> <click selector="{{AdminOrdersGridSection.createNewOrder}}" stepKey="clickCreateNewOrder"/> <click selector="{{AdminOrderFormActionSection.CreateNewCustomer}}" stepKey="clickCreateCustomer"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Create New Order" stepKey="seeNewOrderPageTitle"/> - <!--<actionGroup ref="checkRequiredFieldsNewOrderForm" stepKey="checkRequiredFieldsNewOrder" after="seeNewOrderPageTitle"/>--> - <!--<scrollToTopOfPage stepKey="scrollToTopOfOrderFormPage" after="checkRequiredFieldsNewOrder"/>--> <actionGroup ref="addSimpleProductToOrderWithCustomQuantity" stepKey="addSimpleProductToOrderWithUserDefinedQty"> <argument name="product" value="_defaultProduct"/> <argument name="quantity" value="10"/> </actionGroup> <!--Fill customer group and customer email which both are now required fields--> - <selectOption selector="{{AdminOrderFormAccountSection.group}}" userInput="{{GeneralCustomerGroup.code}}" stepKey="selectCustomerGroup" after="addSimpleProductToOrder"/> + <selectOption selector="{{AdminOrderFormAccountSection.group}}" userInput="{{GeneralCustomerGroup.code}}" stepKey="selectCustomerGroup" after="addSimpleProductToOrderWithUserDefinedQty"/> <fillField selector="{{AdminOrderFormAccountSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail" after="selectCustomerGroup"/> <!--Fill customer address information--> @@ -57,20 +57,113 @@ <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping" after="fillCustomerAddress"/> <!--Verify totals on Order page--> - <see selector="{{AdminOrderFormTotalSection.total('Subtotal')}}" userInput="$1230.00" stepKey="seeOrderSubTotal" after="selectFlatRateShipping"/> + <see selector="{{AdminOrderFormTotalSection.total('Subtotal')}}" userInput="$1,230.00" stepKey="seeOrderSubTotal" after="selectFlatRateShipping"/> <see selector="{{AdminOrderFormTotalSection.total('Shipping')}}" userInput="$50.00" stepKey="seeOrderShipping" after="seeOrderSubTotal"/> <scrollTo selector="{{AdminOrderFormTotalSection.grandTotal}}" stepKey="scrollToOrderGrandTotal"/> - <see selector="{{AdminOrderFormTotalSection.grandTotal}}" userInput="$1280.00" stepKey="seeCorrectGrandTotal" after="scrollToOrderGrandTotal"/> + <see selector="{{AdminOrderFormTotalSection.grandTotal}}" userInput="$1,280.00" stepKey="seeCorrectGrandTotal" after="scrollToOrderGrandTotal"/> <!--Submit Order and verify information--> <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="seeCorrectGrandTotal"/> <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPage" after="clickSubmitOrder"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeSuccessMessage" after="seeViewOrderPage"/> - <scrollTo selector="{{AdminOrderItemsOrderedSection.qtyColumn}}" stepKey="scrollToItemsOrdered" after="seeSuccessMessage"/> + <grabTextFrom selector="|Order # (\d+)|" stepKey="getOrderId" after="seeSuccessMessage"/> + <scrollTo selector="{{AdminOrderItemsOrderedSection.qtyColumn}}" stepKey="scrollToItemsOrdered" after="getOrderId"/> <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Ordered 10" stepKey="seeQtyOfItemsOrdered" after="scrollToItemsOrdered"/> + <!--Create order invoice for first half of ordered items--> + <comment userInput="Admin creates invoice for order" stepKey="adminCreateInvoiceComment" /> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceActionButton"/> + <!--<seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl" after="clickInvoiceAction"/>--> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage" after="clickInvoiceActionButton"/> + <scrollTo selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced"/> + + <!--Verify items invoiced information--> + + <!--<see selector="{{AdminInvoiceItemsSection.itemQty('1')}}" userInput="Invoiced Partial" stepKey="seeQtyOfItemsInvoiced"/>--> + <fillField selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" userInput="5" stepKey="invoiceHalfTheItems"/> + + <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQtyToBeInvoiced"/> + <waitForLoadingMaskToDisappear stepKey="WaitForQtyToUpdate"/> + <waitForElementVisible selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="waitforSubmitInvoiceBtn"/> + + <!--Submit Invoice--> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="submitInvoice"/> + <waitForLoadingMaskToDisappear stepKey="WaitForInvoiceToSubmit"/> + <!--<waitForElementVisible selector="{{AdminOrderDetailsMessagesSection.successMessage}}" stepKey="waitUntilInvoiceSucesssMsg"/>--> + + <!--Invoice created successfully--> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceSuccessMessage"/> + <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoicesTab"/> + <waitForLoadingMaskToDisappear stepKey="waitForInvoiceGridToLoad" after="clickInvoicesTab"/> + <see selector="{{AdminOrderInvoicesTabSection.gridRow('1')}}" userInput="$665.00" stepKey="seeOrderInvoiceTabInGrid" after="waitForInvoiceGridToLoad"/> + <click selector="{{AdminOrderInvoicesTabSection.viewGridRow('1')}}" stepKey="clickToViewInvoice" after="seeOrderInvoiceTabInGrid"/> + <click selector="{{AdminInvoiceOrderInformationSection.orderId}}" stepKey="clickOrderIdLinkOnInvoice"/> + + <!--Ship Order--> + <comment userInput="Admin creates shipment" stepKey="adminCreatesShipmentComment" before="clickShip"/> + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip" after="clickOrderIdLinkOnInvoice"/> + <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="OrderShipmentUrl" after="clickShip"/> + <scrollTo selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" stepKey="scrollToItemsToShip"/> + <see selector="{{AdminShipmentItemsSection.itemQty('1')}}" userInput="Invoiced 5" stepKey="see5itemsInvoiced"/> + <fillField selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" userInput="5" stepKey="fillQtyOfItemsToShip"/> + + <!--Submit Shipment--> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="submitShipment" after="fillQtyOfItemsToShip"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="successfullShipmentCreation" after="submitShipment"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="$getOrderId" stepKey="seeOrderIdInPageTitleAfterShip"/> + + <!--Verify Items Status and Shipped Qty in the Items Ordered section--> + <scrollTo selector="{{AdminOrderItemsOrderedSection.itemStatus('1')}}" stepKey="scrollToItemsShipped"/> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Shipped 5" stepKey="see5itemsShipped"/> + + <!--Create Credit Memo--> + <comment userInput="Admin creates credit memo" stepKey="createCreditMemoComment"/> + <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreateCreditMemo" after="createCreditMemoComment"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewMemoInPageTitle"/> + + <!--Update Qty of items to be refunded and submit refund--> + <scrollTo selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" stepKey="scrollToItemsToRefund"/> + <fillField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" stepKey="fillQtyOfItemsToRefund" after="scrollToItemsToRefund"/> + <click selector="{{AdminCreditMemoItemsSection.updateQty}}" stepKey="updateRefundQty"/> + <waitForLoadingMaskToDisappear stepKey="waitForRefundQtyToUpdate"/> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="seeSubmitRefundBtn"/> + <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="submitRefundOffline"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoSuccessMsg" after="submitRefundOffline"/> + + <!--Create invoice for rest of the ordered items--> + <comment userInput="Admin creates invoice for rest of the items" stepKey="adminCreateInvoiceComment2" /> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceActionForRestOfItems"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage2" after="clickInvoiceActionForRestOfItems"/> + + <comment userInput="Qty To Invoice is 5" stepKey="seeRemainderInQtyToInvoice"/> + <scrollTo selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced2"/> + <!--<see selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced2"/>--> + <seeInField userInput="5" selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="see5InTheQtyToInvoice"/> + + <!--Verify items invoiced information--> + <see selector="{{AdminInvoiceItemsSection.itemQty('1')}}" userInput="Refunded 5" stepKey="seeQtyOfItemsRefunded"/> + + <!--Submit Invoice--> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="submitInvoice2" /> + + <!--Invoice created successfully for the rest of the ordered items--> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceSuccessMessage2" after="submitInvoice2"/> + + <!--Verify Ship Action can be done for the rest of the invoiced items --> + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipActionForRestOfItems" after="seeInvoiceSuccessMessage2"/> + + <!--Verify Items To Ship section --> + <scrollTo selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" stepKey="scrollToItemsToShip2"/> + <see selector="{{AdminShipmentItemsSection.itemQty('1')}}" userInput="Invoiced 10" stepKey="SeeAll10ItemsInvoiced"/> + <fillField selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" userInput="5" stepKey="fillRestOfItemsToShip"/> + <!--Submit Shipment--> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="submitShipment2" after="fillRestOfItemsToShip"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="successfullyCreatedShipment" after="submitShipment2"/> + <!--Verify Items Status and Shipped Qty in the Items Ordered section--> + <scrollTo selector="{{AdminOrderItemsOrderedSection.itemStatus('1')}}" stepKey="scrollToItemsOrdered2"/> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Shipped 10" stepKey="seeAllItemsShipped"/> </test> </tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/Section/AdminShipmentItemsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/Section/AdminShipmentItemsSection.xml index 562ad729fe7f3..e2191342056ca 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/Section/AdminShipmentItemsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Shipping/Section/AdminShipmentItemsSection.xml @@ -12,7 +12,7 @@ <element name="itemName" type="text" selector=".order-shipment-table tbody:nth-of-type({{row}}) .col-product .product-title" parameterized="true"/> <element name="itemSku" type="text" selector=".order-shipment-table tbody:nth-of-type({{row}}) .col-product .product-sku-block" parameterized="true"/> <element name="itemQty" type="text" selector=".order-shipment-table tbody:nth-of-type({{row}}) .col-ordered-qty .qty-table" parameterized="true"/> - <element name="itemQtyToShip" type="input" selector=".order-shipment-table tbody:nth-of-type({{row}}) .col-qty input.qty-item"/> + <element name="itemQtyToShip" type="input" selector=".order-shipment-table tbody:nth-of-type({{row}}) .col-qty input.qty-item" parameterized="true"/> <element name="nameColumn" type="text" selector=".order-shipment-table .col-product .product-title"/> <element name="skuColumn" type="text" selector=".order-shipment-table .col-product .product-sku-block"/> </section> From 34f2b469363c9ec1019e1e895f6b49b5b5491586 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Thu, 28 Jun 2018 15:31:46 -0500 Subject: [PATCH 0009/1415] MAGETWO-60034: Cannot ship remaining items nan order for several of one product if credit memo is made for some - updated testCaseId --- .../Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index c477fabe04828..2d7fe4d165a59 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -12,7 +12,7 @@ <title value="Email is required to create an order from Admin Panel"/> <description value="Admin should not be able to submit orders without an email address"/> <severity value="MAJOR"/> - <testCaseId value="MAGETWO-60034"/> + <testCaseId value="MAGETWO-93030"/> <group value="sales"/> </annotations> From e52a3265ac0d003ae15f028d14970a5c85528762 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@magento.com> Date: Thu, 28 Jun 2018 15:49:52 -0500 Subject: [PATCH 0010/1415] MAGETWO-60034: Cannot ship remaining items nan order for several of one product if credit memo is made for some - updated description title and severity --- .../Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index 2d7fe4d165a59..9b629f410f4e4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -9,9 +9,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAbleToShipPartiallyInvoicedItemsTest"> <annotations> - <title value="Email is required to create an order from Admin Panel"/> - <description value="Admin should not be able to submit orders without an email address"/> - <severity value="MAJOR"/> + <title value="Ship Action is available for remaining of the partially invoiced items "/> + <description value="Admin should be able to ship remaining ordered items if some of them are already refunded"/> + <severity value="CRITICAL"/> <testCaseId value="MAGETWO-93030"/> <group value="sales"/> @@ -78,10 +78,7 @@ <scrollTo selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced"/> <!--Verify items invoiced information--> - - <!--<see selector="{{AdminInvoiceItemsSection.itemQty('1')}}" userInput="Invoiced Partial" stepKey="seeQtyOfItemsInvoiced"/>--> <fillField selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" userInput="5" stepKey="invoiceHalfTheItems"/> - <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQtyToBeInvoiced"/> <waitForLoadingMaskToDisappear stepKey="WaitForQtyToUpdate"/> <waitForElementVisible selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="waitforSubmitInvoiceBtn"/> From fa2c3b5f5cb37f04c12e12b8bf1673ac0c13a5bb Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Sat, 30 Jun 2018 15:14:03 +0300 Subject: [PATCH 0011/1415] Alphabetize Schema Fields#11 --- lib/internal/Magento/Framework/GraphQl/Config.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 8d40d7fa6bb49..e6dc128e4dd43 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -53,6 +53,11 @@ public function getConfigElement(string $configElementName) : ConfigElementInter sprintf('Config element "%s" is not declared in GraphQL schema', $configElementName) ); } + + if (!empty($data['fields']) && is_array($data['fields'])) { + ksort($data['fields']); + } + return $this->configElementFactory->createFromConfigData($data); } From 6421d302bbb8960cc229c3cdbde6b822c8a09538 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Tue, 3 Jul 2018 14:01:28 -0500 Subject: [PATCH 0012/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fixing tests for new logic --- .../Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php | 3 ++- .../testsuite/Magento/Sales/Service/V1/RefundOrderTest.php | 5 +++-- .../integration/testsuite/Magento/Paypal/Model/IpnTest.php | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php index 8262a7e41543e..eae0e600434a6 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php @@ -115,7 +115,8 @@ public function testInvoke() ); $this->assertNotEmpty($result); $order = $this->objectManager->get(OrderRepositoryInterface::class)->get($order->getId()); - $this->assertEquals(Order::STATE_CLOSED, $order->getState()); + //Totally refunded orders still can be processed and shipped. + $this->assertEquals(Order::STATE_PROCESSING, $order->getState()); } private function getItemsForRest($order) diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php index 12cbe1ca0e5e2..aacda763ca2aa 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php @@ -86,10 +86,11 @@ public function testShortRequest() 'Failed asserting that proper shipping amount of the Order was refunded' ); - $this->assertNotEquals( + //Totally refunded orders can be processed. + $this->assertEquals( $existingOrder->getStatus(), $updatedOrder->getStatus(), - 'Failed asserting that order status was changed' + 'Failed asserting that order status has not changed' ); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $this->fail('Failed asserting that Creditmemo was created'); diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php index 1a22ea947f85a..f2cd745e96d83 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php @@ -64,7 +64,8 @@ public function testProcessIpnRequestFullRefund() $creditmemoItems = $order->getCreditmemosCollection()->getItems(); $creditmemo = current($creditmemoItems); - $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ; + //Totally refunded orders still can be shipped + $this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ; $this->assertEquals(1, count($creditmemoItems)); $this->assertEquals(Creditmemo::STATE_REFUNDED, $creditmemo->getState()); $this->assertEquals(10, $order->getSubtotalRefunded()); @@ -146,7 +147,8 @@ public function testProcessIpnRequestRestRefund() $creditmemoItems = $order->getCreditmemosCollection()->getItems(); - $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ; + //Totally refunded orders still can be shipped + $this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ; $this->assertEquals(1, count($creditmemoItems)); $this->assertEquals(10, $order->getSubtotalRefunded()); $this->assertEquals(10, $order->getBaseSubtotalRefunded()); From 9864ab822f453e0a4fe0e20bda28d5cfe26cbc36 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Tue, 3 Jul 2018 14:33:08 -0500 Subject: [PATCH 0013/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fixed test --- .../app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml index d4b9856c5e319..e6ab0ff5026b6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml @@ -22,7 +22,7 @@ <data name="steps" xsi:type="string">invoice, shipment|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> - <data name="resultStatuses" xsi:type="string">Complete,Closed</data> + <data name="resultStatuses" xsi:type="string">Complete,Processing</data> <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionFailMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> From bd8a83b8308963fb19e9938f09f2b4962982c80f Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Thu, 12 Jul 2018 14:50:12 -0500 Subject: [PATCH 0014/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some --- app/code/Magento/Sales/Model/Order.php | 8 +- .../Sales/Test/Unit/Model/OrderTest.php | 161 +++++++++++++++++- 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index d3b8edbed2eea..7f44e286fb8ce 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -546,7 +546,13 @@ public function canCancel() break; } } - if ($allInvoiced) { + + $allRefunded = true; + foreach ($this->getAllItems() as $orderItem) { + $allRefunded = $allRefunded && ((float)$orderItem->getQtyRefunded() == (float)$orderItem->getQtyInvoiced()); + } + + if ($allInvoiced && !$allRefunded) { return false; } diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php index 7f6363346872c..b4b42d0da2d69 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php @@ -114,7 +114,9 @@ protected function setUp() 'getParentItemId', 'getQuoteItemId', 'getLockedDoInvoice', - 'getProductId' + 'getProductId', + 'getQtyRefunded', + 'getQtyInvoiced', ]); $this->salesOrderCollectionMock = $this->getMockBuilder( \Magento\Sales\Model\ResourceModel\Order\Collection::class @@ -619,6 +621,163 @@ public function testCanCancelAllInvoiced() $this->item->expects($this->any()) ->method('getQtyToInvoice') ->willReturn(0); + $this->item->expects($this->any()) + ->method('getQtyRefunded') + ->willReturn(0); + $this->item->expects($this->any()) + ->method('getQtyInvoiced') + ->willReturn(1); + + $this->assertFalse($this->order->canCancel()); + } + + public function testCanCancelAllRefunded() + { + $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) + ->disableOriginalConstructor() + ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) + ->getMock(); + $paymentMock->expects($this->any()) + ->method('canReviewPayment') + ->will($this->returnValue(false)); + $paymentMock->expects($this->any()) + ->method('canFetchTransactionInfo') + ->will($this->returnValue(false)); + $collectionMock = $this->createPartialMock( + \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, + ['getItems', 'setOrderFilter'] + ); + $this->orderItemCollectionFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($collectionMock)); + $collectionMock->expects($this->any()) + ->method('setOrderFilter') + ->willReturnSelf(); + $this->preparePaymentMock($paymentMock); + + $this->prepareItemMock(0); + + $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); + $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); + + $this->item->expects($this->any()) + ->method('isDeleted') + ->willReturn(false); + $this->item->expects($this->any()) + ->method('getQtyToInvoice') + ->willReturn(0); + $this->item->expects($this->any()) + ->method('getQtyRefunded') + ->willReturn(10); + $this->item->expects($this->any()) + ->method('getQtyInvoiced') + ->willReturn(10); + + $this->assertTrue($this->order->canCancel()); + } + + /** + * Test that order can be canceled if some items were partially invoiced with certain qty + * and then refunded for this qty. + * Sample: + * - ordered qty = 20 + * - invoiced = 10 + * - refunded = 10 + */ + public function testCanCancelPartiallyInvoicedAndRefunded() + { + $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) + ->disableOriginalConstructor() + ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) + ->getMock(); + $paymentMock->expects($this->any()) + ->method('canReviewPayment') + ->will($this->returnValue(false)); + $paymentMock->expects($this->any()) + ->method('canFetchTransactionInfo') + ->will($this->returnValue(false)); + $collectionMock = $this->createPartialMock( + \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, + ['getItems', 'setOrderFilter'] + ); + $this->orderItemCollectionFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($collectionMock)); + $collectionMock->expects($this->any()) + ->method('setOrderFilter') + ->willReturnSelf(); + $this->preparePaymentMock($paymentMock); + + $this->prepareItemMock(0); + + $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); + $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); + + $this->item->expects($this->any()) + ->method('isDeleted') + ->willReturn(false); + $this->item->expects($this->any()) + ->method('getQtyToInvoice') + ->willReturn(10); + $this->item->expects($this->any()) + ->method('getQtyRefunded') + ->willReturn(10); + $this->item->expects($this->any()) + ->method('getQtyInvoiced') + ->willReturn(10); + + $this->assertTrue($this->order->canCancel()); + } + + /** + * Test that order CAN NOT be canceled if some items were partially invoiced with certain qty + * and then refunded for less than that qty. + * Sample: + * - ordered qty = 10 + * - invoiced = 10 + * - refunded = 5 + */ + public function testCanCancelPartiallyInvoicedAndNotFullyRefunded() + { + $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) + ->disableOriginalConstructor() + ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) + ->getMock(); + $paymentMock->expects($this->any()) + ->method('canReviewPayment') + ->will($this->returnValue(false)); + $paymentMock->expects($this->any()) + ->method('canFetchTransactionInfo') + ->will($this->returnValue(false)); + $collectionMock = $this->createPartialMock( + \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, + ['getItems', 'setOrderFilter'] + ); + $this->orderItemCollectionFactoryMock->expects($this->any()) + ->method('create') + ->will($this->returnValue($collectionMock)); + $collectionMock->expects($this->any()) + ->method('setOrderFilter') + ->willReturnSelf(); + $this->preparePaymentMock($paymentMock); + + $this->prepareItemMock(0); + + $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); + $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); + + $this->item->expects($this->any()) + ->method('isDeleted') + ->willReturn(false); + $this->item->expects($this->any()) + ->method('getQtyToInvoice') + ->willReturn(0); + $this->item->expects($this->any()) + ->method('getQtyRefunded') + ->willReturn(5); + $this->item->expects($this->any()) + ->method('getQtyInvoiced') + ->willReturn(10); $this->assertFalse($this->order->canCancel()); } From 0a46c8aeeb0b69615f44bb543e6731d264523104 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@magento.com> Date: Thu, 12 Jul 2018 17:04:29 -0500 Subject: [PATCH 0015/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some --- app/code/Magento/Sales/Test/Unit/Model/OrderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php index b4b42d0da2d69..b75e3adb7402b 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php @@ -17,6 +17,7 @@ * Test class for \Magento\Sales\Model\Order * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyPublicMethods) */ class OrderTest extends \PHPUnit\Framework\TestCase { From 6a68bd880131a22bacdbf18b25f274c5c8cc236b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 25 Jul 2018 13:08:12 +0200 Subject: [PATCH 0016/1415] Query complexity limiter introduced --- app/code/Magento/GraphQl/etc/di.xml | 6 +++ .../GraphQl/Query/QueryComplexityLimiter.php | 53 +++++++++++++++++++ .../GraphQl/Query/QueryProcessor.php | 23 ++++---- 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 105fa8bf166b2..4aed25ac7bf4a 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -97,4 +97,10 @@ </argument> </arguments> </type> + <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> + <arguments> + <argument name="queryDepth" xsi:type="number">50</argument> + <argument name="queryComplexity" xsi:type="number">150</argument> + </arguments> + </type> </config> diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php new file mode 100644 index 0000000000000..be768d9f8defd --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\GraphQl\Query; + +use GraphQL\Validator\DocumentValidator; +use GraphQL\Validator\Rules\DisableIntrospection; +use GraphQL\Validator\Rules\QueryDepth; +use GraphQL\Validator\Rules\QueryComplexity; + +/** + * Sets limits for query complexity. A single GraphQL query can potentially + * generate thousands of database operations so, the very complex queries + * should be filtered and rejected. + */ +class QueryComplexityLimiter +{ + /** + * @var int + */ + private $queryDepth; + + /** + * @var int + */ + private $queryComplexity; + + /** + * @param int $queryDepth + * @param int $queryComplexity + */ + public function __construct( + int $queryDepth = 50, + int $queryComplexity = 150 + ) { + $this->queryDepth = $queryDepth; + $this->queryComplexity = $queryComplexity; + } + + public function execute(bool $disableIntrospection = false): void + { + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); + DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); + + if ($disableIntrospection) { + DocumentValidator::addRule(new DisableIntrospection()); + } + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 94a0e5a1c1a6e..0a23e4d00e8c7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -7,9 +7,6 @@ namespace Magento\Framework\GraphQl\Query; -use GraphQL\Validator\DocumentValidator; -use GraphQL\Validator\Rules\DisableIntrospection; -use GraphQL\Validator\Rules\QueryDepth; use Magento\Framework\GraphQl\Exception\ExceptionFormatter; use Magento\Framework\GraphQl\Schema; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; @@ -24,12 +21,21 @@ class QueryProcessor */ private $exceptionFormatter; + /** + * @var QueryComplexityLimiter + */ + protected $queryComplexityLimiter; + /** * @param ExceptionFormatter $exceptionFormatter + * @param QueryComplexityLimiter $queryComplexityChecker */ - public function __construct(ExceptionFormatter $exceptionFormatter) - { + public function __construct( + ExceptionFormatter $exceptionFormatter, + QueryComplexityLimiter $queryComplexityChecker + ) { $this->exceptionFormatter = $exceptionFormatter; + $this->queryComplexityLimiter = $queryComplexityChecker; } /** @@ -49,10 +55,9 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - if (!$this->exceptionFormatter->shouldShowDetail()) { - DocumentValidator::addRule(new QueryDepth(10)); - DocumentValidator::addRule(new DisableIntrospection()); - } + $disableIntrospection = $this->exceptionFormatter->shouldShowDetail(); + $this->queryComplexityLimiter->execute($disableIntrospection); + $rootValue = null; return \GraphQL\GraphQL::executeQuery( $schema, From 660e393a1087060a838dc299ea80606ddb08df50 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 26 Jul 2018 11:11:01 +0200 Subject: [PATCH 0017/1415] Added some missing PHPDoc --- .../Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index be768d9f8defd..993390f5cfd22 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -41,6 +41,9 @@ public function __construct( $this->queryComplexity = $queryComplexity; } + /** + * @param bool $disableIntrospection + */ public function execute(bool $disableIntrospection = false): void { DocumentValidator::addRule(new QueryDepth($this->queryDepth)); From 351ae3784d0a148c40c89e581f9b6f0f61675a9a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 26 Jul 2018 12:04:33 +0200 Subject: [PATCH 0018/1415] Added API-functional test for query limiter --- .../Framework/QueryComplexityLimiterTest.php | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php new file mode 100644 index 0000000000000..fe278eaef1914 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -0,0 +1,332 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Framework; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class QueryComplexityLimiterTest extends GraphQlAbstract +{ + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testQueryComplexityIsLimited() + { + $query + = <<<QUERY +{ +category(id: 2) { + products { + items { + name + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + media_gallery_entries { + file + } + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + thumbnail + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + thumbnail + new_from_date + tier_price + manufacturer + sku + image + canonical_url + updated_at + created_at + media_gallery_entries { + position + id + types + } + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + thumbnail + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + thumbnail + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + default_sort_by + breadcrumbs { + category_id + category_name + category_url_key + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} +QUERY; + + self::expectExceptionMessageRegExp('/Max query complexity should be 150 but got 151/'); + $this->graphQlQuery($query); + } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testQueryDepthIsLimited() + { + $query + = <<<QUERY +{ + category(id: 2) { + products { + items { + name + categories { + products { + items { + media_gallery_entries { + file + } + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + name, + categories { + products { + items { + categories { + products { + items { + categories{ + products { + items { + categories { + products { + items { + categories { + products { + items { + categories { + products { + items { + name, + categories { + products { + items { + categories { + name + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} +QUERY; + self::expectExceptionMessageRegExp('/Max query depth should be 50 but got 51/'); + $this->graphQlQuery($query); + } +} From 9aedd10c130d3455c352d3a3bddad856a75dd82d Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 26 Jul 2018 12:06:12 +0200 Subject: [PATCH 0019/1415] Constructor argument renamed --- .../Magento/Framework/GraphQl/Query/QueryProcessor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 0a23e4d00e8c7..e1c9c6d6dbdfe 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -28,14 +28,14 @@ class QueryProcessor /** * @param ExceptionFormatter $exceptionFormatter - * @param QueryComplexityLimiter $queryComplexityChecker + * @param QueryComplexityLimiter $queryComplexityLimiter */ public function __construct( ExceptionFormatter $exceptionFormatter, - QueryComplexityLimiter $queryComplexityChecker + QueryComplexityLimiter $queryComplexityLimiter ) { $this->exceptionFormatter = $exceptionFormatter; - $this->queryComplexityLimiter = $queryComplexityChecker; + $this->queryComplexityLimiter = $queryComplexityLimiter; } /** From 88fb39883b20bad5500e8a7e1fd492ed33bfecf9 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 30 Jul 2018 14:34:55 +0200 Subject: [PATCH 0020/1415] Fixed introspection disabling expression --- lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index e1c9c6d6dbdfe..e3a2ea3fa753e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,7 +55,7 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $disableIntrospection = $this->exceptionFormatter->shouldShowDetail(); + $disableIntrospection = !$this->exceptionFormatter->shouldShowDetail(); $this->queryComplexityLimiter->execute($disableIntrospection); $rootValue = null; From 99b1d1d5397cc3fb97551699647a33717a6ed3f6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 30 Jul 2018 14:53:14 +0200 Subject: [PATCH 0021/1415] Reduced limiting values --- app/code/Magento/GraphQl/etc/di.xml | 4 +- .../Framework/QueryComplexityLimiterTest.php | 173 +----------------- .../GraphQl/Query/QueryComplexityLimiter.php | 4 +- 3 files changed, 7 insertions(+), 174 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 4aed25ac7bf4a..529280b7cbb6e 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,8 +99,8 @@ </type> <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> - <argument name="queryDepth" xsi:type="number">50</argument> - <argument name="queryComplexity" xsi:type="number">150</argument> + <argument name="queryDepth" xsi:type="number">10</argument> + <argument name="queryComplexity" xsi:type="number">50</argument> </arguments> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index fe278eaef1914..c5f645a94472a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -86,109 +86,6 @@ public function testQueryComplexityIsLimited() id types } - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - thumbnail - sku - image - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - sku - image - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - sku - image - thumbnail - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - default_sort_by - breadcrumbs { - category_id - category_name - category_url_key - } - } - } - } - } - } - } - } - } - } - } } } } @@ -201,7 +98,7 @@ public function testQueryComplexityIsLimited() } QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 150 but got 151/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 50 but got 62/'); $this->graphQlQuery($query); } @@ -238,71 +135,7 @@ public function testQueryDepthIsLimited() categories { products { items { - categories { - products { - items { - categories { - products { - items { - categories { - products { - items { - name, - categories { - products { - items { - categories { - products { - items { - categories{ - products { - items { - categories { - products { - items { - categories { - products { - items { - categories { - products { - items { - name, - categories { - products { - items { - categories { - name - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } + name } } } @@ -326,7 +159,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 50 but got 51/'); + self::expectExceptionMessageRegExp('/Max query depth should be 10 but got 20/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 993390f5cfd22..d2d9477e67b1e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -34,8 +34,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 50, - int $queryComplexity = 150 + int $queryDepth = 10, + int $queryComplexity = 50 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From 9f47f05a36333e749e150c1bfc6c42cc4acbf5eb Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 13:43:37 -0400 Subject: [PATCH 0022/1415] Add Value and ValueInterface to Magento Framework's public API These classes are necessary/useful for creating a backend source for a Magento Configuration field. As such they should be reliable and part of the public API. --- lib/internal/Magento/Framework/App/Config/Value.php | 2 ++ lib/internal/Magento/Framework/App/Config/ValueInterface.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index c85b484d51ce2..e6923caa3d28c 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -17,6 +17,8 @@ * @method string getValue() * @method \Magento\Framework\App\Config\ValueInterface setValue(string $value) * + * @api + * * @SuppressWarnings(PHPMD.NumberOfChildren) */ class Value extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\App\Config\ValueInterface diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 1e0747acc36f2..ab6a34c4274bd 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,7 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * + * @api */ interface ValueInterface { From a541c33264b1dca39f0fe62cc513cef7b160cf90 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 16:23:40 -0400 Subject: [PATCH 0023/1415] Add ReadFactory and WriteFactory to Magento's public API These classes are necessary/useful for creating instances of ReadInterface and WriteInterface using the public API. --- .../Magento/Framework/Filesystem/File/ReadFactory.php | 6 +++++- .../Magento/Framework/Filesystem/File/WriteFactory.php | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php index 38b581da752b7..5d9badf42073f 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading + * @api + */ class ReadFactory { /** @@ -28,7 +32,7 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file + * Create a {@see ReaderInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code diff --git a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php index a45d6a62488f6..af2a43ceaedc3 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading and/or writing + * @api + */ class WriteFactory extends ReadFactory { /** @@ -29,12 +33,12 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file. + * Create a {@see WriterInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code * @param string $mode [optional] - * @return Write + * @return WriteInterface */ public function create($path, $driver, $mode = 'r') { From 2a3562f77e816688c1e25c9ea342dc82456ecf42 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 16:30:23 -0400 Subject: [PATCH 0024/1415] Add directory WriteInterface and ReadInterface --- .../Magento/Framework/Filesystem/Directory/ReadInterface.php | 2 +- .../Magento/Framework/Filesystem/Directory/WriteInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php index 5519245ec24b4..61108c64dda44 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\ReadInterface - * + * @api */ interface ReadInterface { diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php index c72651a78dad3..186cbcb81bff2 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\WriteInterface - * + * @api */ interface WriteInterface extends ReadInterface { From e671008cb2a261842823d64dd4ea20040fafcc5f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 14 Aug 2018 15:26:27 +0300 Subject: [PATCH 0025/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Template fixed: added checking of all gift options. Also added possibility to change order level options visibility from other modules. --- .../GiftMessage/Block/Message/Inline.php | 21 +++++++++++++++++-- .../view/frontend/templates/inline.phtml | 9 +++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index e5b80848661fd..1a874cb5ea4ae 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -238,7 +238,7 @@ public function getMessage($entity = null) */ public function getItems() { - if (!$this->getData('items')) { + if (!$this->hasData('items')) { $items = []; $entityItems = $this->getEntity()->getAllItems(); @@ -325,6 +325,23 @@ public function getEscaped($value, $defaultValue = '') return $this->escapeHtml(trim($value) != '' ? $value : $defaultValue); } + /** + * Check availability of order level functionality + * + * @return bool + */ + public function isOrderLevelAvailable() + { + $entity = $this->getEntity(); + if (!$entity->hasIsGiftOptionsAvailable()) { + $this->_eventManager->dispatch('gift_options_prepare', ['entity' => $entity]); + if (!$entity->getIsGiftOptionsAvailable()) { + $entity->setIsGiftOptionsAvailable($this->isMessagesAvailable()); + } + } + return $entity->getIsGiftOptionsAvailable(); + } + /** * Check availability of giftmessages on order level * @@ -355,7 +372,7 @@ public function isItemMessagesAvailable($item) protected function _toHtml() { // render HTML when messages are allowed for order or for items only - if ($this->isItemsAvailable() || $this->isMessagesAvailable()) { + if ($this->isItemsAvailable() || $this->isOrderLevelAvailable()) { return parent::_toHtml(); } return ''; diff --git a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml index dec54cfeb9df9..8c58959be15b7 100644 --- a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml +++ b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml @@ -18,7 +18,7 @@ </div> <dl class="options-items" id="allow-gift-options-container"> - <?php if ($block->isMessagesAvailable()): ?> + <?php if ($block->isOrderLevelAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_messages_for_order" id="allow_gift_options_for_order" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> @@ -28,6 +28,7 @@ <dd id="allow-gift-options-for-order-container" class="order-options"> <div class="options-order-container" id="options-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"></div> + <?php if ($block->isMessagesAvailable()): ?> <button class="action action-gift" data-mage-init='{"toggleAdvanced": {"selectorsToggleClass":"hidden", "toggleContainers":"#allow-gift-messages-for-order-container"}}'> <span><?= /* @escapeNotVerified */ __('Gift Message') ?></span> @@ -62,8 +63,9 @@ }); </script> </div> + <?php endif; ?> </dd> - <?php endif ?> + <?php endif; ?> <?php if ($block->isItemsAvailable()): ?> <dt id="add-gift-options-for-items-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title individual"> <div class="field choice"> @@ -152,6 +154,7 @@ </div> <dl class="options-items" id="allow-gift-options-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"> + <?php if ($block->isOrderLevelAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" id="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> @@ -192,7 +195,7 @@ </div> <?php endif; ?> </dd> - + <?php endif; ?> <?php if ($block->isItemsAvailable()): ?> <dt id="add-gift-options-for-items-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title individual"> <div class="field choice"> From d764998480c7853c13c88d26a4530083cbd8a0a8 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 16 Aug 2018 14:21:51 +0300 Subject: [PATCH 0026/1415] MAGETWO-92170: Redundant File Names for Quote Attachments --- lib/internal/Magento/Framework/File/Uploader.php | 10 ++++++---- nginx.conf.sample | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 33f458d2082e1..2b768fb2dbdce 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -204,20 +204,22 @@ public function save($destinationFolder, $newFileName = null) $this->_result = false; $destinationFile = $destinationFolder; $fileName = isset($newFileName) ? $newFileName : $this->_file['name']; - $fileName = self::getCorrectFileName($fileName); + $fileName = static::getCorrectFileName($fileName); if ($this->_enableFilesDispersion) { $fileName = $this->correctFileNameCase($fileName); $this->setAllowCreateFolders(true); - $this->_dispretionPath = self::getDispersionPath($fileName); + $this->_dispretionPath = static::getDispersionPath($fileName); $destinationFile .= $this->_dispretionPath; $this->_createDestinationFolder($destinationFile); } if ($this->_allowRenameFiles) { - $fileName = self::getNewFileName(self::_addDirSeparator($destinationFile) . $fileName); + $fileName = static::getNewFileName( + static::_addDirSeparator($destinationFile) . $fileName + ); } - $destinationFile = self::_addDirSeparator($destinationFile) . $fileName; + $destinationFile = static::_addDirSeparator($destinationFile) . $fileName; try { $this->_result = $this->_moveFile($this->_file['tmp_name'], $destinationFile); diff --git a/nginx.conf.sample b/nginx.conf.sample index 6f87a9a076666..90604808f6ec0 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -161,7 +161,7 @@ location /media/import/ { } # PHP entry point for main application -location ~ (index|get|static|report|404|503|health_check)\.php$ { +location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { try_files $uri =404; fastcgi_pass fastcgi_backend; fastcgi_buffers 1024 4k; From ddb642c10e70c1acab5683beaf8d7d5b4b5e8ffd Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Mon, 20 Aug 2018 11:05:50 +0300 Subject: [PATCH 0027/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Moved saving toolbar params to session from block to model. Save params before generating layout xml. --- .../Block/Product/ProductList/Toolbar.php | 43 ++++- .../Catalog/Controller/Category/View.php | 12 +- .../Product/ProductList/ToolbarMemorizer.php | 161 ++++++++++++++++++ 3 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 0b8d2d6c89e72..0e971dcb5b9f5 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -7,6 +7,7 @@ use Magento\Catalog\Helper\Product\ProductList; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; /** * Product list toolbar @@ -77,6 +78,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template /** * @var bool $_paramsMemorizeAllowed + * @deprecated */ protected $_paramsMemorizeAllowed = true; @@ -96,6 +98,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template * Catalog session * * @var \Magento\Catalog\Model\Session + * @deprecated */ protected $_catalogSession; @@ -104,6 +107,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ protected $_toolbarModel; + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + /** * @var ProductList */ @@ -119,6 +127,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ protected $_postDataHelper; + /** + * @var \Magento\Framework\App\Http\Context + */ + private $httpContext; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Catalog\Model\Session $catalogSession @@ -127,6 +140,8 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param ProductList $productListHelper * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper + * @param ToolbarMemorizer|null $toolbarMemorizer + * @param \Magento\Framework\App\Http\Context|null $httpContext * @param array $data */ public function __construct( @@ -137,6 +152,8 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, ProductList $productListHelper, \Magento\Framework\Data\Helper\PostHelper $postDataHelper, + ToolbarMemorizer $toolbarMemorizer = null, + \Magento\Framework\App\Http\Context $httpContext = null, array $data = [] ) { $this->_catalogSession = $catalogSession; @@ -145,6 +162,12 @@ public function __construct( $this->urlEncoder = $urlEncoder; $this->_productListHelper = $productListHelper; $this->_postDataHelper = $postDataHelper; + $this->toolbarMemorizer = $toolbarMemorizer ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + ToolbarMemorizer::class + ); + $this->httpContext = $httpContext ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\App\Http\Context::class + ); parent::__construct($context, $data); } @@ -152,6 +175,7 @@ public function __construct( * Disable list state params memorizing * * @return $this + * @deprecated */ public function disableParamsMemorizing() { @@ -165,6 +189,7 @@ public function disableParamsMemorizing() * @param string $param parameter name * @param mixed $value parameter value * @return $this + * @deprecated */ protected function _memorizeParam($param, $value) { @@ -244,13 +269,13 @@ public function getCurrentOrder() $defaultOrder = $keys[0]; } - $order = $this->_toolbarModel->getOrder(); + $order = $this->toolbarMemorizer->getOrder(); if (!$order || !isset($orders[$order])) { $order = $defaultOrder; } if ($order != $defaultOrder) { - $this->_memorizeParam('sort_order', $order); + $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } $this->setData('_current_grid_order', $order); @@ -270,13 +295,13 @@ public function getCurrentDirection() } $directions = ['asc', 'desc']; - $dir = strtolower($this->_toolbarModel->getDirection()); + $dir = strtolower($this->toolbarMemorizer->getDirection()); if (!$dir || !in_array($dir, $directions)) { $dir = $this->_direction; } if ($dir != $this->_direction) { - $this->_memorizeParam('sort_direction', $dir); + $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } $this->setData('_current_grid_direction', $dir); @@ -412,11 +437,15 @@ public function getCurrentMode() return $mode; } $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); - $mode = $this->_toolbarModel->getMode(); + $mode = $this->toolbarMemorizer->getMode(); if (!$mode || !isset($this->_availableMode[$mode])) { $mode = $defaultMode; } + if ($mode != $defaultMode) { + $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); + } + $this->setData('_current_grid_mode', $mode); return $mode; } @@ -568,13 +597,13 @@ public function getLimit() $defaultLimit = $keys[0]; } - $limit = $this->_toolbarModel->getLimit(); + $limit = $this->toolbarMemorizer->getLimit(); if (!$limit || !isset($limits[$limit])) { $limit = $defaultLimit; } if ($limit != $defaultLimit) { - $this->_memorizeParam('limit_page', $limit); + $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } $this->setData('_current_limit', $limit); diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php index 226e572505076..d451357a7c129 100644 --- a/app/code/Magento/Catalog/Controller/Category/View.php +++ b/app/code/Magento/Catalog/Controller/Category/View.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Model\Layer\Resolver; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Result\PageFactory; @@ -69,6 +70,11 @@ class View extends \Magento\Framework\App\Action\Action */ protected $categoryRepository; + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + /** * Constructor * @@ -82,6 +88,7 @@ class View extends \Magento\Framework\App\Action\Action * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory * @param Resolver $layerResolver * @param CategoryRepositoryInterface $categoryRepository + * @param ToolbarMemorizer|null $toolbarMemorizer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -94,7 +101,8 @@ public function __construct( PageFactory $resultPageFactory, \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory, Resolver $layerResolver, - CategoryRepositoryInterface $categoryRepository + CategoryRepositoryInterface $categoryRepository, + ToolbarMemorizer $toolbarMemorizer = null ) { parent::__construct($context); $this->_storeManager = $storeManager; @@ -106,6 +114,7 @@ public function __construct( $this->resultForwardFactory = $resultForwardFactory; $this->layerResolver = $layerResolver; $this->categoryRepository = $categoryRepository; + $this->toolbarMemorizer = $toolbarMemorizer ?: $context->getObjectManager()->get(ToolbarMemorizer::class); } /** @@ -130,6 +139,7 @@ protected function _initCategory() } $this->_catalogSession->setLastVisitedCategoryId($category->getId()); $this->_coreRegistry->register('current_category', $category); + $this->toolbarMemorizer->memorizeParams(); try { $this->_eventManager->dispatch( 'catalog_controller_category_init_after', diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php new file mode 100644 index 0000000000000..1ff63a0fa3448 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -0,0 +1,161 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Product\ProductList; + +use Magento\Catalog\Model\Session as CatalogSession; + +/** + * Class ToolbarMemorizer + * + * Responds for saving toolbar settings to catalog session + */ +class ToolbarMemorizer +{ + /** + * @var CatalogSession + */ + private $catalogSession; + + /** + * @var Toolbar + */ + private $toolbarModel; + + /** + * @var bool + */ + private $paramsMemorizeAllowed = true; + + /** + * @var string|bool + */ + private $order; + + /** + * @var string|bool + */ + private $direction; + + /** + * @var string|bool + */ + private $mode; + + /** + * @var string|bool + */ + private $limit; + + /** + * @param Toolbar $toolbarModel + * @param CatalogSession $catalogSession + */ + public function __construct( + Toolbar $toolbarModel, + CatalogSession $catalogSession + ) { + $this->toolbarModel = $toolbarModel; + $this->catalogSession = $catalogSession; + } + + /** + * Get sort order + * + * @return string|bool + */ + public function getOrder() + { + if ($this->order === null) { + $this->order = $this->toolbarModel->getOrder() ?? + $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME); + } + return $this->order; + } + + /** + * Get sort direction + * + * @return string|bool + */ + public function getDirection() + { + if ($this->direction === null) { + $this->direction = $this->toolbarModel->getDirection() ?? + $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME); + } + return $this->direction; + } + + /** + * Get sort mode + * + * @return string|bool + */ + public function getMode() + { + if ($this->mode === null) { + $this->mode = $this->toolbarModel->getMode() ?? + $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME); + } + return $this->mode; + } + + /** + * Get products per page limit + * + * @return string|bool + */ + public function getLimit() + { + if ($this->limit === null) { + $this->limit = $this->toolbarModel->getLimit() ?? + $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME); + } + return $this->limit; + } + + /** + * Disable list state params memorizing + * + * @return $this + */ + public function disableParamsMemorizing() + { + $this->paramsMemorizeAllowed = false; + return $this; + } + + /** + * Method to save all catalog parameters in catalog session + * + * @return void + */ + public function memorizeParams() + { + $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) + ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) + ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) + ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + } + + /** + * Memorize parameter value for session + * + * @param string $param parameter name + * @param mixed $value parameter value + * @return $this + */ + private function memorizeParam($param, $value) + { + if ($value && $this->paramsMemorizeAllowed && + !$this->catalogSession->getParamsMemorizeDisabled() && + $this->catalogSession->getData($param) != $value + ) { + $this->catalogSession->setData($param, $value); + } + return $this; + } +} From 12a856ab7def9eb398cd4fc998ded7daa5c9a18a Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 24 Aug 2018 15:36:38 +0300 Subject: [PATCH 0028/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned #8009 - Clear cache for parent product when simple product becomes out of stock. --- .../Model/Indexer/Stock/CacheCleaner.php | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php index a32faa4640a86..9712d129bcd65 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php @@ -10,8 +10,10 @@ use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\Framework\App\ResourceConnection; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Indexer\CacheContext; use Magento\CatalogInventory\Model\Stock; use Magento\Catalog\Model\Product; @@ -46,22 +48,30 @@ class CacheCleaner */ private $connection; + /** + * @var MetadataPool + */ + private $metadataPool; + /** * @param ResourceConnection $resource * @param StockConfigurationInterface $stockConfiguration * @param CacheContext $cacheContext * @param ManagerInterface $eventManager + * @param MetadataPool|null $metadataPool */ public function __construct( ResourceConnection $resource, StockConfigurationInterface $stockConfiguration, CacheContext $cacheContext, - ManagerInterface $eventManager + ManagerInterface $eventManager, + MetadataPool $metadataPool = null ) { $this->resource = $resource; $this->stockConfiguration = $stockConfiguration; $this->cacheContext = $cacheContext; $this->eventManager = $eventManager; + $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class); } /** @@ -76,7 +86,7 @@ public function clean(array $productIds, callable $reindex) $productStatusesAfter = $this->getProductStockStatuses($productIds); $productIds = $this->getProductIdsForCacheClean($productStatusesBefore, $productStatusesAfter); if ($productIds) { - $this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds); + $this->cacheContext->registerEntities(Product::CACHE_TAG, array_unique($productIds)); $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]); } } @@ -87,11 +97,24 @@ public function clean(array $productIds, callable $reindex) */ private function getProductStockStatuses(array $productIds) { + $linkField = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class) + ->getLinkField(); $select = $this->getConnection()->select() ->from( - $this->resource->getTableName('cataloginventory_stock_status'), + ['css' => $this->resource->getTableName('cataloginventory_stock_status')], ['product_id', 'stock_status', 'qty'] - )->where('product_id IN (?)', $productIds) + ) + ->joinLeft( + ['cpr' => $this->resource->getTableName('catalog_product_relation')], + 'css.product_id = cpr.child_id', + [] + ) + ->joinLeft( + ['cpe' => $this->resource->getTableName('catalog_product_entity')], + 'cpr.parent_id = cpe.' . $linkField, + ['parent_id' => 'cpe.entity_id'] + ) + ->where('product_id IN (?)', $productIds) ->where('stock_id = ?', Stock::DEFAULT_STOCK_ID) ->where('website_id = ?', $this->stockConfiguration->getDefaultScopeId()); @@ -125,6 +148,9 @@ private function getProductIdsForCacheClean(array $productStatusesBefore, array if ($statusBefore['stock_status'] !== $statusAfter['stock_status'] || ($stockThresholdQty && $statusAfter['qty'] <= $stockThresholdQty)) { $productIds[] = $productId; + if (isset($statusAfter['parent_id'])) { + $productIds[] = $statusAfter['parent_id']; + } } } From 9aa4cfa46f723e9d584d9bf014489f63af92d4dc Mon Sep 17 00:00:00 2001 From: ck-aagarwal <aman.agarwal@charleskeith.com> Date: Sun, 26 Aug 2018 14:58:00 +0800 Subject: [PATCH 0029/1415] updating code to handle misleading error in add product attribute screen by make error message more genric --- app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index e52791deaf2ad..519cf668e74fc 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -747,7 +747,7 @@ define([ function (value) { return utils.isEmptyNoTrim(value) || /^[a-z]+[a-z0-9_]+$/.test(value); }, - $.mage.__('Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len + $.mage.__('Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len ], 'validate-alphanum': [ function (value) { From 18e509c94f26406c3c73e1b16529d46de1ecbb78 Mon Sep 17 00:00:00 2001 From: ck-aagarwal <aman.agarwal@charleskeith.com> Date: Sun, 26 Aug 2018 15:33:36 +0800 Subject: [PATCH 0030/1415] updating code to handle misleading error in add product attribute screen by make error message more genric --- lib/web/legacy-build.min.js | 2 +- lib/web/mage/validation.js | 2 +- lib/web/prototype/validation.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/web/legacy-build.min.js b/lib/web/legacy-build.min.js index 52d132d634b0f..24e8c2429865f 100644 --- a/lib/web/legacy-build.min.js +++ b/lib/web/legacy-build.min.js @@ -5,4 +5,4 @@ var Prototype={Version:"1.7",Browser:(function(){var d=navigator.userAgent;var b * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ -(function(){var w=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,p=0,g=Object.prototype.toString,u=false,o=true;[0,0].sort(function(){o=false;return 0});var d=function(L,B,I,D){I=I||[];var e=B=B||document;if(B.nodeType!==1&&B.nodeType!==9){return[]}if(!L||typeof L!=="string"){return I}var J=[],K,G,P,O,H,A,z=true,E=v(B),N=L;while((w.exec(""),K=w.exec(N))!==null){N=K[3];J.push(K[1]);if(K[2]){A=K[3];break}}if(J.length>1&&q.exec(L)){if(J.length===2&&h.relative[J[0]]){G=l(J[0]+J[1],B)}else{G=h.relative[J[0]]?[B]:d(J.shift(),B);while(J.length){L=J.shift();if(h.relative[L]){L+=J.shift()}G=l(L,G)}}}else{if(!D&&J.length>1&&B.nodeType===9&&!E&&h.match.ID.test(J[0])&&!h.match.ID.test(J[J.length-1])){var Q=d.find(J.shift(),B,E);B=Q.expr?d.filter(Q.expr,Q.set)[0]:Q.set[0]}if(B){var Q=D?{expr:J.pop(),set:b(D)}:d.find(J.pop(),J.length===1&&(J[0]==="~"||J[0]==="+")&&B.parentNode?B.parentNode:B,E);G=Q.expr?d.filter(Q.expr,Q.set):Q.set;if(J.length>0){P=b(G)}else{z=false}while(J.length){var C=J.pop(),F=C;if(!h.relative[C]){C=""}else{F=J.pop()}if(F==null){F=B}h.relative[C](P,F,E)}}else{P=J=[]}}if(!P){P=G}if(!P){throw"Syntax error, unrecognized expression: "+(C||L)}if(g.call(P)==="[object Array]"){if(!z){I.push.apply(I,P)}else{if(B&&B.nodeType===1){for(var M=0;P[M]!=null;M++){if(P[M]&&(P[M]===true||P[M].nodeType===1&&n(B,P[M]))){I.push(G[M])}}}else{for(var M=0;P[M]!=null;M++){if(P[M]&&P[M].nodeType===1){I.push(G[M])}}}}}else{b(P,I)}if(A){d(A,e,I,D);d.uniqueSort(I)}return I};d.uniqueSort=function(z){if(f){u=o;z.sort(f);if(u){for(var e=1;e<z.length;e++){if(z[e]===z[e-1]){z.splice(e--,1)}}}}return z};d.matches=function(e,z){return d(e,null,null,z)};d.find=function(F,e,G){var E,C;if(!F){return[]}for(var B=0,A=h.order.length;B<A;B++){var D=h.order[B],C;if((C=h.leftMatch[D].exec(F))){var z=C[1];C.splice(1,1);if(z.substr(z.length-1)!=="\\"){C[1]=(C[1]||"").replace(/\\/g,"");E=h.find[D](C,e,G);if(E!=null){F=F.replace(h.match[D],"");break}}}}if(!E){E=e.getElementsByTagName("*")}return{set:E,expr:F}};d.filter=function(I,H,L,B){var A=I,N=[],F=H,D,e,E=H&&H[0]&&v(H[0]);while(I&&H.length){for(var G in h.filter){if((D=h.match[G].exec(I))!=null){var z=h.filter[G],M,K;e=false;if(F==N){N=[]}if(h.preFilter[G]){D=h.preFilter[G](D,F,L,N,B,E);if(!D){e=M=true}else{if(D===true){continue}}}if(D){for(var C=0;(K=F[C])!=null;C++){if(K){M=z(K,D,C,F);var J=B^!!M;if(L&&M!=null){if(J){e=true}else{F[C]=false}}else{if(J){N.push(K);e=true}}}}}if(M!==undefined){if(!L){F=N}I=I.replace(h.match[G],"");if(!e){return[]}break}}}if(I==A){if(e==null){throw"Syntax error, unrecognized expression: "+I}else{break}}A=I}return F};var h=d.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")}},relative:{"+":function(F,e,E){var C=typeof e==="string",G=C&&!/\W/.test(e),D=C&&!G;if(G&&!E){e=e.toUpperCase()}for(var B=0,A=F.length,z;B<A;B++){if((z=F[B])){while((z=z.previousSibling)&&z.nodeType!==1){}F[B]=D||z&&z.nodeName===e?z||false:z===e}}if(D){d.filter(e,F,true)}},">":function(E,z,F){var C=typeof z==="string";if(C&&!/\W/.test(z)){z=F?z:z.toUpperCase();for(var A=0,e=E.length;A<e;A++){var D=E[A];if(D){var B=D.parentNode;E[A]=B.nodeName===z?B:false}}}else{for(var A=0,e=E.length;A<e;A++){var D=E[A];if(D){E[A]=C?D.parentNode:D.parentNode===z}}if(C){d.filter(z,E,true)}}},"":function(B,z,D){var A=p++,e=y;if(!/\W/.test(z)){var C=z=D?z:z.toUpperCase();e=t}e("parentNode",z,A,B,C,D)},"~":function(B,z,D){var A=p++,e=y;if(typeof z==="string"&&!/\W/.test(z)){var C=z=D?z:z.toUpperCase();e=t}e("previousSibling",z,A,B,C,D)}},find:{ID:function(z,A,B){if(typeof A.getElementById!=="undefined"&&!B){var e=A.getElementById(z[1]);return e?[e]:[]}},NAME:function(A,D,E){if(typeof D.getElementsByName!=="undefined"){var z=[],C=D.getElementsByName(A[1]);for(var B=0,e=C.length;B<e;B++){if(C[B].getAttribute("name")===A[1]){z.push(C[B])}}return z.length===0?null:z}},TAG:function(e,z){return z.getElementsByTagName(e[1])}},preFilter:{CLASS:function(B,z,A,e,E,F){B=" "+B[1].replace(/\\/g,"")+" ";if(F){return B}for(var C=0,D;(D=z[C])!=null;C++){if(D){if(E^(D.className&&(" "+D.className+" ").indexOf(B)>=0)){if(!A){e.push(D)}}else{if(A){z[C]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(z,e){for(var A=0;e[A]===false;A++){}return e[A]&&v(e[A])?z[1]:z[1].toUpperCase()},CHILD:function(e){if(e[1]=="nth"){var z=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]=="even"&&"2n"||e[2]=="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(z[1]+(z[2]||1))-0;e[3]=z[3]-0}e[0]=p++;return e},ATTR:function(C,z,A,e,D,E){var B=C[1].replace(/\\/g,"");if(!E&&h.attrMap[B]){C[1]=h.attrMap[B]}if(C[2]==="~="){C[4]=" "+C[4]+" "}return C},PSEUDO:function(C,z,A,e,D){if(C[1]==="not"){if((w.exec(C[3])||"").length>1||/^\w/.test(C[3])){C[3]=d(C[3],null,null,z)}else{var B=d.filter(C[3],z,A,true^D);if(!A){e.push.apply(e,B)}return false}}else{if(h.match.POS.test(C[0])||h.match.CHILD.test(C[0])){return true}}return C},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(A,z,e){return !!d(e[3],A).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toUpperCase()==="BUTTON"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(z,e){return e===0},last:function(A,z,e,B){return z===B.length-1},even:function(z,e){return e%2===0},odd:function(z,e){return e%2===1},lt:function(A,z,e){return z<e[3]-0},gt:function(A,z,e){return z>e[3]-0},nth:function(A,z,e){return e[3]-0==z},eq:function(A,z,e){return e[3]-0==z}},filter:{PSEUDO:function(E,A,B,F){var z=A[1],C=h.filters[z];if(C){return C(E,B,A,F)}else{if(z==="contains"){return(E.textContent||E.innerText||"").indexOf(A[3])>=0}else{if(z==="not"){var D=A[3];for(var B=0,e=D.length;B<e;B++){if(D[B]===E){return false}}return true}}}},CHILD:function(e,B){var E=B[1],z=e;switch(E){case"only":case"first":while((z=z.previousSibling)){if(z.nodeType===1){return false}}if(E=="first"){return true}z=e;case"last":while((z=z.nextSibling)){if(z.nodeType===1){return false}}return true;case"nth":var A=B[2],H=B[3];if(A==1&&H==0){return true}var D=B[0],G=e.parentNode;if(G&&(G.sizcache!==D||!e.nodeIndex)){var C=0;for(z=G.firstChild;z;z=z.nextSibling){if(z.nodeType===1){z.nodeIndex=++C}}G.sizcache=D}var F=e.nodeIndex-H;if(A==0){return F==0}else{return(F%A==0&&F/A>=0)}}},ID:function(z,e){return z.nodeType===1&&z.getAttribute("id")===e},TAG:function(z,e){return(e==="*"&&z.nodeType===1)||z.nodeName===e},CLASS:function(z,e){return(" "+(z.className||z.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(D,B){var A=B[1],e=h.attrHandle[A]?h.attrHandle[A](D):D[A]!=null?D[A]:D.getAttribute(A),E=e+"",C=B[2],z=B[4];return e==null?C==="!=":C==="="?E===z:C==="*="?E.indexOf(z)>=0:C==="~="?(" "+E+" ").indexOf(z)>=0:!z?E&&e!==false:C==="!="?E!=z:C==="^="?E.indexOf(z)===0:C==="$="?E.substr(E.length-z.length)===z:C==="|="?E===z||E.substr(0,z.length+1)===z+"-":false},POS:function(C,z,A,D){var e=z[2],B=h.setFilters[e];if(B){return B(C,A,z,D)}}}};var q=h.match.POS;for(var s in h.match){h.match[s]=new RegExp(h.match[s].source+/(?![^\[]*\])(?![^\(]*\))/.source);h.leftMatch[s]=new RegExp(/(^(?:.|\r|\n)*?)/.source+h.match[s].source)}var b=function(z,e){z=Array.prototype.slice.call(z,0);if(e){e.push.apply(e,z);return e}return z};try{Array.prototype.slice.call(document.documentElement.childNodes,0)}catch(r){b=function(C,B){var z=B||[];if(g.call(C)==="[object Array]"){Array.prototype.push.apply(z,C)}else{if(typeof C.length==="number"){for(var A=0,e=C.length;A<e;A++){z.push(C[A])}}else{for(var A=0;C[A];A++){z.push(C[A])}}}return z}}var f;if(document.documentElement.compareDocumentPosition){f=function(z,e){if(!z.compareDocumentPosition||!e.compareDocumentPosition){if(z==e){u=true}return 0}var A=z.compareDocumentPosition(e)&4?-1:z===e?0:1;if(A===0){u=true}return A}}else{if("sourceIndex" in document.documentElement){f=function(z,e){if(!z.sourceIndex||!e.sourceIndex){if(z==e){u=true}return 0}var A=z.sourceIndex-e.sourceIndex;if(A===0){u=true}return A}}else{if(document.createRange){f=function(B,z){if(!B.ownerDocument||!z.ownerDocument){if(B==z){u=true}return 0}var A=B.ownerDocument.createRange(),e=z.ownerDocument.createRange();A.setStart(B,0);A.setEnd(B,0);e.setStart(z,0);e.setEnd(z,0);var C=A.compareBoundaryPoints(Range.START_TO_END,e);if(C===0){u=true}return C}}}}(function(){var z=document.createElement("div"),A="script"+(new Date).getTime();z.innerHTML="<a name='"+A+"'/>";var e=document.documentElement;e.insertBefore(z,e.firstChild);if(!!document.getElementById(A)){h.find.ID=function(C,D,E){if(typeof D.getElementById!=="undefined"&&!E){var B=D.getElementById(C[1]);return B?B.id===C[1]||typeof B.getAttributeNode!=="undefined"&&B.getAttributeNode("id").nodeValue===C[1]?[B]:undefined:[]}};h.filter.ID=function(D,B){var C=typeof D.getAttributeNode!=="undefined"&&D.getAttributeNode("id");return D.nodeType===1&&C&&C.nodeValue===B}}e.removeChild(z);e=z=null})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){h.find.TAG=function(z,D){var C=D.getElementsByTagName(z[1]);if(z[1]==="*"){var B=[];for(var A=0;C[A];A++){if(C[A].nodeType===1){B.push(C[A])}}C=B}return C}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){h.attrHandle.href=function(z){return z.getAttribute("href",2)}}e=null})();if(document.querySelectorAll){(function(){var e=d,A=document.createElement("div");A.innerHTML="<p class='TEST'></p>";if(A.querySelectorAll&&A.querySelectorAll(".TEST").length===0){return}d=function(E,D,B,C){D=D||document;if(!C&&D.nodeType===9&&!v(D)){try{return b(D.querySelectorAll(E),B)}catch(F){}}return e(E,D,B,C)};for(var z in e){d[z]=e[z]}A=null})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}h.order.splice(1,0,"CLASS");h.find.CLASS=function(z,A,B){if(typeof A.getElementsByClassName!=="undefined"&&!B){return A.getElementsByClassName(z[1])}};e=null})()}function t(z,E,D,I,F,H){var G=z=="previousSibling"&&!H;for(var B=0,A=I.length;B<A;B++){var e=I[B];if(e){if(G&&e.nodeType===1){e.sizcache=D;e.sizset=B}e=e[z];var C=false;while(e){if(e.sizcache===D){C=I[e.sizset];break}if(e.nodeType===1&&!H){e.sizcache=D;e.sizset=B}if(e.nodeName===E){C=e;break}e=e[z]}I[B]=C}}}function y(z,E,D,I,F,H){var G=z=="previousSibling"&&!H;for(var B=0,A=I.length;B<A;B++){var e=I[B];if(e){if(G&&e.nodeType===1){e.sizcache=D;e.sizset=B}e=e[z];var C=false;while(e){if(e.sizcache===D){C=I[e.sizset];break}if(e.nodeType===1){if(!H){e.sizcache=D;e.sizset=B}if(typeof E!=="string"){if(e===E){C=true;break}}else{if(d.filter(E,[e]).length>0){C=e;break}}}e=e[z]}I[B]=C}}}var n=document.compareDocumentPosition?function(z,e){return z.compareDocumentPosition(e)&16}:function(z,e){return z!==e&&(z.contains?z.contains(e):true)};var v=function(e){return e.nodeType===9&&e.documentElement.nodeName!=="HTML"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!=="HTML"};var l=function(e,F){var B=[],C="",D,A=F.nodeType?[F]:F;while((D=h.match.PSEUDO.exec(e))){C+=D[0];e=e.replace(h.match.PSEUDO,"")}e=h.relative[e]?e+"*":e;for(var E=0,z=A.length;E<z;E++){d(e,A[E],B)}return d.filter(C,B)};window.Sizzle=d})();(function(e){var f=Prototype.Selector.extendElements;function b(g,h){return f(e(g,h||document))}function d(h,g){return e.matches(g,[h]).length==1}Prototype.Selector.engine=e;Prototype.Selector.select=b;Prototype.Selector.match=d})(Sizzle);window.Sizzle=Prototype._original_property;delete Prototype._original_property;var Form={reset:function(b){b=$(b);b.reset();return b},serializeElements:function(n,f){if(typeof f!="object"){f={hash:!!f}}else{if(Object.isUndefined(f.hash)){f.hash=true}}var g,l,b=false,h=f.submit,d,e;if(f.hash){e={};d=function(o,p,q){if(p in o){if(!Object.isArray(o[p])){o[p]=[o[p]]}o[p].push(q)}else{o[p]=q}return o}}else{e="";d=function(o,p,q){return o+(o?"&":"")+encodeURIComponent(p)+"="+encodeURIComponent(q)}}return n.inject(e,function(o,p){if(!p.disabled&&p.name){g=p.name;l=$(p).getValue();if(l!=null&&p.type!="file"&&(p.type!="submit"||(!b&&h!==false&&(!h||g==h)&&(b=true)))){o=d(o,g,l)}}return o})}};Form.Methods={serialize:function(d,b){return Form.serializeElements(Form.getElements(d),b)},getElements:function(g){var h=$(g).getElementsByTagName("*"),f,b=[],e=Form.Element.Serializers;for(var d=0;f=h[d];d++){b.push(f)}return b.inject([],function(l,n){if(e[n.tagName.toLowerCase()]){l.push(Element.extend(n))}return l})},getInputs:function(l,e,f){l=$(l);var b=l.getElementsByTagName("input");if(!e&&!f){return $A(b).map(Element.extend)}for(var g=0,n=[],h=b.length;g<h;g++){var d=b[g];if((e&&d.type!=e)||(f&&d.name!=f)){continue}n.push(Element.extend(d))}return n},disable:function(b){b=$(b);Form.getElements(b).invoke("disable");return b},enable:function(b){b=$(b);Form.getElements(b).invoke("enable");return b},findFirstElement:function(d){var e=$(d).getElements().findAll(function(f){return"hidden"!=f.type&&!f.disabled});var b=e.findAll(function(f){return f.hasAttribute("tabIndex")&&f.tabIndex>=0}).sortBy(function(f){return f.tabIndex}).first();return b?b:e.find(function(f){return/^(?:input|select|textarea)$/i.test(f.tagName)})},focusFirstElement:function(d){d=$(d);var b=d.findFirstElement();if(b){b.activate()}return d},request:function(d,b){d=$(d),b=Object.clone(b||{});var f=b.parameters,e=d.readAttribute("action")||"";if(e.blank()){e=window.location.href}b.parameters=d.serialize(true);if(f){if(Object.isString(f)){f=f.toQueryParams()}Object.extend(b.parameters,f)}if(d.hasAttribute("method")&&!b.method){b.method=d.method}return new Ajax.Request(e,b)}};Form.Element={focus:function(b){$(b).focus();return b},select:function(b){$(b).select();return b}};Form.Element.Methods={serialize:function(b){b=$(b);if(!b.disabled&&b.name){var d=b.getValue();if(d!=undefined){var e={};e[b.name]=d;return Object.toQueryString(e)}}return""},getValue:function(b){b=$(b);var d=b.tagName.toLowerCase();return Form.Element.Serializers[d](b)},setValue:function(b,d){b=$(b);var e=b.tagName.toLowerCase();Form.Element.Serializers[e](b,d);return b},clear:function(b){$(b).value="";return b},present:function(b){return $(b).value!=""},activate:function(b){b=$(b);try{b.focus();if(b.select&&(b.tagName.toLowerCase()!="input"||!(/^(?:button|reset|submit)$/i.test(b.type)))){b.select()}}catch(d){}return b},disable:function(b){b=$(b);b.disabled=true;return b},enable:function(b){b=$(b);b.disabled=false;return b}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers=(function(){function d(n,o){switch(n.type.toLowerCase()){case"checkbox":case"radio":return h(n,o);default:return g(n,o)}}function h(n,o){if(Object.isUndefined(o)){return n.checked?n.value:null}else{n.checked=!!o}}function g(n,o){if(Object.isUndefined(o)){return n.value}else{n.value=o}}function b(p,s){if(Object.isUndefined(s)){return(p.type==="select-one"?e:f)(p)}var o,q,t=!Object.isArray(s);for(var n=0,r=p.length;n<r;n++){o=p.options[n];q=this.optionValue(o);if(t){if(q==s){o.selected=true;return}}else{o.selected=s.include(q)}}}function e(o){var n=o.selectedIndex;return n>=0?l(o.options[n]):null}function f(q){var n,r=q.length;if(!r){return null}for(var p=0,n=[];p<r;p++){var o=q.options[p];if(o.selected){n.push(l(o))}}return n}function l(n){return Element.hasAttribute(n,"value")?n.value:n.text}return{input:d,inputSelector:h,textarea:g,select:b,selectOne:e,selectMany:f,optionValue:l,button:g}})();Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,b,d,e){$super(e,d);this.element=$(b);this.lastValue=this.getValue()},execute:function(){var b=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(b)?this.lastValue!=b:String(this.lastValue)!=String(b)){this.callback(this.element,b);this.lastValue=b}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element)}});Abstract.EventObserver=Class.create({initialize:function(b,d){this.element=$(b);this.callback=d;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=="form"){this.registerFormCallbacks()}else{this.registerCallback(this.element)}},onElementEvent:function(){var b=this.getValue();if(this.lastValue!=b){this.callback(this.element,b);this.lastValue=b}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this)},registerCallback:function(b){if(b.type){switch(b.type.toLowerCase()){case"checkbox":case"radio":Event.observe(b,"click",this.onElementEvent.bind(this));break;default:Event.observe(b,"change",this.onElementEvent.bind(this));break}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element)}});(function(){var J={KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{}};var h=document.documentElement;var K="onmouseenter" in h&&"onmouseleave" in h;var b=function(L){return false};if(window.attachEvent){if(window.addEventListener){b=function(L){return !(L instanceof window.Event)}}else{b=function(L){return true}}}var y;function H(M,L){return M.which?(M.which===L+1):(M.button===L)}var u={0:1,1:4,2:2};function F(M,L){return M.button===u[L]}function I(M,L){switch(L){case 0:return M.which==1&&!M.metaKey;case 1:return M.which==2||(M.which==1&&M.metaKey);case 2:return M.which==3;default:return false}}if(window.attachEvent){if(!window.addEventListener){y=F}else{y=function(M,L){return b(M)?F(M,L):H(M,L)}}}else{if(Prototype.Browser.WebKit){y=I}else{y=H}}function C(L){return y(L,0)}function A(L){return y(L,1)}function t(L){return y(L,2)}function f(N){N=J.extend(N);var M=N.target,L=N.type,O=N.currentTarget;if(O&&O.tagName){if(L==="load"||L==="error"||(L==="click"&&O.tagName.toLowerCase()==="input"&&O.type==="radio")){M=O}}if(M.nodeType==Node.TEXT_NODE){M=M.parentNode}return Element.extend(M)}function v(M,N){var L=J.element(M);if(!N){return L}while(L){if(Object.isElement(L)&&Prototype.Selector.match(L,N)){return Element.extend(L)}L=L.parentNode}}function z(L){return{x:e(L),y:d(L)}}function e(N){var M=document.documentElement,L=document.body||{scrollLeft:0};return N.pageX||(N.clientX+(M.scrollLeft||L.scrollLeft)-(M.clientLeft||0))}function d(N){var M=document.documentElement,L=document.body||{scrollTop:0};return N.pageY||(N.clientY+(M.scrollTop||L.scrollTop)-(M.clientTop||0))}function w(L){J.extend(L);L.preventDefault();L.stopPropagation();L.stopped=true}J.Methods={isLeftClick:C,isMiddleClick:A,isRightClick:t,element:f,findElement:v,pointer:z,pointerX:e,pointerY:d,stop:w};var E=Object.keys(J.Methods).inject({},function(L,M){L[M]=J.Methods[M].methodize();return L});if(window.attachEvent){function o(M){var L;switch(M.type){case"mouseover":case"mouseenter":L=M.fromElement;break;case"mouseout":case"mouseleave":L=M.toElement;break;default:return null}return Element.extend(L)}var B={stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return"[object Event]"}};J.extend=function(M,L){if(!M){return false}if(!b(M)){return M}if(M._extendedByPrototype){return M}M._extendedByPrototype=Prototype.emptyFunction;var N=J.pointer(M);Object.extend(M,{target:M.srcElement||L,relatedTarget:o(M),pageX:N.x,pageY:N.y});Object.extend(M,E);Object.extend(M,B);return M}}else{J.extend=Prototype.K}if(window.addEventListener){J.prototype=window.Event.prototype||document.createEvent("HTMLEvents").__proto__;Object.extend(J.prototype,E)}function s(P,O,Q){var N=Element.retrieve(P,"prototype_event_registry");if(Object.isUndefined(N)){g.push(P);N=Element.retrieve(P,"prototype_event_registry",$H())}var L=N.get(O);if(Object.isUndefined(L)){L=[];N.set(O,L)}if(L.pluck("handler").include(Q)){return false}var M;if(O.include(":")){M=function(R){if(Object.isUndefined(R.eventName)){return false}if(R.eventName!==O){return false}J.extend(R,P);Q.call(P,R)}}else{if(!K&&(O==="mouseenter"||O==="mouseleave")){if(O==="mouseenter"||O==="mouseleave"){M=function(S){J.extend(S,P);var R=S.relatedTarget;while(R&&R!==P){try{R=R.parentNode}catch(T){R=P}}if(R===P){return}Q.call(P,S)}}}else{M=function(R){J.extend(R,P);Q.call(P,R)}}}M.handler=Q;L.push(M);return M}function n(){for(var L=0,M=g.length;L<M;L++){J.stopObserving(g[L]);g[L]=null}}var g=[];if(Prototype.Browser.IE){window.attachEvent("onunload",n)}if(Prototype.Browser.WebKit){window.addEventListener("unload",Prototype.emptyFunction,false)}var r=Prototype.K,l={mouseenter:"mouseover",mouseleave:"mouseout"};if(!K){r=function(L){return(l[L]||L)}}function D(O,N,P){O=$(O);var M=s(O,N,P);if(!M){return O}if(N.include(":")){if(O.addEventListener){O.addEventListener("dataavailable",M,false)}else{O.attachEvent("ondataavailable",M);O.attachEvent("onlosecapture",M)}}else{var L=r(N);if(O.addEventListener){O.addEventListener(L,M,false)}else{O.attachEvent("on"+L,M)}}return O}function q(R,O,S){R=$(R);var N=Element.retrieve(R,"prototype_event_registry");if(!N){return R}if(!O){N.each(function(U){var T=U.key;q(R,T)});return R}var P=N.get(O);if(!P){return R}if(!S){P.each(function(T){q(R,O,T.handler)});return R}var Q=P.length,M;while(Q--){if(P[Q].handler===S){M=P[Q];break}}if(!M){return R}if(O.include(":")){if(R.removeEventListener){R.removeEventListener("dataavailable",M,false)}else{R.detachEvent("ondataavailable",M);R.detachEvent("onlosecapture",M)}}else{var L=r(O);if(R.removeEventListener){R.removeEventListener(L,M,false)}else{R.detachEvent("on"+L,M)}}N.set(O,P.without(M));return R}function G(O,N,M,L){O=$(O);if(Object.isUndefined(L)){L=true}if(O==document&&document.createEvent&&!O.dispatchEvent){O=document.documentElement}var P;if(document.createEvent){P=document.createEvent("HTMLEvents");P.initEvent("dataavailable",L,true)}else{P=document.createEventObject();P.eventType=L?"ondataavailable":"onlosecapture"}P.eventName=N;P.memo=M||{};if(document.createEvent){O.dispatchEvent(P)}else{O.fireEvent(P.eventType,P)}return J.extend(P)}J.Handler=Class.create({initialize:function(N,M,L,O){this.element=$(N);this.eventName=M;this.selector=L;this.callback=O;this.handler=this.handleEvent.bind(this)},start:function(){J.observe(this.element,this.eventName,this.handler);return this},stop:function(){J.stopObserving(this.element,this.eventName,this.handler);return this},handleEvent:function(M){var L=J.findElement(M,this.selector);if(L){this.callback.call(this.element,M,L)}}});function p(N,M,L,O){N=$(N);if(Object.isFunction(L)&&Object.isUndefined(O)){O=L,L=null}return new J.Handler(N,M,L,O).start()}Object.extend(J,J.Methods);Object.extend(J,{fire:G,observe:D,stopObserving:q,on:p});Element.addMethods({fire:G,observe:D,stopObserving:q,on:p});Object.extend(document,{fire:G.methodize(),observe:D.methodize(),stopObserving:q.methodize(),on:p.methodize(),loaded:false});if(window.Event){Object.extend(window.Event,J)}else{window.Event=J}})();(function(){var e;function b(){if(document.loaded){return}if(e){window.clearTimeout(e)}document.loaded=true;document.fire("dom:loaded")}function d(){if(document.readyState==="complete"){document.stopObserving("readystatechange",d);b()}}if(document.addEventListener){document.addEventListener("DOMContentLoaded",b,false)}else{document.observe("readystatechange",d);if(window==top){var e=window.setInterval(function(){try{document.documentElement.doScroll("left")}catch(f){return}window.clearInterval(e);b()},5)}}Event.observe(window,"load",b)})();Element.addMethods();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(b,d){return Element.insert(b,{before:d})},Top:function(b,d){return Element.insert(b,{top:d})},Bottom:function(b,d){return Element.insert(b,{bottom:d})},After:function(b,d){return Element.insert(b,{after:d})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(d,b,e){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(d,b,e)}this.xcomp=b;this.ycomp=e;this.offset=Element.cumulativeOffset(d);return(e>=this.offset[1]&&e<this.offset[1]+d.offsetHeight&&b>=this.offset[0]&&b<this.offset[0]+d.offsetWidth)},withinIncludingScrolloffsets:function(d,b,f){var e=Element.cumulativeScrollOffset(d);this.xcomp=b+e[0]-this.deltaX;this.ycomp=f+e[1]-this.deltaY;this.offset=Element.cumulativeOffset(d);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+d.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+d.offsetWidth)},overlap:function(d,b){if(!d){return 0}if(d=="vertical"){return((this.offset[1]+b.offsetHeight)-this.ycomp)/b.offsetHeight}if(d=="horizontal"){return((this.offset[0]+b.offsetWidth)-this.xcomp)/b.offsetWidth}},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(b){Position.prepare();return Element.absolutize(b)},relativize:function(b){Position.prepare();return Element.relativize(b)},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(d,e,b){b=b||{};return Element.clonePosition(e,d,b)}};if(!document.getElementsByClassName){document.getElementsByClassName=function(d){function b(e){return e.blank()?null:"[contains(concat(' ', @class, ' '), ' "+e+" ')]"}d.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(e,g){g=g.toString().strip();var f=/\s/.test(g)?$w(g).map(b).join(""):b(g);return f?document._getElementsByXPath(".//*"+f,e):[]}:function(g,h){h=h.toString().strip();var l=[],n=(/\s/.test(h)?$w(h):null);if(!n&&!h){return l}var e=$(g).getElementsByTagName("*");h=" "+h+" ";for(var f=0,p,o;p=e[f];f++){if(p.className&&(o=" "+p.className+" ")&&(o.include(h)||(n&&n.all(function(q){return !q.toString().blank()&&o.include(" "+q+" ")})))){l.push(Element.extend(p))}}return l};return function(f,e){return $(e||document.body).getElementsByClassName(f)}}(Element.Methods)}Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(b){this.element=$(b)},_each:function(b){this.element.className.split(/\s+/).select(function(d){return d.length>0})._each(b)},set:function(b){this.element.className=b},add:function(b){if(this.include(b)){return}this.set($A(this).concat(b).join(" "))},remove:function(b){if(!this.include(b)){return}this.set($A(this).without(b).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);(function(){window.Selector=Class.create({initialize:function(b){this.expression=b.strip()},findElements:function(b){return Prototype.Selector.select(this.expression,b)},match:function(b){return Prototype.Selector.match(b,this.expression)},toString:function(){return this.expression},inspect:function(){return"#<Selector: "+this.expression+">"}});Object.extend(Selector,{matchElements:function(h,l){var b=Prototype.Selector.match,f=[];for(var e=0,g=h.length;e<g;e++){var d=h[e];if(b(d,l)){f.push(Element.extend(d))}}return f},findElement:function(h,l,d){d=d||0;var b=0,f;for(var e=0,g=h.length;e<g;e++){f=h[e];if(Prototype.Selector.match(f,l)&&d===b++){return Element.extend(f)}}},findChildElements:function(d,e){var b=e.toArray().join(", ");return Prototype.Selector.select(b,d||document)}})})();var Window=Class.create();Window.keepMultiModalWindow=false;Window.hasEffectLib=(typeof Effect!="undefined");Window.resizeEffectDuration=0.4;Window.prototype={initialize:function(){var e;var d=0;if(arguments.length>0){if(typeof arguments[0]=="string"){e=arguments[0];d=1}else{e=arguments[0]?arguments[0].id:null}}if(!e){e="window_"+new Date().getTime()}if($(e)){alert("Window "+e+" is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor")}this.options=Object.extend({className:"dialog",windowClassName:null,blurClassName:null,minWidth:100,minHeight:20,resizable:true,closable:true,minimizable:true,maximizable:true,draggable:true,userData:null,showEffect:(Window.hasEffectLib?Effect.Appear:Element.show),hideEffect:(Window.hasEffectLib?Effect.Fade:Element.hide),showEffectOptions:{},hideEffectOptions:{},effectOptions:null,parent:document.body,title:" ",url:null,onload:Prototype.emptyFunction,width:200,height:300,opacity:1,recenterAuto:true,wiredDrag:false,closeOnEsc:true,closeCallback:null,destroyOnClose:false,gridX:1,gridY:1},arguments[d]||{});if(this.options.blurClassName){this.options.focusClassName=this.options.className}if(typeof this.options.top=="undefined"&&typeof this.options.bottom=="undefined"){this.options.top=this._round(Math.random()*500,this.options.gridY)}if(typeof this.options.left=="undefined"&&typeof this.options.right=="undefined"){this.options.left=this._round(Math.random()*500,this.options.gridX)}if(this.options.effectOptions){Object.extend(this.options.hideEffectOptions,this.options.effectOptions);Object.extend(this.options.showEffectOptions,this.options.effectOptions);if(this.options.showEffect==Element.Appear){this.options.showEffectOptions.to=this.options.opacity}}if(Window.hasEffectLib){if(this.options.showEffect==Effect.Appear){this.options.showEffectOptions.to=this.options.opacity}if(this.options.hideEffect==Effect.Fade){this.options.hideEffectOptions.from=this.options.opacity}}if(this.options.hideEffect==Element.hide){this.options.hideEffect=function(){Element.hide(this.element);if(this.options.destroyOnClose){this.destroy()}}.bind(this)}if(this.options.parent!=document.body){this.options.parent=$(this.options.parent)}this.element=this._createWindow(e);this.element.win=this;this.eventMouseDown=this._initDrag.bindAsEventListener(this);this.eventMouseUp=this._endDrag.bindAsEventListener(this);this.eventMouseMove=this._updateDrag.bindAsEventListener(this);this.eventOnLoad=this._getWindowBorderSize.bindAsEventListener(this);this.eventMouseDownContent=this.toFront.bindAsEventListener(this);this.eventResize=this._recenter.bindAsEventListener(this);this.eventKeyUp=this._keyUp.bindAsEventListener(this);this.topbar=$(this.element.id+"_top");this.bottombar=$(this.element.id+"_bottom");this.content=$(this.element.id+"_content");Event.observe(this.topbar,"mousedown",this.eventMouseDown);Event.observe(this.bottombar,"mousedown",this.eventMouseDown);Event.observe(this.content,"mousedown",this.eventMouseDownContent);Event.observe(window,"load",this.eventOnLoad);Event.observe(window,"resize",this.eventResize);Event.observe(window,"scroll",this.eventResize);Event.observe(document,"keyup",this.eventKeyUp);Event.observe(this.options.parent,"scroll",this.eventResize);if(this.options.draggable){var b=this;[this.topbar,this.topbar.up().previous(),this.topbar.up().next()].each(function(f){f.observe("mousedown",b.eventMouseDown);f.addClassName("top_draggable")});[this.bottombar.up(),this.bottombar.up().previous(),this.bottombar.up().next()].each(function(f){f.observe("mousedown",b.eventMouseDown);f.addClassName("bottom_draggable")})}if(this.options.resizable){this.sizer=$(this.element.id+"_sizer");Event.observe(this.sizer,"mousedown",this.eventMouseDown)}this.useLeft=null;this.useTop=null;if(typeof this.options.left!="undefined"){this.element.setStyle({left:parseFloat(this.options.left)+"px"});this.useLeft=true}else{this.element.setStyle({right:parseFloat(this.options.right)+"px"});this.useLeft=false}if(typeof this.options.top!="undefined"){this.element.setStyle({top:parseFloat(this.options.top)+"px"});this.useTop=true}else{this.element.setStyle({bottom:parseFloat(this.options.bottom)+"px"});this.useTop=false}this.storedLocation=null;this.setOpacity(this.options.opacity);if(this.options.zIndex){this.setZIndex(this.options.zIndex)}else{this.setZIndex(this.getMaxZIndex())}if(this.options.destroyOnClose){this.setDestroyOnClose(true)}this._getWindowBorderSize();this.width=this.options.width;this.height=this.options.height;this.visible=false;this.constraint=false;this.constraintPad={top:0,left:0,bottom:0,right:0};if(this.width&&this.height){this.setSize(this.options.width,this.options.height)}this.setTitle(this.options.title);Windows.register(this)},getMaxZIndex:function(){var b=0,d;var g=document.body.childNodes;for(d=0;d<g.length;d++){var e=g[d];var f=e.nodeType==1?parseInt(e.style.zIndex,10)||0:0;if(f<10000){b=Math.max(b,f)}}return b+10},destroy:function(){this._notify("onDestroy");Event.stopObserving(this.topbar,"mousedown",this.eventMouseDown);Event.stopObserving(this.bottombar,"mousedown",this.eventMouseDown);Event.stopObserving(this.content,"mousedown",this.eventMouseDownContent);Event.stopObserving(window,"load",this.eventOnLoad);Event.stopObserving(window,"resize",this.eventResize);Event.stopObserving(window,"scroll",this.eventResize);Event.stopObserving(this.content,"load",this.options.onload);Event.stopObserving(document,"keyup",this.eventKeyUp);if(this._oldParent){var e=this.getContent();var b=null;for(var d=0;d<e.childNodes.length;d++){b=e.childNodes[d];if(b.nodeType==1){break}b=null}if(b){this._oldParent.appendChild(b)}this._oldParent=null}if(this.sizer){Event.stopObserving(this.sizer,"mousedown",this.eventMouseDown)}if(this.options.url){this.content.src=null}if(this.iefix){Element.remove(this.iefix)}Element.remove(this.element);Windows.unregister(this)},setCloseCallback:function(b){this.options.closeCallback=b},getContent:function(){return this.content},setContent:function(n,l,e){var b=$(n);if(null==b){throw"Unable to find element '"+n+"' in DOM"}this._oldParent=b.parentNode;var h=null;var g=null;if(l){h=Element.getDimensions(b)}if(e){g=Position.cumulativeOffset(b)}var f=this.getContent();this.setHTMLContent("");f=this.getContent();f.appendChild(b);b.show();if(l){this.setSize(h.width,h.height)}if(e){this.setLocation(g[1]-this.heightN,g[0]-this.widthW)}},setHTMLContent:function(b){if(this.options.url){this.content.src=null;this.options.url=null;var d='<div id="'+this.getId()+'_content" class="'+this.options.className+'_content"> </div>';$(this.getId()+"_table_content").innerHTML=d;this.content=$(this.element.id+"_content")}this.getContent().innerHTML=b},setAjaxContent:function(d,b,f,e){this.showFunction=f?"showCenter":"show";this.showModal=e||false;b=b||{};this.setHTMLContent("");this.onComplete=b.onComplete;if(!this._onCompleteHandler){this._onCompleteHandler=this._setAjaxContent.bind(this)}b.onComplete=this._onCompleteHandler;new Ajax.Request(d,b);b.onComplete=this.onComplete},_setAjaxContent:function(b){Element.update(this.getContent(),b.responseText);if(this.onComplete){this.onComplete(b)}this.onComplete=null;this[this.showFunction](this.showModal)},setURL:function(b){if(this.options.url){this.content.src=null}this.options.url=b;var d="<iframe frameborder='0' name='"+this.getId()+"_content' id='"+this.getId()+"_content' src='"+b+"' width='"+this.width+"' height='"+this.height+"'> </iframe>";$(this.getId()+"_table_content").innerHTML=d;this.content=$(this.element.id+"_content")},getURL:function(){return this.options.url?this.options.url:null},refresh:function(){if(this.options.url){$(this.element.getAttribute("id")+"_content").src=this.options.url}},setCookie:function(d,e,t,g,b){d=d||this.element.id;this.cookie=[d,e,t,g,b];var r=WindowUtilities.getCookie(d);if(r){var s=r.split(",");var p=s[0].split(":");var o=s[1].split(":");var q=parseFloat(s[2]),l=parseFloat(s[3]);var n=s[4];var f=s[5];this.setSize(q,l);if(n=="true"){this.doMinimize=true}else{if(f=="true"){this.doMaximize=true}}this.useLeft=p[0]=="l";this.useTop=o[0]=="t";this.element.setStyle(this.useLeft?{left:p[1]}:{right:p[1]});this.element.setStyle(this.useTop?{top:o[1]}:{bottom:o[1]})}},getId:function(){return this.element.id},setDestroyOnClose:function(){this.options.destroyOnClose=true},setConstraint:function(b,d){this.constraint=b;this.constraintPad=Object.extend(this.constraintPad,d||{});if(this.useTop&&this.useLeft){this.setLocation(parseFloat(this.element.style.top),parseFloat(this.element.style.left))}},_initDrag:function(d){if(Event.element(d)==this.sizer&&this.isMinimized()){return}if(Event.element(d)!=this.sizer&&this.isMaximized()){return}if(Prototype.Browser.IE&&this.heightN==0){this._getWindowBorderSize()}this.pointer=[this._round(Event.pointerX(d),this.options.gridX),this._round(Event.pointerY(d),this.options.gridY)];if(this.options.wiredDrag){this.currentDrag=this._createWiredElement()}else{this.currentDrag=this.element}if(Event.element(d)==this.sizer){this.doResize=true;this.widthOrg=this.width;this.heightOrg=this.height;this.bottomOrg=parseFloat(this.element.getStyle("bottom"));this.rightOrg=parseFloat(this.element.getStyle("right"));this._notify("onStartResize")}else{this.doResize=false;var b=$(this.getId()+"_close");if(b&&Position.within(b,this.pointer[0],this.pointer[1])){this.currentDrag=null;return}this.toFront();if(!this.options.draggable){return}this._notify("onStartMove")}Event.observe(document,"mouseup",this.eventMouseUp,false);Event.observe(document,"mousemove",this.eventMouseMove,false);WindowUtilities.disableScreen("__invisible__","__invisible__",this.overlayOpacity);document.body.ondrag=function(){return false};document.body.onselectstart=function(){return false};this.currentDrag.show();Event.stop(d)},_round:function(d,b){return b==1?d:d=Math.floor(d/b)*b},_updateDrag:function(d){var b=[this._round(Event.pointerX(d),this.options.gridX),this._round(Event.pointerY(d),this.options.gridY)];var q=b[0]-this.pointer[0];var p=b[1]-this.pointer[1];if(this.doResize){var o=this.widthOrg+q;var f=this.heightOrg+p;q=this.width-this.widthOrg;p=this.height-this.heightOrg;if(this.useLeft){o=this._updateWidthConstraint(o)}else{this.currentDrag.setStyle({right:(this.rightOrg-q)+"px"})}if(this.useTop){f=this._updateHeightConstraint(f)}else{this.currentDrag.setStyle({bottom:(this.bottomOrg-p)+"px"})}this.setSize(o,f);this._notify("onResize")}else{this.pointer=b;if(this.useLeft){var e=parseFloat(this.currentDrag.getStyle("left"))+q;var n=this._updateLeftConstraint(e);this.pointer[0]+=n-e;this.currentDrag.setStyle({left:n+"px"})}else{this.currentDrag.setStyle({right:parseFloat(this.currentDrag.getStyle("right"))-q+"px"})}if(this.useTop){var l=parseFloat(this.currentDrag.getStyle("top"))+p;var g=this._updateTopConstraint(l);this.pointer[1]+=g-l;this.currentDrag.setStyle({top:g+"px"})}else{this.currentDrag.setStyle({bottom:parseFloat(this.currentDrag.getStyle("bottom"))-p+"px"})}this._notify("onMove")}if(this.iefix){this._fixIEOverlapping()}this._removeStoreLocation();Event.stop(d)},_endDrag:function(b){WindowUtilities.enableScreen("__invisible__");if(this.doResize){this._notify("onEndResize")}else{this._notify("onEndMove")}Event.stopObserving(document,"mouseup",this.eventMouseUp,false);Event.stopObserving(document,"mousemove",this.eventMouseMove,false);Event.stop(b);this._hideWiredElement();this._saveCookie();document.body.ondrag=null;document.body.onselectstart=null},_updateLeftConstraint:function(d){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowWidth:this.options.parent.getDimensions().width;if(d<this.constraintPad.left){d=this.constraintPad.left}if(d+this.width+this.widthE+this.widthW>b-this.constraintPad.right){d=b-this.constraintPad.right-this.width-this.widthE-this.widthW}}return d},_updateTopConstraint:function(e){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowHeight:this.options.parent.getDimensions().height;var d=this.height+this.heightN+this.heightS;if(e<this.constraintPad.top){e=this.constraintPad.top}if(e+d>b-this.constraintPad.bottom){e=b-this.constraintPad.bottom-d}}return e},_updateWidthConstraint:function(b){if(this.constraint&&this.useLeft&&this.useTop){var d=this.options.parent==document.body?WindowUtilities.getPageSize().windowWidth:this.options.parent.getDimensions().width;var e=parseFloat(this.element.getStyle("left"));if(e+b+this.widthE+this.widthW>d-this.constraintPad.right){b=d-this.constraintPad.right-e-this.widthE-this.widthW}}return b},_updateHeightConstraint:function(d){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowHeight:this.options.parent.getDimensions().height;var e=parseFloat(this.element.getStyle("top"));if(e+d+this.heightN+this.heightS>b-this.constraintPad.bottom){d=b-this.constraintPad.bottom-e-this.heightN-this.heightS}}return d},_createWindow:function(b){var h=this.options.className;var f=document.createElement("div");f.setAttribute("id",b);f.className="dialog";if(this.options.windowClassName){f.className+=" "+this.options.windowClassName}var g;if(this.options.url){g='<iframe frameborder="0" name="'+b+'_content" id="'+b+'_content" src="'+this.options.url+'"> </iframe>'}else{g='<div id="'+b+'_content" class="'+h+'_content"> </div>'}var l=this.options.closable?"<div class='"+h+"_close' id='"+b+"_close' onclick='Windows.close(\""+b+"\", event)'> </div>":"";var n=this.options.minimizable?"<div class='"+h+"_minimize' id='"+b+"_minimize' onclick='Windows.minimize(\""+b+"\", event)'> </div>":"";var o=this.options.maximizable?"<div class='"+h+"_maximize' id='"+b+"_maximize' onclick='Windows.maximize(\""+b+"\", event)'> </div>":"";var e=this.options.resizable?"class='"+h+"_sizer' id='"+b+"_sizer'":"class='"+h+"_se'";var d="../themes/default/blank.gif";f.innerHTML=l+n+o+" <a href='#' id='"+b+"_focus_anchor'><!-- --></a> <table id='"+b+"_row1' class=\"top table_window\"> <tr> <td class='"+h+"_nw'></td> <td class='"+h+"_n'><div id='"+b+"_top' class='"+h+"_title title_window'>"+this.options.title+"</div></td> <td class='"+h+"_ne'></td> </tr> </table> <table id='"+b+"_row2' class=\"mid table_window\"> <tr> <td class='"+h+"_w'></td> <td id='"+b+"_table_content' class='"+h+"_content' valign='top'>"+g+"</td> <td class='"+h+"_e'></td> </tr> </table> <table id='"+b+"_row3' class=\"bot table_window\"> <tr> <td class='"+h+"_sw'></td> <td class='"+h+"_s'><div id='"+b+"_bottom' class='status_bar'><span style='float:left; width:1px; height:1px'></span></div></td> <td "+e+"></td> </tr> </table> ";Element.hide(f);this.options.parent.insertBefore(f,this.options.parent.firstChild);Event.observe($(b+"_content"),"load",this.options.onload);return f},changeClassName:function(b){var d=this.options.className;var e=this.getId();$A(["_close","_minimize","_maximize","_sizer","_content"]).each(function(f){this._toggleClassName($(e+f),d+f,b+f)}.bind(this));this._toggleClassName($(e+"_top"),d+"_title",b+"_title");$$("#"+e+" td").each(function(f){f.className=f.className.sub(d,b)});this.options.className=b},_toggleClassName:function(e,d,b){if(e){e.removeClassName(d);e.addClassName(b)}},setLocation:function(f,d){f=this._updateTopConstraint(f);d=this._updateLeftConstraint(d);var b=this.currentDrag||this.element;b.setStyle({top:f+"px"});b.setStyle({left:d+"px"});this.useLeft=true;this.useTop=true},getLocation:function(){var b={};if(this.useTop){b=Object.extend(b,{top:this.element.getStyle("top")})}else{b=Object.extend(b,{bottom:this.element.getStyle("bottom")})}if(this.useLeft){b=Object.extend(b,{left:this.element.getStyle("left")})}else{b=Object.extend(b,{right:this.element.getStyle("right")})}return b},getSize:function(){return{width:this.width,height:this.height}},setSize:function(f,d,b){f=parseFloat(f);d=parseFloat(d);if(!this.minimized&&f<this.options.minWidth){f=this.options.minWidth}if(!this.minimized&&d<this.options.minHeight){d=this.options.minHeight}if(this.options.maxHeight&&d>this.options.maxHeight){d=this.options.maxHeight}if(this.options.maxWidth&&f>this.options.maxWidth){f=this.options.maxWidth}if(this.useTop&&this.useLeft&&Window.hasEffectLib&&Effect.ResizeWindow&&b){new Effect.ResizeWindow(this,null,null,f,d,{duration:Window.resizeEffectDuration})}else{this.width=f;this.height=d;var h=this.currentDrag?this.currentDrag:this.element;h.setStyle({width:f+this.widthW+this.widthE+"px"});h.setStyle({height:d+this.heightN+this.heightS+"px"});if(!this.currentDrag||this.currentDrag==this.element){var g=$(this.element.id+"_content");g.setStyle({height:d+"px"});g.setStyle({width:f+"px"})}}},updateHeight:function(){this.setSize(this.width,this.content.scrollHeight,true)},updateWidth:function(){this.setSize(this.content.scrollWidth,this.height,true)},toFront:function(){if(this.element.style.zIndex<Windows.maxZIndex){this.setZIndex(Windows.maxZIndex+1)}if(this.iefix){this._fixIEOverlapping()}},getBounds:function(d){if(!this.width||!this.height||!this.visible){this.computeBounds()}var b=this.width;var e=this.height;if(!d){b+=this.widthW+this.widthE;e+=this.heightN+this.heightS}var f=Object.extend(this.getLocation(),{width:b+"px",height:e+"px"});return f},computeBounds:function(){if(!this.width||!this.height){var b=WindowUtilities._computeSize(this.content.innerHTML,this.content.id,this.width,this.height,0,this.options.className);if(this.height){this.width=b+5}else{this.height=b+5}}this.setSize(this.width,this.height);if(this.centered){this._center(this.centerTop,this.centerLeft)}},show:function(d){this.visible=true;if(d){if(typeof this.overlayOpacity=="undefined"){var b=this;setTimeout(function(){b.show(d)},10);return}Windows.addModalWindow(this);this.modal=true;this.setZIndex(Windows.maxZIndex+1);Windows.unsetOverflow(this)}else{if(!this.element.style.zIndex){this.setZIndex(Windows.maxZIndex+1)}}if(this.oldStyle){this.getContent().setStyle({overflow:this.oldStyle})}this.computeBounds();this._notify("onBeforeShow");if(this.options.showEffect!=Element.show&&this.options.showEffectOptions){this.options.showEffect(this.element,this.options.showEffectOptions)}else{this.options.showEffect(this.element)}this._checkIEOverlapping();WindowUtilities.focusedWindow=this;this._notify("onShow");$(this.element.id+"_focus_anchor").focus()},showCenter:function(b,e,d){this.centered=true;this.centerTop=e;this.centerLeft=d;this.show(b)},isVisible:function(){return this.visible},_center:function(e,d){var f=WindowUtilities.getWindowScroll(this.options.parent);var b=WindowUtilities.getPageSize(this.options.parent);if(typeof e=="undefined"){e=(b.windowHeight-(this.height+this.heightN+this.heightS))/2}e+=f.top;if(typeof d=="undefined"){d=(b.windowWidth-(this.width+this.widthW+this.widthE))/2}d+=f.left;this.setLocation(e,d);this.toFront()},_recenter:function(d){if(this.centered){var b=WindowUtilities.getPageSize(this.options.parent);var e=WindowUtilities.getWindowScroll(this.options.parent);if(this.pageSize&&this.pageSize.windowWidth==b.windowWidth&&this.pageSize.windowHeight==b.windowHeight&&this.windowScroll.left==e.left&&this.windowScroll.top==e.top){return}this.pageSize=b;this.windowScroll=e;if($("overlay_modal")){$("overlay_modal").setStyle({height:(b.pageHeight+"px")})}if(this.options.recenterAuto){this._center(this.centerTop,this.centerLeft)}}},hide:function(){this.visible=false;if(this.modal){Windows.removeModalWindow(this);Windows.resetOverflow()}this.oldStyle=this.getContent().getStyle("overflow")||"auto";this.getContent().setStyle({overflow:"hidden"});this.options.hideEffect(this.element,this.options.hideEffectOptions);if(this.iefix){this.iefix.hide()}if(!this.doNotNotifyHide){this._notify("onHide")}},close:function(){if(this.visible){if(this.options.closeCallback&&!this.options.closeCallback(this)){return}if(this.options.destroyOnClose){var b=this.destroy.bind(this);if(this.options.hideEffectOptions.afterFinish){var d=this.options.hideEffectOptions.afterFinish;this.options.hideEffectOptions.afterFinish=function(){d();b()}}else{this.options.hideEffectOptions.afterFinish=function(){b()}}}Windows.updateFocusedWindow();this.doNotNotifyHide=true;this.hide();this.doNotNotifyHide=false;this._notify("onClose")}},minimize:function(){if(this.resizing){return}var b=$(this.getId()+"_row2");if(!this.minimized){this.minimized=true;var f=b.getDimensions().height;this.r2Height=f;var e=this.element.getHeight()-f;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,null,null,null,this.height-f,{duration:Window.resizeEffectDuration})}else{this.height-=f;this.element.setStyle({height:e+"px"});b.hide()}if(!this.useTop){var d=parseFloat(this.element.getStyle("bottom"));this.element.setStyle({bottom:(d+f)+"px"})}}else{this.minimized=false;var f=this.r2Height;this.r2Height=null;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,null,null,null,this.height+f,{duration:Window.resizeEffectDuration})}else{var e=this.element.getHeight()+f;this.height+=f;this.element.setStyle({height:e+"px"});b.show()}if(!this.useTop){var d=parseFloat(this.element.getStyle("bottom"));this.element.setStyle({bottom:(d-f)+"px"})}this.toFront()}this._notify("onMinimize");this._saveCookie()},maximize:function(){if(this.isMinimized()||this.resizing){return}if(Prototype.Browser.IE&&this.heightN==0){this._getWindowBorderSize()}if(this.storedLocation!=null){this._restoreLocation();if(this.iefix){this.iefix.hide()}}else{this._storeLocation();Windows.unsetOverflow(this);var l=WindowUtilities.getWindowScroll(this.options.parent);var d=WindowUtilities.getPageSize(this.options.parent);var h=l.left;var g=l.top;if(this.options.parent!=document.body){l={top:0,left:0,bottom:0,right:0};var f=this.options.parent.getDimensions();d.windowWidth=f.width;d.windowHeight=f.height;g=0;h=0}if(this.constraint){d.windowWidth-=Math.max(0,this.constraintPad.left)+Math.max(0,this.constraintPad.right);d.windowHeight-=Math.max(0,this.constraintPad.top)+Math.max(0,this.constraintPad.bottom);h+=Math.max(0,this.constraintPad.left);g+=Math.max(0,this.constraintPad.top)}var e=d.windowWidth-this.widthW-this.widthE;var b=d.windowHeight-this.heightN-this.heightS;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,g,h,e,b,{duration:Window.resizeEffectDuration})}else{this.setSize(e,b);this.element.setStyle(this.useLeft?{left:h}:{right:h});this.element.setStyle(this.useTop?{top:g}:{bottom:g})}this.toFront();if(this.iefix){this._fixIEOverlapping()}}this._notify("onMaximize");this._saveCookie()},isMinimized:function(){return this.minimized},isMaximized:function(){return(this.storedLocation!=null)},setOpacity:function(b){if(Element.setOpacity){Element.setOpacity(this.element,b)}},setZIndex:function(b){this.element.setStyle({zIndex:b});Windows.updateZindex(b,this)},setTitle:function(b){if(!b||b==""){b=" "}Element.update(this.element.id+"_top",b)},getTitle:function(){return $(this.element.id+"_top").innerHTML},setStatusBar:function(d){var b=$(this.getId()+"_bottom");if(typeof(d)=="object"){if(this.bottombar.firstChild){this.bottombar.replaceChild(d,this.bottombar.firstChild)}else{this.bottombar.appendChild(d)}}else{this.bottombar.innerHTML=d}},_checkIEOverlapping:function(){if(!this.iefix&&(navigator.appVersion.indexOf("MSIE")>0)&&(navigator.userAgent.indexOf("Opera")<0)&&(this.element.getStyle("position")=="absolute")){new Insertion.After(this.element.id,'<iframe id="'+this.element.id+'_iefix" style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" src="javascript:false;" frameborder="0" scrolling="no"></iframe>');this.iefix=$(this.element.id+"_iefix")}if(this.iefix){setTimeout(this._fixIEOverlapping.bind(this),50)}},_fixIEOverlapping:function(){Position.clone(this.element,this.iefix);this.iefix.style.zIndex=this.element.style.zIndex-1;this.iefix.show()},_keyUp:function(b){if(27==b.keyCode&&this.options.closeOnEsc){this.close()}},_getWindowBorderSize:function(d){var e=this._createHiddenDiv(this.options.className+"_n");this.heightN=Element.getDimensions(e).height;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_s");this.heightS=Element.getDimensions(e).height;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_e");this.widthE=Element.getDimensions(e).width;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_w");this.widthW=Element.getDimensions(e).width;e.parentNode.removeChild(e);var e=document.createElement("div");e.className="overlay_"+this.options.className;document.body.appendChild(e);var b=this;setTimeout(function(){b.overlayOpacity=($(e).getStyle("opacity"));e.parentNode.removeChild(e)},10);if(Prototype.Browser.IE){this.heightS=$(this.getId()+"_row3").getDimensions().height;this.heightN=$(this.getId()+"_row1").getDimensions().height}if(Prototype.Browser.WebKit&&Prototype.Browser.WebKitVersion<420){this.setSize(this.width,this.height)}if(this.doMaximize){this.maximize()}if(this.doMinimize){this.minimize()}},_createHiddenDiv:function(d){var b=document.body;var e=document.createElement("div");e.setAttribute("id",this.element.id+"_tmp");e.className=d;e.style.display="none";e.innerHTML="";b.insertBefore(e,b.firstChild);return e},_storeLocation:function(){if(this.storedLocation==null){this.storedLocation={useTop:this.useTop,useLeft:this.useLeft,top:this.element.getStyle("top"),bottom:this.element.getStyle("bottom"),left:this.element.getStyle("left"),right:this.element.getStyle("right"),width:this.width,height:this.height}}},_restoreLocation:function(){if(this.storedLocation!=null){this.useLeft=this.storedLocation.useLeft;this.useTop=this.storedLocation.useTop;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,this.storedLocation.top,this.storedLocation.left,this.storedLocation.width,this.storedLocation.height,{duration:Window.resizeEffectDuration})}else{this.element.setStyle(this.useLeft?{left:this.storedLocation.left}:{right:this.storedLocation.right});this.element.setStyle(this.useTop?{top:this.storedLocation.top}:{bottom:this.storedLocation.bottom});this.setSize(this.storedLocation.width,this.storedLocation.height)}Windows.resetOverflow();this._removeStoreLocation()}},_removeStoreLocation:function(){this.storedLocation=null},_saveCookie:function(){if(this.cookie){var b="";if(this.useLeft){b+="l:"+(this.storedLocation?this.storedLocation.left:this.element.getStyle("left"))}else{b+="r:"+(this.storedLocation?this.storedLocation.right:this.element.getStyle("right"))}if(this.useTop){b+=",t:"+(this.storedLocation?this.storedLocation.top:this.element.getStyle("top"))}else{b+=",b:"+(this.storedLocation?this.storedLocation.bottom:this.element.getStyle("bottom"))}b+=","+(this.storedLocation?this.storedLocation.width:this.width);b+=","+(this.storedLocation?this.storedLocation.height:this.height);b+=","+this.isMinimized();b+=","+this.isMaximized();WindowUtilities.setCookie(b,this.cookie)}},_createWiredElement:function(){if(!this.wiredElement){if(Prototype.Browser.IE){this._getWindowBorderSize()}var d=document.createElement("div");d.className="wired_frame "+this.options.className+"_wired_frame";d.style.position="absolute";this.options.parent.insertBefore(d,this.options.parent.firstChild);this.wiredElement=$(d)}if(this.useLeft){this.wiredElement.setStyle({left:this.element.getStyle("left")})}else{this.wiredElement.setStyle({right:this.element.getStyle("right")})}if(this.useTop){this.wiredElement.setStyle({top:this.element.getStyle("top")})}else{this.wiredElement.setStyle({bottom:this.element.getStyle("bottom")})}var b=this.element.getDimensions();this.wiredElement.setStyle({width:b.width+"px",height:b.height+"px"});this.wiredElement.setStyle({zIndex:Windows.maxZIndex+30});return this.wiredElement},_hideWiredElement:function(){if(!this.wiredElement||!this.currentDrag){return}if(this.currentDrag==this.element){this.currentDrag=null}else{if(this.useLeft){this.element.setStyle({left:this.currentDrag.getStyle("left")})}else{this.element.setStyle({right:this.currentDrag.getStyle("right")})}if(this.useTop){this.element.setStyle({top:this.currentDrag.getStyle("top")})}else{this.element.setStyle({bottom:this.currentDrag.getStyle("bottom")})}this.currentDrag.hide();this.currentDrag=null;if(this.doResize){this.setSize(this.width,this.height)}}},_notify:function(b){if(this.options[b]){this.options[b](this)}else{Windows.notify(b,this)}}};var Windows={windows:[],modalWindows:[],observers:[],focusedWindow:null,maxZIndex:0,overlayShowEffectOptions:{duration:0.5},overlayHideEffectOptions:{duration:0.5},addObserver:function(b){this.removeObserver(b);this.observers.push(b)},removeObserver:function(b){this.observers=this.observers.reject(function(d){return d==b})},notify:function(b,d){this.observers.each(function(e){if(e[b]){e[b](b,d)}})},getWindow:function(b){return this.windows.detect(function(e){return e.getId()==b})},getFocusedWindow:function(){return this.focusedWindow},updateFocusedWindow:function(){this.focusedWindow=this.windows.length>=2?this.windows[this.windows.length-2]:null},register:function(b){this.windows.push(b)},addModalWindow:function(b){if(this.modalWindows.length==0){WindowUtilities.disableScreen(b.options.className,"overlay_modal",b.overlayOpacity,b.getId(),b.options.parent)}else{if(Window.keepMultiModalWindow){$("overlay_modal").style.zIndex=Windows.maxZIndex+1;Windows.maxZIndex+=1;WindowUtilities._hideSelect(this.modalWindows.last().getId())}else{this.modalWindows.last().element.hide()}WindowUtilities._showSelect(b.getId())}this.modalWindows.push(b)},removeModalWindow:function(b){this.modalWindows.pop();if(this.modalWindows.length==0){WindowUtilities.enableScreen()}else{if(Window.keepMultiModalWindow){this.modalWindows.last().toFront();WindowUtilities._showSelect(this.modalWindows.last().getId())}else{this.modalWindows.last().element.show()}}},register:function(b){this.windows.push(b)},unregister:function(b){this.windows=this.windows.reject(function(e){return e==b})},closeAll:function(){this.windows.each(function(b){Windows.close(b.getId())})},closeAllModalWindows:function(){WindowUtilities.enableScreen();this.modalWindows.each(function(b){if(b){b.close()}})},minimize:function(e,b){var d=this.getWindow(e);if(d&&d.visible){d.minimize()}Event.stop(b)},maximize:function(e,b){var d=this.getWindow(e);if(d&&d.visible){d.maximize()}Event.stop(b)},close:function(e,b){var d=this.getWindow(e);if(d){d.close()}if(b){Event.stop(b)}},blur:function(d){var b=this.getWindow(d);if(!b){return}if(b.options.blurClassName){b.changeClassName(b.options.blurClassName)}if(this.focusedWindow==b){this.focusedWindow=null}b._notify("onBlur")},focus:function(d){var b=this.getWindow(d);if(!b){return}if(this.focusedWindow){this.blur(this.focusedWindow.getId())}if(b.options.focusClassName){b.changeClassName(b.options.focusClassName)}this.focusedWindow=b;b._notify("onFocus")},unsetOverflow:function(b){this.windows.each(function(e){e.oldOverflow=e.getContent().getStyle("overflow")||"auto";e.getContent().setStyle({overflow:"hidden"})});if(b&&b.oldOverflow){b.getContent().setStyle({overflow:b.oldOverflow})}},resetOverflow:function(){this.windows.each(function(b){if(b.oldOverflow){b.getContent().setStyle({overflow:b.oldOverflow})}})},updateZindex:function(b,d){if(b>this.maxZIndex){this.maxZIndex=b;if(this.focusedWindow){this.blur(this.focusedWindow.getId())}}this.focusedWindow=d;if(this.focusedWindow){this.focus(this.focusedWindow.getId())}}};var Dialog={dialogId:null,onCompleteFunc:null,callFunc:null,parameters:null,confirm:function(f,e){if(f&&typeof f!="string"){Dialog._runAjaxRequest(f,e,Dialog.confirm);return}f=f||"";e=e||{};var h=e.okLabel?e.okLabel:"Ok";var b=e.cancelLabel?e.cancelLabel:"Cancel";e=Object.extend(e,e.windowParameters||{});e.windowParameters=e.windowParameters||{};e.className=e.className||"alert";var d="class ='"+(e.buttonClass?e.buttonClass+" ":"")+" ok_button'";var g="class ='"+(e.buttonClass?e.buttonClass+" ":"")+" cancel_button'";var f=" <div class='"+e.className+"_message'>"+f+"</div> <div class='"+e.className+"_buttons'> <button type='button' title='"+h+"' onclick='Dialog.okCallback()' "+d+"><span><span><span>"+h+"</span></span></span></button> <button type='button' title='"+b+"' onclick='Dialog.cancelCallback()' "+g+"><span><span><span>"+b+"</span></span></span></button> </div> ";return this._openDialog(f,e)},alert:function(e,d){if(e&&typeof e!="string"){Dialog._runAjaxRequest(e,d,Dialog.alert);return}e=e||"";d=d||{};var f=d.okLabel?d.okLabel:"Ok";d=Object.extend(d,d.windowParameters||{});d.windowParameters=d.windowParameters||{};d.className=d.className||"alert";var b="class ='"+(d.buttonClass?d.buttonClass+" ":"")+" ok_button'";var e=" <div class='"+d.className+"_message'>"+e+"</div> <div class='"+d.className+"_buttons'> <button type='button' title='"+f+"' onclick='Dialog.okCallback()' "+b+"><span><span><span>"+f+"</span></span></span></button> </div>";return this._openDialog(e,d)},info:function(d,b){if(d&&typeof d!="string"){Dialog._runAjaxRequest(d,b,Dialog.info);return}d=d||"";b=b||{};b=Object.extend(b,b.windowParameters||{});b.windowParameters=b.windowParameters||{};b.className=b.className||"alert";var d="<div id='modal_dialog_message' class='"+b.className+"_message'>"+d+"</div>";if(b.showProgress){d+="<div id='modal_dialog_progress' class='"+b.className+"_progress'> </div>"}b.ok=null;b.cancel=null;return this._openDialog(d,b)},setInfoMessage:function(b){$("modal_dialog_message").update(b)},closeInfo:function(){Windows.close(this.dialogId)},_openDialog:function(g,f){var e=f.className;if(!f.height&&!f.width){f.width=WindowUtilities.getPageSize(f.options.parent||document.body).pageWidth/2}if(f.id){this.dialogId=f.id}else{var d=new Date();this.dialogId="modal_dialog_"+d.getTime();f.id=this.dialogId}if(!f.height||!f.width){var b=WindowUtilities._computeSize(g,this.dialogId,f.width,f.height,5,e);if(f.height){f.width=b+5}else{f.height=b+5}}f.effectOptions=f.effectOptions;f.resizable=f.resizable||false;f.minimizable=f.minimizable||false;f.maximizable=f.maximizable||false;f.draggable=f.draggable||false;f.closable=f.closable||false;var h=new Window(f);h.getContent().innerHTML=g;h.showCenter(true,f.top,f.left);h.setDestroyOnClose();h.cancelCallback=f.onCancel||f.cancel;h.okCallback=f.onOk||f.ok;return h},_getAjaxContent:function(b){Dialog.callFunc(b.responseText,Dialog.parameters)},_runAjaxRequest:function(e,d,b){if(e.options==null){e.options={}}Dialog.onCompleteFunc=e.options.onComplete;Dialog.parameters=d;Dialog.callFunc=b;e.options.onComplete=Dialog._getAjaxContent;new Ajax.Request(e.url,e.options)},okCallback:function(){var b=Windows.focusedWindow;if(!b.okCallback||b.okCallback(b)){$$("#"+b.getId()+" input").each(function(d){d.onclick=null});b.close()}},cancelCallback:function(){var b=Windows.focusedWindow;$$("#"+b.getId()+" input").each(function(d){d.onclick=null});b.close();if(b.cancelCallback){b.cancelCallback(b)}}};if(Prototype.Browser.WebKit){var array=navigator.userAgent.match(new RegExp(/AppleWebKit\/([\d\.\+]*)/));Prototype.Browser.WebKitVersion=parseFloat(array[1])}var WindowUtilities={getWindowScroll:function(parent){var T,L,W,H;parent=parent||document.body;if(parent!=document.body){T=parent.scrollTop;L=parent.scrollLeft;W=parent.scrollWidth;H=parent.scrollHeight}else{var w=window;with(w.document){if(w.document.documentElement&&documentElement.scrollTop){T=documentElement.scrollTop;L=documentElement.scrollLeft}else{if(w.document.body){T=body.scrollTop;L=body.scrollLeft}}if(w.innerWidth){W=w.innerWidth;H=w.innerHeight}else{if(w.document.documentElement&&documentElement.clientWidth){W=documentElement.clientWidth;H=documentElement.clientHeight}else{W=body.offsetWidth;H=body.offsetHeight}}}}return{top:T,left:L,width:W,height:H}},getPageSize:function(f){f=f||document.body;var e,l;var g,d;if(f!=document.body){e=f.getWidth();l=f.getHeight();d=f.scrollWidth;g=f.scrollHeight}else{var h,b;if(window.innerHeight&&window.scrollMaxY){h=document.body.scrollWidth;b=window.innerHeight+window.scrollMaxY}else{if(document.body.scrollHeight>document.body.offsetHeight){h=document.body.scrollWidth;b=document.body.scrollHeight}else{h=document.body.offsetWidth;b=document.body.offsetHeight}}if(self.innerHeight){e=document.documentElement.clientWidth;l=self.innerHeight}else{if(document.documentElement&&document.documentElement.clientHeight){e=document.documentElement.clientWidth;l=document.documentElement.clientHeight}else{if(document.body){e=document.body.clientWidth;l=document.body.clientHeight}}}if(b<l){g=l}else{g=b}if(h<e){d=e}else{d=h}}return{pageWidth:d,pageHeight:g,windowWidth:e,windowHeight:l}},disableScreen:function(e,b,f,g,d){WindowUtilities.initLightbox(b,e,function(){this._disableScreen(e,b,f,g)}.bind(this),d||document.body)},_disableScreen:function(e,d,g,h){var f=$(d);var b=WindowUtilities.getPageSize(f.parentNode);if(h&&Prototype.Browser.IE){WindowUtilities._hideSelect();WindowUtilities._showSelect(h)}f.style.height=(b.pageHeight+"px");f.style.display="none";if(d=="overlay_modal"&&Window.hasEffectLib&&Windows.overlayShowEffectOptions){f.overlayOpacity=g;new Effect.Appear(f,Object.extend({from:0,to:g},Windows.overlayShowEffectOptions))}else{f.style.display="block"}},enableScreen:function(d){d=d||"overlay_modal";var b=$(d);if(b){if(d=="overlay_modal"&&Window.hasEffectLib&&Windows.overlayHideEffectOptions){new Effect.Fade(b,Object.extend({from:b.overlayOpacity,to:0},Windows.overlayHideEffectOptions))}else{b.style.display="none";b.parentNode.removeChild(b)}if(d!="__invisible__"){WindowUtilities._showSelect()}}},_hideSelect:function(b){if(Prototype.Browser.IE){b=b==null?"":"#"+b+" ";$$(b+"select").each(function(d){if(!WindowUtilities.isDefined(d.oldVisibility)){d.oldVisibility=d.style.visibility?d.style.visibility:"visible";d.style.visibility="hidden"}})}},_showSelect:function(b){if(Prototype.Browser.IE){b=b==null?"":"#"+b+" ";$$(b+"select").each(function(d){if(WindowUtilities.isDefined(d.oldVisibility)){try{d.style.visibility=d.oldVisibility}catch(f){d.style.visibility="visible"}d.oldVisibility=null}else{if(d.style.visibility){d.style.visibility="visible"}}})}},isDefined:function(b){return typeof(b)!="undefined"&&b!=null},initLightbox:function(g,e,b,d){if($(g)){Element.setStyle(g,{zIndex:Windows.maxZIndex+1});Windows.maxZIndex++;b()}else{var f=document.createElement("div");f.setAttribute("id",g);f.className="overlay_"+e;f.style.display="none";f.style.position="absolute";f.style.top="0";f.style.left="0";f.style.zIndex=Windows.maxZIndex+1;Windows.maxZIndex++;f.style.width="100%";d.insertBefore(f,d.firstChild);if(Prototype.Browser.WebKit&&g=="overlay_modal"){setTimeout(function(){b()},10)}else{b()}}},setCookie:function(d,b){document.cookie=b[0]+"="+escape(d)+((b[1])?"; expires="+b[1].toUTCString():"")+((b[2])?"; path="+b[2]:"")+((b[3])?"; domain="+b[3]:"")+((b[4])?"; secure":"")},getCookie:function(e){var d=document.cookie;var g=e+"=";var f=d.indexOf("; "+g);if(f==-1){f=d.indexOf(g);if(f!=0){return null}}else{f+=2}var b=document.cookie.indexOf(";",f);if(b==-1){b=d.length}return unescape(d.substring(f+g.length,b))},_computeSize:function(g,b,d,l,f,h){var o=document.body;var e=document.createElement("div");e.setAttribute("id",b);e.className=h+"_content";if(l){e.style.height=l+"px"}else{e.style.width=d+"px"}e.style.position="absolute";e.style.top="0";e.style.left="0";e.style.display="none";e.innerHTML=g;o.insertBefore(e,o.firstChild);var n;if(l){n=$(e).getDimensions().width+f}else{n=$(e).getDimensions().height+f}o.removeChild(e);return n}};var Builder={NODEMAP:{AREA:"map",CAPTION:"table",COL:"table",COLGROUP:"table",LEGEND:"fieldset",OPTGROUP:"select",OPTION:"select",PARAM:"object",TBODY:"table",TD:"table",TFOOT:"table",TH:"table",THEAD:"table",TR:"table"},node:function(b){b=b.toUpperCase();var l=this.NODEMAP[b]||"div";var d=document.createElement(l);try{d.innerHTML="<"+b+"></"+b+">"}catch(h){}var g=d.firstChild||null;if(g&&(g.tagName.toUpperCase()!=b)){g=g.getElementsByTagName(b)[0]}if(!g){g=document.createElement(b)}if(!g){return}if(arguments[1]){if(this._isStringOrNumber(arguments[1])||(arguments[1] instanceof Array)||arguments[1].tagName){this._children(g,arguments[1])}else{var f=this._attributes(arguments[1]);if(f.length){try{d.innerHTML="<"+b+" "+f+"></"+b+">"}catch(h){}g=d.firstChild||null;if(!g){g=document.createElement(b);for(attr in arguments[1]){g[attr=="class"?"className":attr]=arguments[1][attr]}}if(g.tagName.toUpperCase()!=b){g=d.getElementsByTagName(b)[0]}}}}if(arguments[2]){this._children(g,arguments[2])}return $(g)},_text:function(b){return document.createTextNode(b)},ATTR_MAP:{className:"class",htmlFor:"for"},_attributes:function(b){var d=[];for(attribute in b){d.push((attribute in this.ATTR_MAP?this.ATTR_MAP[attribute]:attribute)+'="'+b[attribute].toString().escapeHTML().gsub(/"/,""")+'"')}return d.join(" ")},_children:function(d,b){if(b.tagName){d.appendChild(b);return}if(typeof b=="object"){b.flatten().each(function(f){if(typeof f=="object"){d.appendChild(f)}else{if(Builder._isStringOrNumber(f)){d.appendChild(Builder._text(f))}}})}else{if(Builder._isStringOrNumber(b)){d.appendChild(Builder._text(b))}}},_isStringOrNumber:function(b){return(typeof b=="string"||typeof b=="number")},build:function(d){var b=this.node("div");$(b).update(d.strip());return b.down()},dump:function(d){if(typeof d!="object"&&typeof d!="function"){d=window}var b=("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);b.each(function(e){d[e]=function(){return Builder.node.apply(Builder,[e].concat($A(arguments)))}})}};String.prototype.parseColor=function(){var b="#";if(this.slice(0,4)=="rgb("){var e=this.slice(4,this.length-1).split(",");var d=0;do{b+=parseInt(e[d]).toColorPart()}while(++d<3)}else{if(this.slice(0,1)=="#"){if(this.length==4){for(var d=1;d<4;d++){b+=(this.charAt(d)+this.charAt(d)).toLowerCase()}}if(this.length==7){b=this.toLowerCase()}}}return(b.length==7?b:(arguments[0]||this))};Element.collectTextNodes=function(b){return $A($(b).childNodes).collect(function(d){return(d.nodeType==3?d.nodeValue:(d.hasChildNodes()?Element.collectTextNodes(d):""))}).flatten().join("")};Element.collectTextNodesIgnoreClass=function(b,d){return $A($(b).childNodes).collect(function(e){return(e.nodeType==3?e.nodeValue:((e.hasChildNodes()&&!Element.hasClassName(e,d))?Element.collectTextNodesIgnoreClass(e,d):""))}).flatten().join("")};Element.setContentZoom=function(b,d){b=$(b);b.setStyle({fontSize:(d/100)+"em"});if(Prototype.Browser.WebKit){window.scrollBy(0,0)}return b};Element.getInlineOpacity=function(b){return $(b).style.opacity||""};Element.forceRerendering=function(b){try{b=$(b);var f=document.createTextNode(" ");b.appendChild(f);b.removeChild(f)}catch(d){}};var Effect={_elementDoesNotExistError:{name:"ElementDoesNotExistError",message:"The specified DOM element does not exist, but is required for this effect to operate"},Transitions:{linear:Prototype.K,sinoidal:function(b){return(-Math.cos(b*Math.PI)/2)+0.5},reverse:function(b){return 1-b},flicker:function(b){var b=((-Math.cos(b*Math.PI)/4)+0.75)+Math.random()/4;return b>1?1:b},wobble:function(b){return(-Math.cos(b*Math.PI*(9*b))/2)+0.5},pulse:function(d,b){return(-Math.cos((d*((b||5)-0.5)*2)*Math.PI)/2)+0.5},spring:function(b){return 1-(Math.cos(b*4.5*Math.PI)*Math.exp(-b*6))},none:function(b){return 0},full:function(b){return 1}},DefaultOptions:{duration:1,fps:100,sync:false,from:0,to:1,delay:0,queue:"parallel"},tagifyText:function(b){var d="position:relative";if(Prototype.Browser.IE){d+=";zoom:1"}b=$(b);$A(b.childNodes).each(function(e){if(e.nodeType==3){e.nodeValue.toArray().each(function(f){b.insertBefore(new Element("span",{style:d}).update(f==" "?String.fromCharCode(160):f),e)});Element.remove(e)}})},multiple:function(d,e){var g;if(((typeof d=="object")||Object.isFunction(d))&&(d.length)){g=d}else{g=$(d).childNodes}var b=Object.extend({speed:0.1,delay:0},arguments[2]||{});var f=b.delay;$A(g).each(function(l,h){new e(l,Object.extend(b,{delay:h*b.speed+f}))})},PAIRS:{slide:["SlideDown","SlideUp"],blind:["BlindDown","BlindUp"],appear:["Appear","Fade"]},toggle:function(d,e){d=$(d);e=(e||"appear").toLowerCase();var b=Object.extend({queue:{position:"end",scope:(d.id||"global"),limit:1}},arguments[2]||{});Effect[d.visible()?Effect.PAIRS[e][1]:Effect.PAIRS[e][0]](d,b)}};Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;Effect.ScopedQueue=Class.create(Enumerable,{initialize:function(){this.effects=[];this.interval=null},_each:function(b){this.effects._each(b)},add:function(d){var e=new Date().getTime();var b=Object.isString(d.options.queue)?d.options.queue:d.options.queue.position;switch(b){case"front":this.effects.findAll(function(f){return f.state=="idle"}).each(function(f){f.startOn+=d.finishOn;f.finishOn+=d.finishOn});break;case"with-last":e=this.effects.pluck("startOn").max()||e;break;case"end":e=this.effects.pluck("finishOn").max()||e;break}d.startOn+=e;d.finishOn+=e;if(!d.options.queue.limit||(this.effects.length<d.options.queue.limit)){this.effects.push(d)}if(!this.interval){this.interval=setInterval(this.loop.bind(this),15)}},remove:function(b){this.effects=this.effects.reject(function(d){return d==b});if(this.effects.length==0){clearInterval(this.interval);this.interval=null}},loop:function(){var e=new Date().getTime();for(var d=0,b=this.effects.length;d<b;d++){this.effects[d]&&this.effects[d].loop(e)}}});Effect.Queues={instances:$H(),get:function(b){if(!Object.isString(b)){return b}return this.instances.get(b)||this.instances.set(b,new Effect.ScopedQueue())}};Effect.Queue=Effect.Queues.get("global");Effect.Base=Class.create({position:null,start:function(b){function d(f,e){return((f[e+"Internal"]?"this.options."+e+"Internal(this);":"")+(f[e]?"this.options."+e+"(this);":""))}if(b&&b.transition===false){b.transition=Effect.Transitions.linear}this.options=Object.extend(Object.extend({},Effect.DefaultOptions),b||{});this.currentFrame=0;this.state="idle";this.startOn=this.options.delay*1000;this.finishOn=this.startOn+(this.options.duration*1000);this.fromToDelta=this.options.to-this.options.from;this.totalTime=this.finishOn-this.startOn;this.totalFrames=this.options.fps*this.options.duration;this.render=(function(){function e(g,f){if(g.options[f+"Internal"]){g.options[f+"Internal"](g)}if(g.options[f]){g.options[f](g)}}return function(f){if(this.state==="idle"){this.state="running";e(this,"beforeSetup");if(this.setup){this.setup()}e(this,"afterSetup")}if(this.state==="running"){f=(this.options.transition(f)*this.fromToDelta)+this.options.from;this.position=f;e(this,"beforeUpdate");if(this.update){this.update(f)}e(this,"afterUpdate")}}})();this.event("beforeStart");if(!this.options.sync){Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).add(this)}},loop:function(e){if(e>=this.startOn){if(e>=this.finishOn){this.render(1);this.cancel();this.event("beforeFinish");if(this.finish){this.finish()}this.event("afterFinish");return}var d=(e-this.startOn)/this.totalTime,b=(d*this.totalFrames).round();if(b>this.currentFrame){this.render(d);this.currentFrame=b}}},cancel:function(){if(!this.options.sync){Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).remove(this)}this.state="finished"},event:function(b){if(this.options[b+"Internal"]){this.options[b+"Internal"](this)}if(this.options[b]){this.options[b](this)}},inspect:function(){var b=$H();for(property in this){if(!Object.isFunction(this[property])){b.set(property,this[property])}}return"#<Effect:"+b.inspect()+",options:"+$H(this.options).inspect()+">"}});Effect.Parallel=Class.create(Effect.Base,{initialize:function(b){this.effects=b||[];this.start(arguments[1])},update:function(b){this.effects.invoke("render",b)},finish:function(b){this.effects.each(function(d){d.render(1);d.cancel();d.event("beforeFinish");if(d.finish){d.finish(b)}d.event("afterFinish")})}});Effect.Tween=Class.create(Effect.Base,{initialize:function(e,h,g){e=Object.isString(e)?$(e):e;var d=$A(arguments),f=d.last(),b=d.length==5?d[3]:null;this.method=Object.isFunction(f)?f.bind(e):Object.isFunction(e[f])?e[f].bind(e):function(l){e[f]=l};this.start(Object.extend({from:h,to:g},b||{}))},update:function(b){this.method(b)}});Effect.Event=Class.create(Effect.Base,{initialize:function(){this.start(Object.extend({duration:0},arguments[0]||{}))},update:Prototype.emptyFunction});Effect.Opacity=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}var b=Object.extend({from:this.element.getOpacity()||0,to:1},arguments[1]||{});this.start(b)},update:function(b){this.element.setOpacity(b)}});Effect.Move=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({x:0,y:0,mode:"relative"},arguments[1]||{});this.start(b)},setup:function(){this.element.makePositioned();this.originalLeft=parseFloat(this.element.getStyle("left")||"0");this.originalTop=parseFloat(this.element.getStyle("top")||"0");if(this.options.mode=="absolute"){this.options.x=this.options.x-this.originalLeft;this.options.y=this.options.y-this.originalTop}},update:function(b){this.element.setStyle({left:(this.options.x*b+this.originalLeft).round()+"px",top:(this.options.y*b+this.originalTop).round()+"px"})}});Effect.MoveBy=function(d,b,e){return new Effect.Move(d,Object.extend({x:e,y:b},arguments[3]||{}))};Effect.Scale=Class.create(Effect.Base,{initialize:function(d,e){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:"box",scaleFrom:100,scaleTo:e},arguments[2]||{});this.start(b)},setup:function(){this.restoreAfterFinish=this.options.restoreAfterFinish||false;this.elementPositioning=this.element.getStyle("position");this.originalStyle={};["top","left","width","height","fontSize"].each(function(d){this.originalStyle[d]=this.element.style[d]}.bind(this));this.originalTop=this.element.offsetTop;this.originalLeft=this.element.offsetLeft;var b=this.element.getStyle("font-size")||"100%";["em","px","%","pt"].each(function(d){if(b.indexOf(d)>0){this.fontSize=parseFloat(b);this.fontSizeType=d}}.bind(this));this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;this.dims=null;if(this.options.scaleMode=="box"){this.dims=[this.element.offsetHeight,this.element.offsetWidth]}if(/^content/.test(this.options.scaleMode)){this.dims=[this.element.scrollHeight,this.element.scrollWidth]}if(!this.dims){this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth]}},update:function(b){var d=(this.options.scaleFrom/100)+(this.factor*b);if(this.options.scaleContent&&this.fontSize){this.element.setStyle({fontSize:this.fontSize*d+this.fontSizeType})}this.setDimensions(this.dims[0]*d,this.dims[1]*d)},finish:function(b){if(this.restoreAfterFinish){this.element.setStyle(this.originalStyle)}},setDimensions:function(b,g){var h={};if(this.options.scaleX){h.width=g.round()+"px"}if(this.options.scaleY){h.height=b.round()+"px"}if(this.options.scaleFromCenter){var f=(b-this.dims[0])/2;var e=(g-this.dims[1])/2;if(this.elementPositioning=="absolute"){if(this.options.scaleY){h.top=this.originalTop-f+"px"}if(this.options.scaleX){h.left=this.originalLeft-e+"px"}}else{if(this.options.scaleY){h.top=-f+"px"}if(this.options.scaleX){h.left=-e+"px"}}}this.element.setStyle(h)}});Effect.Highlight=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({startcolor:"#ffff99"},arguments[1]||{});this.start(b)},setup:function(){if(this.element.getStyle("display")=="none"){this.cancel();return}this.oldStyle={};if(!this.options.keepBackgroundImage){this.oldStyle.backgroundImage=this.element.getStyle("background-image");this.element.setStyle({backgroundImage:"none"})}if(!this.options.endcolor){this.options.endcolor=this.element.getStyle("background-color").parseColor("#ffffff")}if(!this.options.restorecolor){this.options.restorecolor=this.element.getStyle("background-color")}this._base=$R(0,2).map(function(b){return parseInt(this.options.startcolor.slice(b*2+1,b*2+3),16)}.bind(this));this._delta=$R(0,2).map(function(b){return parseInt(this.options.endcolor.slice(b*2+1,b*2+3),16)-this._base[b]}.bind(this))},update:function(b){this.element.setStyle({backgroundColor:$R(0,2).inject("#",function(d,e,f){return d+((this._base[f]+(this._delta[f]*b)).round().toColorPart())}.bind(this))})},finish:function(){this.element.setStyle(Object.extend(this.oldStyle,{backgroundColor:this.options.restorecolor}))}});Effect.ScrollTo=function(e){var d=arguments[1]||{},b=document.viewport.getScrollOffsets(),f=$(e).cumulativeOffset();if(d.offset){f[1]+=d.offset}return new Effect.Tween(null,b.top,f[1],d,function(g){scrollTo(b.left,g.round())})};Effect.Fade=function(e){e=$(e);var b=e.getInlineOpacity();var d=Object.extend({from:e.getOpacity()||1,to:0,afterFinishInternal:function(f){if(f.options.to!=0){return}f.element.hide().setStyle({opacity:b})}},arguments[1]||{});return new Effect.Opacity(e,d)};Effect.Appear=function(d){d=$(d);var b=Object.extend({from:(d.getStyle("display")=="none"?0:d.getOpacity()||0),to:1,afterFinishInternal:function(e){e.element.forceRerendering()},beforeSetup:function(e){e.element.setOpacity(e.options.from).show()}},arguments[1]||{});return new Effect.Opacity(d,b)};Effect.Puff=function(d){d=$(d);var b={opacity:d.getInlineOpacity(),position:d.getStyle("position"),top:d.style.top,left:d.style.left,width:d.style.width,height:d.style.height};return new Effect.Parallel([new Effect.Scale(d,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new Effect.Opacity(d,{sync:true,to:0})],Object.extend({duration:1,beforeSetupInternal:function(e){Position.absolutize(e.effects[0].element)},afterFinishInternal:function(e){e.effects[0].element.hide().setStyle(b)}},arguments[1]||{}))};Effect.BlindUp=function(b){b=$(b);b.makeClipping();return new Effect.Scale(b,0,Object.extend({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(d){d.element.hide().undoClipping()}},arguments[1]||{}))};Effect.BlindDown=function(d){d=$(d);var b=d.getDimensions();return new Effect.Scale(d,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:b.height,originalWidth:b.width},restoreAfterFinish:true,afterSetup:function(e){e.element.makeClipping().setStyle({height:"0px"}).show()},afterFinishInternal:function(e){e.element.undoClipping()}},arguments[1]||{}))};Effect.SwitchOff=function(d){d=$(d);var b=d.getInlineOpacity();return new Effect.Appear(d,Object.extend({duration:0.4,from:0,transition:Effect.Transitions.flicker,afterFinishInternal:function(e){new Effect.Scale(e.element,1,{duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetup:function(f){f.element.makePositioned().makeClipping()},afterFinishInternal:function(f){f.element.hide().undoClipping().undoPositioned().setStyle({opacity:b})}})}},arguments[1]||{}))};Effect.DropOut=function(d){d=$(d);var b={top:d.getStyle("top"),left:d.getStyle("left"),opacity:d.getInlineOpacity()};return new Effect.Parallel([new Effect.Move(d,{x:0,y:100,sync:true}),new Effect.Opacity(d,{sync:true,to:0})],Object.extend({duration:0.5,beforeSetup:function(e){e.effects[0].element.makePositioned()},afterFinishInternal:function(e){e.effects[0].element.hide().undoPositioned().setStyle(b)}},arguments[1]||{}))};Effect.Shake=function(f){f=$(f);var d=Object.extend({distance:20,duration:0.5},arguments[1]||{});var g=parseFloat(d.distance);var e=parseFloat(d.duration)/10;var b={top:f.getStyle("top"),left:f.getStyle("left")};return new Effect.Move(f,{x:g,y:0,duration:e,afterFinishInternal:function(h){new Effect.Move(h.element,{x:-g*2,y:0,duration:e*2,afterFinishInternal:function(l){new Effect.Move(l.element,{x:g*2,y:0,duration:e*2,afterFinishInternal:function(n){new Effect.Move(n.element,{x:-g*2,y:0,duration:e*2,afterFinishInternal:function(o){new Effect.Move(o.element,{x:g*2,y:0,duration:e*2,afterFinishInternal:function(p){new Effect.Move(p.element,{x:-g,y:0,duration:e,afterFinishInternal:function(q){q.element.undoPositioned().setStyle(b)}})}})}})}})}})}})};Effect.SlideDown=function(e){e=$(e).cleanWhitespace();var b=e.down().getStyle("bottom");var d=e.getDimensions();return new Effect.Scale(e,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:window.opera?0:1,scaleMode:{originalHeight:d.height,originalWidth:d.width},restoreAfterFinish:true,afterSetup:function(f){f.element.makePositioned();f.element.down().makePositioned();if(window.opera){f.element.setStyle({top:""})}f.element.makeClipping().setStyle({height:"0px"}).show()},afterUpdateInternal:function(f){f.element.down().setStyle({bottom:(f.dims[0]-f.element.clientHeight)+"px"})},afterFinishInternal:function(f){f.element.undoClipping().undoPositioned();f.element.down().undoPositioned().setStyle({bottom:b})}},arguments[1]||{}))};Effect.SlideUp=function(e){e=$(e).cleanWhitespace();var b=e.down().getStyle("bottom");var d=e.getDimensions();return new Effect.Scale(e,window.opera?0:1,Object.extend({scaleContent:false,scaleX:false,scaleMode:"box",scaleFrom:100,scaleMode:{originalHeight:d.height,originalWidth:d.width},restoreAfterFinish:true,afterSetup:function(f){f.element.makePositioned();f.element.down().makePositioned();if(window.opera){f.element.setStyle({top:""})}f.element.makeClipping().show()},afterUpdateInternal:function(f){f.element.down().setStyle({bottom:(f.dims[0]-f.element.clientHeight)+"px"})},afterFinishInternal:function(f){f.element.hide().undoClipping().undoPositioned();f.element.down().undoPositioned().setStyle({bottom:b})}},arguments[1]||{}))};Effect.Squish=function(b){return new Effect.Scale(b,window.opera?1:0,{restoreAfterFinish:true,beforeSetup:function(d){d.element.makeClipping()},afterFinishInternal:function(d){d.element.hide().undoClipping()}})};Effect.Grow=function(e){e=$(e);var d=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.full},arguments[1]||{});var b={top:e.style.top,left:e.style.left,height:e.style.height,width:e.style.width,opacity:e.getInlineOpacity()};var l=e.getDimensions();var n,h;var g,f;switch(d.direction){case"top-left":n=h=g=f=0;break;case"top-right":n=l.width;h=f=0;g=-l.width;break;case"bottom-left":n=g=0;h=l.height;f=-l.height;break;case"bottom-right":n=l.width;h=l.height;g=-l.width;f=-l.height;break;case"center":n=l.width/2;h=l.height/2;g=-l.width/2;f=-l.height/2;break}return new Effect.Move(e,{x:n,y:h,duration:0.01,beforeSetup:function(o){o.element.hide().makeClipping().makePositioned()},afterFinishInternal:function(o){new Effect.Parallel([new Effect.Opacity(o.element,{sync:true,to:1,from:0,transition:d.opacityTransition}),new Effect.Move(o.element,{x:g,y:f,sync:true,transition:d.moveTransition}),new Effect.Scale(o.element,100,{scaleMode:{originalHeight:l.height,originalWidth:l.width},sync:true,scaleFrom:window.opera?1:0,transition:d.scaleTransition,restoreAfterFinish:true})],Object.extend({beforeSetup:function(p){p.effects[0].element.setStyle({height:"0px"}).show()},afterFinishInternal:function(p){p.effects[0].element.undoClipping().undoPositioned().setStyle(b)}},d))}})};Effect.Shrink=function(e){e=$(e);var d=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.none},arguments[1]||{});var b={top:e.style.top,left:e.style.left,height:e.style.height,width:e.style.width,opacity:e.getInlineOpacity()};var h=e.getDimensions();var g,f;switch(d.direction){case"top-left":g=f=0;break;case"top-right":g=h.width;f=0;break;case"bottom-left":g=0;f=h.height;break;case"bottom-right":g=h.width;f=h.height;break;case"center":g=h.width/2;f=h.height/2;break}return new Effect.Parallel([new Effect.Opacity(e,{sync:true,to:0,from:1,transition:d.opacityTransition}),new Effect.Scale(e,window.opera?1:0,{sync:true,transition:d.scaleTransition,restoreAfterFinish:true}),new Effect.Move(e,{x:g,y:f,sync:true,transition:d.moveTransition})],Object.extend({beforeStartInternal:function(l){l.effects[0].element.makePositioned().makeClipping()},afterFinishInternal:function(l){l.effects[0].element.hide().undoClipping().undoPositioned().setStyle(b)}},d))};Effect.Pulsate=function(e){e=$(e);var d=arguments[1]||{},b=e.getInlineOpacity(),g=d.transition||Effect.Transitions.linear,f=function(h){return 1-g((-Math.cos((h*(d.pulses||5)*2)*Math.PI)/2)+0.5)};return new Effect.Opacity(e,Object.extend(Object.extend({duration:2,from:0,afterFinishInternal:function(h){h.element.setStyle({opacity:b})}},d),{transition:f}))};Effect.Fold=function(d){d=$(d);var b={top:d.style.top,left:d.style.left,width:d.style.width,height:d.style.height};d.makeClipping();return new Effect.Scale(d,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(e){new Effect.Scale(d,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(f){f.element.hide().undoClipping().setStyle(b)}})}},arguments[1]||{}))};Effect.Morph=Class.create(Effect.Base,{initialize:function(e){this.element=$(e);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({style:{}},arguments[1]||{});if(!Object.isString(b.style)){this.style=$H(b.style)}else{if(b.style.include(":")){this.style=b.style.parseStyle()}else{this.element.addClassName(b.style);this.style=$H(this.element.getStyles());this.element.removeClassName(b.style);var d=this.element.getStyles();this.style=this.style.reject(function(f){return f.value==d[f.key]});b.afterFinishInternal=function(f){f.element.addClassName(f.options.style);f.transforms.each(function(g){f.element.style[g.style]=""})}}}this.start(b)},setup:function(){function b(d){if(!d||["rgba(0, 0, 0, 0)","transparent"].include(d)){d="#ffffff"}d=d.parseColor();return $R(0,2).map(function(e){return parseInt(d.slice(e*2+1,e*2+3),16)})}this.transforms=this.style.map(function(l){var h=l[0],g=l[1],f=null;if(g.parseColor("#zzzzzz")!="#zzzzzz"){g=g.parseColor();f="color"}else{if(h=="opacity"){g=parseFloat(g);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}}else{if(Element.CSS_LENGTH.test(g)){var e=g.match(/^([\+\-]?[0-9\.]+)(.*)$/);g=parseFloat(e[1]);f=(e.length==3)?e[2]:null}}}var d=this.element.getStyle(h);return{style:h.camelize(),originalValue:f=="color"?b(d):parseFloat(d||0),targetValue:f=="color"?b(g):g,unit:f}}.bind(this)).reject(function(d){return((d.originalValue==d.targetValue)||(d.unit!="color"&&(isNaN(d.originalValue)||isNaN(d.targetValue))))})},update:function(b){var f={},d,e=this.transforms.length;while(e--){f[(d=this.transforms[e]).style]=d.unit=="color"?"#"+(Math.round(d.originalValue[0]+(d.targetValue[0]-d.originalValue[0])*b)).toColorPart()+(Math.round(d.originalValue[1]+(d.targetValue[1]-d.originalValue[1])*b)).toColorPart()+(Math.round(d.originalValue[2]+(d.targetValue[2]-d.originalValue[2])*b)).toColorPart():(d.originalValue+(d.targetValue-d.originalValue)*b).toFixed(3)+(d.unit===null?"":d.unit)}this.element.setStyle(f,true)}});Effect.Transform=Class.create({initialize:function(b){this.tracks=[];this.options=arguments[1]||{};this.addTracks(b)},addTracks:function(b){b.each(function(d){d=$H(d);var e=d.values().first();this.tracks.push($H({ids:d.keys().first(),effect:Effect.Morph,options:{style:e}}))}.bind(this));return this},play:function(){return new Effect.Parallel(this.tracks.map(function(b){var f=b.get("ids"),e=b.get("effect"),d=b.get("options");var g=[$(f)||$$(f)].flatten();return g.map(function(h){return new e(h,Object.extend({sync:true},d))})}).flatten(),this.options)}});Element.CSS_PROPERTIES=$w("backgroundColor backgroundPosition borderBottomColor borderBottomStyle borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth borderRightColor borderRightStyle borderRightWidth borderSpacing borderTopColor borderTopStyle borderTopWidth bottom clip color fontSize fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop markerOffset maxHeight maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft paddingRight paddingTop right textIndent top width wordSpacing zIndex");Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.__parseStyleElement=document.createElement("div");String.prototype.parseStyle=function(){var d,b=$H();if(Prototype.Browser.WebKit){d=new Element("div",{style:this}).style}else{String.__parseStyleElement.innerHTML='<div style="'+this+'"></div>';d=String.__parseStyleElement.childNodes[0].style}Element.CSS_PROPERTIES.each(function(e){if(d[e]){b.set(e,d[e])}});if(Prototype.Browser.IE&&this.include("opacity")){b.set("opacity",this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1])}return b};if(document.defaultView&&document.defaultView.getComputedStyle){Element.getStyles=function(d){var b=document.defaultView.getComputedStyle($(d),null);return Element.CSS_PROPERTIES.inject({},function(e,f){e[f]=b[f];return e})}}else{Element.getStyles=function(d){d=$(d);var b=d.currentStyle,e;e=Element.CSS_PROPERTIES.inject({},function(f,g){f[g]=b[g];return f});if(!e.opacity){e.opacity=d.getOpacity()}return e}}Effect.Methods={morph:function(b,d){b=$(b);new Effect.Morph(b,Object.extend({style:d},arguments[2]||{}));return b},visualEffect:function(e,g,d){e=$(e);var f=g.dasherize().camelize(),b=f.charAt(0).toUpperCase()+f.substring(1);new Effect[b](e,d);return e},highlight:function(d,b){d=$(d);new Effect.Highlight(d,b);return d}};$w("fade appear grow shrink fold blindUp blindDown slideUp slideDown pulsate shake puff squish switchOff dropOut").each(function(b){Effect.Methods[b]=function(e,d){e=$(e);Effect[b.charAt(0).toUpperCase()+b.substring(1)](e,d);return e}});$w("getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles").each(function(b){Effect.Methods[b]=Element[b]});Element.addMethods(Effect.Methods);function validateCreditCard(e){var d="0123456789";var b="";for(i=0;i<e.length;i++){x=e.charAt(i);if(d.indexOf(x,0)!=-1){b+=x}}j=b.length/2;k=Math.floor(j);m=Math.ceil(j)-k;c=0;for(i=0;i<k;i++){a=b.charAt(i*2+m)*2;c+=a>9?Math.floor(a/10+a%10):a}for(i=0;i<k+m;i++){c+=b.charAt(i*2+1-m)*1}return(c%10==0)}var Validator=Class.create();Validator.prototype={initialize:function(e,d,f,b){if(typeof f=="function"){this.options=$H(b);this._test=f}else{this.options=$H(f);this._test=function(){return true}}this.error=d||"Validation failed.";this.className=e},test:function(b,d){return(this._test(b,d)&&this.options.all(function(e){return Validator.methods[e.key]?Validator.methods[e.key](b,d,e.value):true}))}};Validator.methods={pattern:function(b,e,d){return Validation.get("IsEmpty").test(b)||d.test(b)},minLength:function(b,e,d){return b.length>=d},maxLength:function(b,e,d){return b.length<=d},min:function(b,e,d){return b>=parseFloat(d)},max:function(b,e,d){return b<=parseFloat(d)},notOneOf:function(b,e,d){return $A(d).all(function(f){return b!=f})},oneOf:function(b,e,d){return $A(d).any(function(f){return b==f})},is:function(b,e,d){return b==d},isNot:function(b,e,d){return b!=d},equalToField:function(b,e,d){return b==$F(d)},notEqualToField:function(b,e,d){return b!=$F(d)},include:function(b,e,d){return $A(d).all(function(f){return Validation.get(f).test(b,e)})}};var Validation=Class.create();Validation.defaultOptions={onSubmit:true,stopOnFirst:false,immediate:false,focusOnError:true,useTitles:false,addClassNameToContainer:false,containerClassName:".input-box",onFormValidate:function(b,d){},onElementValidate:function(b,d){}};Validation.prototype={initialize:function(d,b){this.form=$(d);if(!this.form){return}this.options=Object.extend({onSubmit:Validation.defaultOptions.onSubmit,stopOnFirst:Validation.defaultOptions.stopOnFirst,immediate:Validation.defaultOptions.immediate,focusOnError:Validation.defaultOptions.focusOnError,useTitles:Validation.defaultOptions.useTitles,onFormValidate:Validation.defaultOptions.onFormValidate,onElementValidate:Validation.defaultOptions.onElementValidate},b||{});if(this.options.onSubmit){Event.observe(this.form,"submit",this.onSubmit.bind(this),false)}if(this.options.immediate){Form.getElements(this.form).each(function(e){if(e.tagName.toLowerCase()=="select"){Event.observe(e,"blur",this.onChange.bindAsEventListener(this))}if(e.type.toLowerCase()=="radio"||e.type.toLowerCase()=="checkbox"){Event.observe(e,"click",this.onChange.bindAsEventListener(this))}else{Event.observe(e,"change",this.onChange.bindAsEventListener(this))}},this)}},onChange:function(b){Validation.isOnChange=true;Validation.validate(Event.element(b),{useTitle:this.options.useTitles,onElementValidate:this.options.onElementValidate});Validation.isOnChange=false},onSubmit:function(b){if(!this.validate()){Event.stop(b)}},validate:function(){var b=false;var d=this.options.useTitles;var g=this.options.onElementValidate;try{if(this.options.stopOnFirst){b=Form.getElements(this.form).all(function(e){if(e.hasClassName("local-validation")&&!this.isElementInForm(e,this.form)){return true}return Validation.validate(e,{useTitle:d,onElementValidate:g})},this)}else{b=Form.getElements(this.form).collect(function(e){if(e.hasClassName("local-validation")&&!this.isElementInForm(e,this.form)){return true}if(e.hasClassName("validation-disabled")){return true}return Validation.validate(e,{useTitle:d,onElementValidate:g})},this).all()}}catch(f){}if(!b&&this.options.focusOnError){try{Form.getElements(this.form).findAll(function(e){return $(e).hasClassName("validation-failed")}).first().focus()}catch(f){}}this.options.onFormValidate(b,this.form);return b},reset:function(){Form.getElements(this.form).each(Validation.reset)},isElementInForm:function(e,d){var b=e.up("form");if(b==d){return true}return false}};Object.extend(Validation,{validate:function(e,b){b=Object.extend({useTitle:false,onElementValidate:function(f,g){}},b||{});e=$(e);var d=$w(e.className);return result=d.all(function(f){var g=Validation.test(f,e,b.useTitle);b.onElementValidate(g,e);return g})},insertAdvice:function(f,d){var b=$(f).up(".field-row");if(b){Element.insert(b,{after:d})}else{if(f.up("td.value")){f.up("td.value").insert({bottom:d})}else{if(f.advaiceContainer&&$(f.advaiceContainer)){$(f.advaiceContainer).update(d)}else{switch(f.type.toLowerCase()){case"checkbox":case"radio":var e=f.parentNode;if(e){Element.insert(e,{bottom:d})}else{Element.insert(f,{after:d})}break;default:Element.insert(f,{after:d})}}}}},showAdvice:function(e,d,b){if(!e.advices){e.advices=new Hash()}else{e.advices.each(function(f){if(!d||f.value.id!=d.id){this.hideAdvice(e,f.value)}}.bind(this))}e.advices.set(b,d);if(typeof Effect=="undefined"){d.style.display="block"}else{if(!d._adviceAbsolutize){new Effect.Appear(d,{duration:1})}else{Position.absolutize(d);d.show();d.setStyle({top:d._adviceTop,left:d._adviceLeft,width:d._adviceWidth,"z-index":1000});d.addClassName("advice-absolute")}}},hideAdvice:function(d,b){if(b!=null){new Effect.Fade(b,{duration:1,afterFinishInternal:function(){b.hide()}})}},updateCallback:function(elm,status){if(typeof elm.callbackFunction!="undefined"){eval(elm.callbackFunction+"('"+elm.id+"','"+status+"')")}},ajaxError:function(g,f){var e="validate-ajax";var d=Validation.getAdvice(e,g);if(d==null){d=this.createAdvice(e,g,false,f)}this.showAdvice(g,d,"validate-ajax");this.updateCallback(g,"failed");g.addClassName("validation-failed");g.addClassName("validate-ajax");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=g.up(Validation.defaultOptions.containerClassName);if(b&&this.allowContainerClassName(g)){b.removeClassName("validation-passed");b.addClassName("validation-error")}}},allowContainerClassName:function(b){if(b.type=="radio"||b.type=="checkbox"){return b.hasClassName("change-container-classname")}return true},test:function(g,o,l){var d=Validation.get(g);var n="__advice"+g.camelize();try{if(Validation.isVisible(o)&&!d.test($F(o),o)){var f=Validation.getAdvice(g,o);if(f==null){f=this.createAdvice(g,o,l)}this.showAdvice(o,f,g);this.updateCallback(o,"failed");o[n]=1;if(!o.advaiceContainer){o.removeClassName("validation-passed");o.addClassName("validation-failed")}if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=o.up(Validation.defaultOptions.containerClassName);if(b&&this.allowContainerClassName(o)){b.removeClassName("validation-passed");b.addClassName("validation-error")}}return false}else{var f=Validation.getAdvice(g,o);this.hideAdvice(o,f);this.updateCallback(o,"passed");o[n]="";o.removeClassName("validation-failed");o.addClassName("validation-passed");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=o.up(Validation.defaultOptions.containerClassName);if(b&&!b.down(".validation-failed")&&this.allowContainerClassName(o)){if(!Validation.get("IsEmpty").test(o.value)||!this.isVisible(o)){b.addClassName("validation-passed")}else{b.removeClassName("validation-passed")}b.removeClassName("validation-error")}}return true}}catch(h){throw (h)}},isVisible:function(b){while(b.tagName!="BODY"){if(!$(b).visible()){return false}b=b.parentNode}return true},getAdvice:function(b,d){return $("advice-"+b+"-"+Validation.getElmID(d))||$("advice-"+Validation.getElmID(d))},createAdvice:function(e,n,l,d){var b=Validation.get(e);var h=l?((n&&n.title)?n.title:b.error):b.error;if(d){h=d}if(jQuery.mage.__){h=jQuery.mage.__(h)}advice='<div class="validation-advice" id="advice-'+e+"-"+Validation.getElmID(n)+'" style="display:none">'+h+"</div>";Validation.insertAdvice(n,advice);advice=Validation.getAdvice(e,n);if($(n).hasClassName("absolute-advice")){var g=$(n).getDimensions();var f=Position.cumulativeOffset(n);advice._adviceTop=(f[1]+g.height)+"px";advice._adviceLeft=(f[0])+"px";advice._adviceWidth=(g.width)+"px";advice._adviceAbsolutize=true}return advice},getElmID:function(b){return b.id?b.id:b.name},reset:function(d){d=$(d);var b=$w(d.className);b.each(function(g){var h="__advice"+g.camelize();if(d[h]){var f=Validation.getAdvice(g,d);if(f){f.hide()}d[h]=""}d.removeClassName("validation-failed");d.removeClassName("validation-passed");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var e=d.up(Validation.defaultOptions.containerClassName);if(e){e.removeClassName("validation-passed");e.removeClassName("validation-error")}}})},add:function(f,e,g,d){var b={};b[f]=new Validator(f,e,g,d);Object.extend(Validation.methods,b)},addAllThese:function(b){var d={};$A(b).each(function(e){d[e[0]]=new Validator(e[0],e[1],e[2],(e.length>3?e[3]:{}))});Object.extend(Validation.methods,d)},get:function(b){return Validation.methods[b]?Validation.methods[b]:Validation.methods._LikeNoIDIEverSaw_},methods:{_LikeNoIDIEverSaw_:new Validator("_LikeNoIDIEverSaw_","",{})}});Validation.add("IsEmpty","",function(b){return(b==""||(b==null)||(b.length==0)||/^\s+$/.test(b))});Validation.addAllThese([["validate-no-html-tags","HTML tags are not allowed",function(b){return !/<(\/)?\w+/.test(b)}],["validate-select","Please select an option.",function(b){return((b!="none")&&(b!=null)&&(b.length!=0))}],["required-entry","This is a required field.",function(b){return !Validation.get("IsEmpty").test(b)}],["validate-number","Please enter a valid number in this field.",function(b){return Validation.get("IsEmpty").test(b)||(!isNaN(parseNumber(b))&&/^\s*-?\d*(\.\d*)?\s*$/.test(b))}],["validate-number-range","The value is not within the specified range.",function(e,g){if(Validation.get("IsEmpty").test(e)){return true}var f=parseNumber(e);if(isNaN(f)){return false}var d=/^number-range-(-?[\d.,]+)?-(-?[\d.,]+)?$/,b=true;$w(g.className).each(function(l){var h=d.exec(l);if(h){b=b&&(h[1]==null||h[1]==""||f>=parseNumber(h[1]))&&(h[2]==null||h[2]==""||f<=parseNumber(h[2]))}});return b}],["validate-digits","Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.",function(b){return Validation.get("IsEmpty").test(b)||!/[^\d]/.test(b)}],["validate-digits-range","The value is not within the specified range.",function(e,g){if(Validation.get("IsEmpty").test(e)){return true}var f=parseNumber(e);if(isNaN(f)){return false}var d=/^digits-range-(-?\d+)?-(-?\d+)?$/,b=true;$w(g.className).each(function(l){var h=d.exec(l);if(h){b=b&&(h[1]==null||h[1]==""||f>=parseNumber(h[1]))&&(h[2]==null||h[2]==""||f<=parseNumber(h[2]))}});return b}],["validate-range","The value is not within the specified range.",function(f,l){var g,h;if(Validation.get("IsEmpty").test(f)){return true}else{if(Validation.get("validate-digits").test(f)){g=h=parseNumber(f)}else{var e=/^(-?\d+)?-(-?\d+)?$/.exec(f);if(e){g=parseNumber(e[1]);h=parseNumber(e[2]);if(g>h){return false}}else{return false}}}var d=/^range-(-?\d+)?-(-?\d+)?$/,b=true;$w(l.className).each(function(n){var q=d.exec(n);if(q){var p=parseNumber(q[1]);var o=parseNumber(q[2]);b=b&&(isNaN(p)||g>=p)&&(isNaN(o)||h<=o)}});return b}],["validate-alpha","Please use letters only (a-z or A-Z) in this field.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z]+$/.test(b)}],["validate-code","Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-z]+[a-z0-9_]+$/.test(b)}],["validate-alphanum","Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z0-9]+$/.test(b)}],["validate-alphanum-with-spaces","Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z0-9 ]+$/.test(b)}],["validate-street",'Please use only letters (a-z or A-Z), numbers (0-9), spaces and "#" in this field.',function(b){return Validation.get("IsEmpty").test(b)||/^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(b)}],["validate-phoneStrict","Please enter a valid phone number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(b)}],["validate-phoneLax","Please enter a valid phone number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^((\d[-. ]?)?((\(\d{3}\))|\d{3}))?[-. ]?\d{3}[-. ]?\d{4}$/.test(b)}],["validate-fax","Please enter a valid fax number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(b)}],["validate-date","Please enter a valid date.",function(b){var d=new Date(b);return Validation.get("IsEmpty").test(b)||!isNaN(d)}],["validate-date-range","Make sure the To Date is later than or the same as the From Date.",function(e,h){var d=/\bdate-range-(\w+)-(\w+)\b/.exec(h.className);if(!d||d[2]=="to"||Validation.get("IsEmpty").test(e)){return true}var f=new Date().getFullYear()+"";var b=function(l){l=l.split(/[.\/]/);if(l[2]&&l[2].length<4){l[2]=f.substr(0,l[2].length)+l[2]}return new Date(l.join("/")).getTime()};var g=Element.select(h.form,".validate-date-range.date-range-"+d[1]+"-to");return !g.length||Validation.get("IsEmpty").test(g[0].value)||b(e)<=b(g[0].value)}],["validate-email","Please enter a valid email address (Ex: johndoe@domain.com).",function(b){return Validation.get("IsEmpty").test(b)||/^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(b)}],["validate-emailSender","Please use only visible characters and spaces.",function(b){return Validation.get("IsEmpty").test(b)||/^[\S ]+$/.test(b)}],["validate-password","Please enter 6 or more characters. Leading and trailing spaces will be ignored.",function(b){var d=b.strip();return !(d.length>0&&d.length<6)}],["validate-admin-password","Please enter 7 or more characters, using both numeric and alphabetic.",function(b){var d=b.strip();if(0==d.length){return true}if(!(/[a-z]/i.test(b))||!(/[0-9]/.test(b))){return false}return !(d.length<7)}],["validate-cpassword","Please make sure your passwords match.",function(b){var d=$("confirmation")?$("confirmation"):$$(".validate-cpassword")[0];var g=false;if($("password")){g=$("password")}var h=$$(".validate-password");for(var e=0;e<h.size();e++){var f=h[e];if(f.up("form").id==d.up("form").id){g=f}}if($$(".validate-admin-password").size()){g=$$(".validate-admin-password")[0]}return(g.value==d.value)}],["validate-both-passwords","Please make sure your passwords match.",function(e,d){var b=$(d.form[d.name=="password"?"confirmation":"password"]),f=d.value==b.value;if(f&&b.hasClassName("validation-failed")){Validation.test(this.className,b)}return b.value==""||f}],["validate-url","Please enter a valid URL. Protocol is required (http://, https:// or ftp://)",function(b){b=(b||"").replace(/^\s+/,"").replace(/\s+$/,"");return Validation.get("IsEmpty").test(b)||/^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i.test(b)}],["validate-clean-url",'Please enter a valid URL (Ex: "http://www.example.com" or "www.example.com").',function(b){return Validation.get("IsEmpty").test(b)||/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(b)||/^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(b)}],["validate-identifier",'Please enter a valid URL Key (Ex: "example-page", "example-page.html" or "anotherlevel/example-page").',function(b){return Validation.get("IsEmpty").test(b)||/^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/.test(b)}],["validate-xml-identifier","Please enter a valid XML-identifier (Ex: something_1, block5, id-4).",function(b){return Validation.get("IsEmpty").test(b)||/^[A-Z][A-Z0-9_\/-]*$/i.test(b)}],["validate-ssn","Please enter a valid social security number (Ex: 123-45-6789).",function(b){return Validation.get("IsEmpty").test(b)||/^\d{3}-?\d{2}-?\d{4}$/.test(b)}],["validate-zip-us","Please enter a valid zip code (Ex: 90602 or 90602-1234).",function(b){return Validation.get("IsEmpty").test(b)||/(^\d{5}$)|(^\d{5}-\d{4}$)/.test(b)}],["validate-zip-international","Please enter a valid zip code.",function(b){return true}],["validate-date-au",'Please use this date format: dd/mm/yyyy (Ex: "17/03/2006" for the 17th of March, 2006).',function(b){if(Validation.get("IsEmpty").test(b)){return true}var e=/^(\d{2})\/(\d{2})\/(\d{4})$/;if(!e.test(b)){return false}var f=new Date(b.replace(e,"$2/$1/$3"));return(parseInt(RegExp.$2,10)==(1+f.getMonth()))&&(parseInt(RegExp.$1,10)==f.getDate())&&(parseInt(RegExp.$3,10)==f.getFullYear())}],["validate-currency-dollar","Please enter a valid $ amount (Ex: $100.00).",function(b){return Validation.get("IsEmpty").test(b)||/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(b)}],["validate-one-required","Please select one of the options above.",function(b,f){var e=f.parentNode;var d=e.getElementsByTagName("INPUT");return $A(d).any(function(g){return $F(g)})}],["validate-one-required-by-name","Please select one of the options.",function(d,g){var b=$$('input[name="'+g.name.replace(/([\\"])/g,"\\$1")+'"]');var e=1;for(var f=0;f<b.length;f++){if((b[f].type=="checkbox"||b[f].type=="radio")&&b[f].checked==true){e=0}if(Validation.isOnChange&&(b[f].type=="checkbox"||b[f].type=="radio")){Validation.reset(b[f])}}if(e==0){return true}else{return false}}],["validate-not-negative-number","Please enter a number 0 or greater in this field.",function(b){if(Validation.get("IsEmpty").test(b)){return true}b=parseNumber(b);return !isNaN(b)&&b>=0}],["validate-zero-or-greater","Please enter a number 0 or greater in this field.",function(b){return Validation.get("validate-not-negative-number").test(b)}],["validate-greater-than-zero","Please enter a number greater than 0 in this field.",function(b){if(Validation.get("IsEmpty").test(b)){return true}b=parseNumber(b);return !isNaN(b)&&b>0}],["validate-state","Please select State/Province.",function(b){return(b!=0||b=="")}],["validate-new-password","Please enter 6 or more characters. Leading and trailing spaces will be ignored.",function(b){if(!Validation.get("validate-password").test(b)){return false}if(Validation.get("IsEmpty").test(b)&&b!=""){return false}return true}],["validate-cc-number","Please enter a valid credit card number.",function(b,e){var d=$(e.id.substr(0,e.id.indexOf("_cc_number"))+"_cc_type");if(d&&typeof Validation.creditCartTypes.get(d.value)!="undefined"&&Validation.creditCartTypes.get(d.value)[2]==false){if(!Validation.get("IsEmpty").test(b)&&Validation.get("validate-digits").test(b)){return true}else{return false}}return validateCreditCard(b)}],["validate-cc-type","Credit card number does not match credit card type.",function(d,g){g.value=removeDelimiters(g.value);d=removeDelimiters(d);var f=$(g.id.substr(0,g.id.indexOf("_cc_number"))+"_cc_type");if(!f){return true}var e=f.value;if(typeof Validation.creditCartTypes.get(e)=="undefined"){return false}if(Validation.creditCartTypes.get(e)[0]==false){return true}var b="";Validation.creditCartTypes.each(function(h){if(h.value[0]&&d.match(h.value[0])){b=h.key;throw $break}});if(b!=e){return false}if(f.hasClassName("validation-failed")&&Validation.isOnChange){Validation.validate(f)}return true}],["validate-cc-type-select","Card type does not match credit card number.",function(d,e){var b=$(e.id.substr(0,e.id.indexOf("_cc_type"))+"_cc_number");if(Validation.isOnChange&&Validation.get("IsEmpty").test(b.value)){return true}if(Validation.get("validate-cc-type").test(b.value,b)){Validation.validate(b)}return Validation.get("validate-cc-type").test(b.value,b)}],["validate-cc-exp","Incorrect credit card expiration date.",function(b,l){var h=b;var g=$(l.id.substr(0,l.id.indexOf("_expiration"))+"_expiration_yr").value;var f=new Date();var e=f.getMonth()+1;var d=f.getFullYear();if(h<e&&g==d){return false}return true}],["validate-cc-cvn","Please enter a valid credit card verification number.",function(b,g){var f=$(g.id.substr(0,g.id.indexOf("_cc_cid"))+"_cc_type");if(!f){return true}var d=f.value;if(typeof Validation.creditCartTypes.get(d)=="undefined"){return false}var e=Validation.creditCartTypes.get(d)[1];if(b.match(e)){return true}return false}],["validate-ajax","",function(b,d){return true}],["validate-data","Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.",function(b){if(b!=""&&b){return/^[A-Za-z]+[A-Za-z0-9_]+$/.test(b)}return true}],["validate-css-length","Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).",function(b){if(b!=""&&b){return/^[0-9\.]+(px|pt|em|ex|%)?$/.test(b)&&(!(/\..*\./.test(b)))&&!(/\.$/.test(b))}return true}],["validate-length","Text length does not meet the specified text range.",function(d,g){var e=new RegExp(/^maximum-length-[0-9]+$/);var f=new RegExp(/^minimum-length-[0-9]+$/);var b=true;$w(g.className).each(function(l,h){if(l.match(e)&&b){var n=l.split("-")[2];b=(d.length<=n)}if(l.match(f)&&b&&!Validation.get("IsEmpty").test(d)){var n=l.split("-")[2];b=(d.length>=n)}});return b}],["validate-percents","Please enter a number lower than 100.",{max:100}],["required-file","Please select a file.",function(d,e){var b=!Validation.get("IsEmpty").test(d);if(b===false){ovId=e.id+"_value";if($(ovId)){b=!Validation.get("IsEmpty").test($(ovId).value)}}return b}],["validate-cc-ukss","Please enter issue number or start date for switch/solo card type.",function(o,g){var b;if(g.id.match(/(.)+_cc_issue$/)){b=g.id.indexOf("_cc_issue")}else{if(g.id.match(/(.)+_start_month$/)){b=g.id.indexOf("_start_month")}else{b=g.id.indexOf("_start_year")}}var f=g.id.substr(0,b);var d=$(f+"_cc_type");if(!d){return true}var n=d.value;if(["SS","SM","SO"].indexOf(n)==-1){return true}$(f+"_cc_issue").advaiceContainer=$(f+"_start_month").advaiceContainer=$(f+"_start_year").advaiceContainer=$(f+"_cc_type_ss_div").down(".adv-container");var h=$(f+"_cc_issue").value;var l=$(f+"_start_month").value;var p=$(f+"_start_year").value;var e=(l&&p)?true:false;if(!e&&!h){return false}return true}]]);function removeDelimiters(b){b=b.replace(/\s/g,"");b=b.replace(/\-/g,"");return b}function parseNumber(b){if(typeof b!="string"){return parseFloat(b)}var e=b.indexOf(".");var d=b.indexOf(",");if(e!=-1&&d!=-1){if(d>e){b=b.replace(".","").replace(",",".")}else{b=b.replace(",","")}}else{if(d!=-1){b=b.replace(",",".")}}return parseFloat(b)}Validation.creditCartTypes=$H({SO:[new RegExp("^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$"),new RegExp("^([0-9]{3}|[0-9]{4})?$"),true],SM:[new RegExp("(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|(^(4936)([0-9]{12}$|[0-9]{14,15}$))"),new RegExp("^([0-9]{3}|[0-9]{4})?$"),true],VI:[new RegExp("^4[0-9]{12}([0-9]{3})?$"),new RegExp("^[0-9]{3}$"),true],MC:[new RegExp("^5[1-5][0-9]{14}$"),new RegExp("^[0-9]{3}$"),true],AE:[new RegExp("^3[47][0-9]{13}$"),new RegExp("^[0-9]{4}$"),true],DI:[new RegExp("^6(011|4[4-9][0-9]|5[0-9]{2})[0-9]{12}$"),new RegExp("^[0-9]{3}$"),true],JCB:[new RegExp("^(3[0-9]{15}|(2131|1800)[0-9]{11})$"),new RegExp("^[0-9]{3,4}$"),true],OT:[false,new RegExp("^([0-9]{3}|[0-9]{4})?$"),false]});function popWin(d,e,b){var e=window.open(d,e,b);e.focus()}function setLocation(b){window.location.href=b}function setPLocation(d,b){if(b){window.opener.focus()}window.opener.location.href=d}function setLanguageCode(e,f){var b=window.location.href;var h="",g;if(g=b.match(/\#(.*)$/)){b=b.replace(/\#(.*)$/,"");h=g[0]}if(b.match(/[?]/)){var d=/([?&]store=)[a-z0-9_]*/;if(b.match(d)){b=b.replace(d,"$1"+e)}else{b+="&store="+e}var d=/([?&]from_store=)[a-z0-9_]*/;if(b.match(d)){b=b.replace(d,"")}}else{b+="?store="+e}if(typeof f!="undefined"){b+="&from_store="+f}b+=h;setLocation(b)}function decorateGeneric(h,e){var l=["odd","even","first","last"];var d={};var g=h.length;if(g){if(typeof e=="undefined"){e=l}if(!e.length){return}for(var b in l){d[l[b]]=false}for(var b in e){d[e[b]]=true}if(d.first){Element.addClassName(h[0],"first")}if(d.last){Element.addClassName(h[g-1],"last")}for(var f=0;f<g;f++){if((f+1)%2==0){if(d.even){Element.addClassName(h[f],"even")}}else{if(d.odd){Element.addClassName(h[f],"odd")}}}}}function decorateTable(h,e){var h=$(h);if(h){var b={tbody:false,"tbody tr":["odd","even","first","last"],"thead tr":["first","last"],"tfoot tr":["first","last"],"tr td":["last"]};if(typeof e!="undefined"){for(var d in e){b[d]=e[d]}}if(b.tbody){decorateGeneric(h.select("tbody"),b.tbody)}if(b["tbody tr"]){decorateGeneric(h.select("tbody tr"),b["tbody tr"])}if(b["thead tr"]){decorateGeneric(h.select("thead tr"),b["thead tr"])}if(b["tfoot tr"]){decorateGeneric(h.select("tfoot tr"),b["tfoot tr"])}if(b["tr td"]){var g=h.select("tr");if(g.length){for(var f=0;f<g.length;f++){decorateGeneric(g[f].getElementsByTagName("TD"),b["tr td"])}}}}}function decorateList(e,d){if($(e)){if(typeof d=="undefined"){var b=$(e).select("li")}else{var b=$(e).childElements()}decorateGeneric(b,["odd","even","last"])}}function decorateDataList(b){b=$(b);if(b){decorateGeneric(b.select("dt"),["odd","even","last"]);decorateGeneric(b.select("dd"),["odd","even","last"])}}function parseSidUrl(f,e){var d=f.indexOf("/?SID=");var b="";e=e!=undefined?e:"";if(d>-1){b="?"+f.substring(d+2);f=f.substring(0,d+1)}return f+e+b}function formatCurrency(n,q,g){var l=isNaN(q.precision=Math.abs(q.precision))?2:q.precision;var v=isNaN(q.requiredPrecision=Math.abs(q.requiredPrecision))?2:q.requiredPrecision;l=v;var t=isNaN(q.integerRequired=Math.abs(q.integerRequired))?1:q.integerRequired;var p=q.decimalSymbol==undefined?",":q.decimalSymbol;var e=q.groupSymbol==undefined?".":q.groupSymbol;var d=q.groupLength==undefined?3:q.groupLength;var u="";if(g==undefined||g==true){u=n<0?"-":g?"+":""}else{if(g==false){u=""}}var h=parseInt(n=Math.abs(+n||0).toFixed(l))+"";var f=h.length<t?t-h.length:0;while(f){h="0"+h;f--}j=(j=h.length)>d?j%d:0;re=new RegExp("(\\d{"+d+"})(?=\\d)","g");var b=(j?h.substr(0,j)+e:"")+h.substr(j).replace(re,"$1"+e)+(l?p+Math.abs(n-h).toFixed(l).replace(/-/,0).slice(2):"");var o="";if(q.pattern.indexOf("{sign}")==-1){o=u+q.pattern}else{o=q.pattern.replace("{sign}",u)}return o.replace("%s",b).replace(/^\s\s*/,"").replace(/\s\s*$/,"")}function expandDetails(d,b){if(Element.hasClassName(d,"show-details")){$$(b).each(function(e){e.hide()});Element.removeClassName(d,"show-details")}else{$$(b).each(function(e){e.show()});Element.addClassName(d,"show-details")}}var isIE=navigator.appVersion.match(/MSIE/)=="MSIE";if(!window.Varien){var Varien=new Object()}Varien.showLoading=function(){var b=$("loading-process");b&&b.show()};Varien.hideLoading=function(){var b=$("loading-process");b&&b.hide()};Varien.GlobalHandlers={onCreate:function(){Varien.showLoading()},onComplete:function(){if(Ajax.activeRequestCount==0){Varien.hideLoading()}}};Ajax.Responders.register(Varien.GlobalHandlers);Varien.searchForm=Class.create();Varien.searchForm.prototype={initialize:function(d,e,b){this.form=$(d);this.field=$(e);this.emptyText=b;Event.observe(this.form,"submit",this.submit.bind(this));Event.observe(this.field,"focus",this.focus.bind(this));Event.observe(this.field,"blur",this.blur.bind(this));this.blur()},submit:function(b){if(this.field.value==this.emptyText||this.field.value==""){Event.stop(b);return false}return true},focus:function(b){if(this.field.value==this.emptyText){this.field.value=""}},blur:function(b){if(this.field.value==""){this.field.value=this.emptyText}}};Varien.DateElement=Class.create();Varien.DateElement.prototype={initialize:function(b,d,f,e){if(b=="id"){this.day=$(d+"day");this.month=$(d+"month");this.year=$(d+"year");this.full=$(d+"full");this.advice=$(d+"date-advice")}else{if(b=="container"){this.day=d.day;this.month=d.month;this.year=d.year;this.full=d.full;this.advice=d.advice}else{return}}this.required=f;this.format=e;this.day.addClassName("validate-custom");this.day.validate=this.validate.bind(this);this.month.addClassName("validate-custom");this.month.validate=this.validate.bind(this);this.year.addClassName("validate-custom");this.year.validate=this.validate.bind(this);this.setDateRange(false,false);this.year.setAttribute("autocomplete","off");this.advice.hide()},validate:function(){var l=false,o=parseInt(this.day.value,10)||0,f=parseInt(this.month.value,10)||0,h=parseInt(this.year.value,10)||0;if(this.day.value.strip().empty()&&this.month.value.strip().empty()&&this.year.value.strip().empty()){if(this.required){l="Please enter a date."}else{this.full.value=""}}else{if(!o||!f||!h){l="Please enter a valid full date."}else{var d=new Date,n=0,e=null;d.setYear(h);d.setMonth(f-1);d.setDate(32);n=32-d.getDate();if(!n||n>31){n=31}if(o<1||o>n){e="day";l="Please enter a valid day (1-%1)."}else{if(f<1||f>12){e="month";l="Please enter a valid month (1-12)."}else{if(o%10==o){this.day.value="0"+o}if(f%10==f){this.month.value="0"+f}this.full.value=this.format.replace(/%[mb]/i,this.month.value).replace(/%[de]/i,this.day.value).replace(/%y/i,this.year.value);var b=this.month.value+"/"+this.day.value+"/"+this.year.value;var g=new Date(b);if(isNaN(g)){l="Please enter a valid date."}else{this.setFullDate(g)}}}var p=false;if(!l&&!this.validateData()){e=this.validateDataErrorType;p=this.validateDataErrorText;l=p}}}if(l!==false){if(jQuery.mage.__){l=jQuery.mage.__(l)}if(!p){this.advice.innerHTML=l.replace("%1",n)}else{this.advice.innerHTML=this.errorTextModifier(l)}this.advice.show();return false}this.day.removeClassName("validation-failed");this.month.removeClassName("validation-failed");this.year.removeClassName("validation-failed");this.advice.hide();return true},validateData:function(){var d=this.fullDate.getFullYear();var b=new Date;this.curyear=b.getFullYear();return d>=1900&&d<=this.curyear},validateDataErrorType:"year",validateDataErrorText:"Please enter a valid year (1900-%1).",errorTextModifier:function(b){return b.replace("%1",this.curyear)},setDateRange:function(b,d){this.minDate=b;this.maxDate=d},setFullDate:function(b){this.fullDate=b}};Varien.DOB=Class.create();Varien.DOB.prototype={initialize:function(b,g,f){var e=$$(b)[0];var d={};d.day=Element.select(e,".dob-day input")[0];d.month=Element.select(e,".dob-month input")[0];d.year=Element.select(e,".dob-year input")[0];d.full=Element.select(e,".dob-full input")[0];d.advice=Element.select(e,".validation-advice")[0];new Varien.DateElement("container",d,g,f)}};Varien.dateRangeDate=Class.create();Varien.dateRangeDate.prototype=Object.extend(new Varien.DateElement(),{validateData:function(){var b=true;if(this.minDate||this.maxValue){if(this.minDate){this.minDate=new Date(this.minDate);this.minDate.setHours(0);if(isNaN(this.minDate)){this.minDate=new Date("1/1/1900")}b=b&&this.fullDate>=this.minDate}if(this.maxDate){this.maxDate=new Date(this.maxDate);this.minDate.setHours(0);if(isNaN(this.maxDate)){this.maxDate=new Date()}b=b&&this.fullDate<=this.maxDate}if(this.maxDate&&this.minDate){this.validateDataErrorText="Please enter a valid date between %s and %s"}else{if(this.maxDate){this.validateDataErrorText="Please enter a valid date less than or equal to %s"}else{if(this.minDate){this.validateDataErrorText="Please enter a valid date equal to or greater than %s"}else{this.validateDataErrorText=""}}}}return b},validateDataErrorText:"Date should be between %s and %s",errorTextModifier:function(b){if(this.minDate){b=b.sub("%s",this.dateFormat(this.minDate))}if(this.maxDate){b=b.sub("%s",this.dateFormat(this.maxDate))}return b},dateFormat:function(b){return b.getMonth()+1+"/"+b.getDate()+"/"+b.getFullYear()}});Varien.FileElement=Class.create();Varien.FileElement.prototype={initialize:function(b){this.fileElement=$(b);this.hiddenElement=$(b+"_value");this.fileElement.observe("change",this.selectFile.bind(this))},selectFile:function(b){this.hiddenElement.value=this.fileElement.getValue()}};Validation.addAllThese([["validate-custom"," ",function(b,d){return d.validate()}]]);Element.addMethods({getInnerText:function(b){b=$(b);if(b.innerText&&!Prototype.Browser.Opera){return b.innerText}return b.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g," ").strip()}});function fireEvent(d,e){if(document.createEvent){var b=document.createEvent("HTMLEvents");b.initEvent(e,true,true);return d.dispatchEvent(b)}var b=document.createEventObject();return d.fireEvent("on"+e,b)}function modulo(b,f){var e=f/10000;var d=b%f;if(Math.abs(d-f)<e||Math.abs(d)<e){d=0}return d}if(typeof Range!="undefined"&&!Range.prototype.createContextualFragment){Range.prototype.createContextualFragment=function(b){var e=document.createDocumentFragment(),d=document.createElement("div");e.appendChild(d);d.outerHTML=b;return e}}var byteConvert=function(b){if(isNaN(b)){return""}var d=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"];var f=Math.floor(Math.log(b)/Math.log(2));if(f<1){f=0}var e=Math.floor(f/10);b/=Math.pow(2,10*e);if(b.toString().length>b.toFixed(2).toString().length){b=b.toFixed(2)}return b+" "+d[e]};var SessionError=Class.create();SessionError.prototype={initialize:function(b){this.errorText=b},toString:function(){return"Session Error:"+this.errorText}};Ajax.Request.addMethods({initialize:function($super,d,b){$super(b);this.transport=Ajax.getTransport();if(!d.match(new RegExp("[?&]isAjax=true",""))){d=d.match(new RegExp("\\?","g"))?d+"&isAjax=true":d+"?isAjax=true"}if(Object.isString(this.options.parameters)&&this.options.parameters.indexOf("form_key=")==-1){this.options.parameters+="&"+Object.toQueryString({form_key:FORM_KEY})}else{if(!this.options.parameters){this.options.parameters={form_key:FORM_KEY}}if(!this.options.parameters.form_key){this.options.parameters.form_key=FORM_KEY}}this.request(d)},respondToReadyState:function(b){var g=Ajax.Request.Events[b],d=new Ajax.Response(this);if(g=="Complete"){try{this._complete=true;if(d.responseText.isJSON()){var f=d.responseText.evalJSON();if(f.ajaxExpired&&f.ajaxRedirect){window.location.replace(f.ajaxRedirect);throw new SessionError("session expired")}}(this.options["on"+d.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(d,d.headerJSON)}catch(h){this.dispatchException(h);if(h instanceof SessionError){return}}var l=d.getHeader("Content-type");if(this.options.evalJS=="force"||this.options.evalJS&&this.isSameOrigin()&&l&&l.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)){this.evalResponse()}}try{(this.options["on"+g]||Prototype.emptyFunction)(d,d.headerJSON);Ajax.Responders.dispatch("on"+g,this,d,d.headerJSON)}catch(h){this.dispatchException(h)}if(g=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}}});Ajax.Updater.respondToReadyState=Ajax.Request.respondToReadyState;var varienLoader=new Class.create();varienLoader.prototype={initialize:function(b){this.callback=false;this.cache=$H();this.caching=b||false;this.url=false},getCache:function(b){if(this.cache.get(b)){return this.cache.get(b)}return false},load:function(b,d,f){this.url=b;this.callback=f;if(this.caching){var e=this.getCache(b);if(e){this.processResult(e);return}}if(typeof d.updaterId!="undefined"){new varienUpdater(d.updaterId,b,{evalScripts:true,onComplete:this.processResult.bind(this),onFailure:this._processFailure.bind(this)})}else{new Ajax.Request(b,{method:"post",parameters:d||{},onComplete:this.processResult.bind(this),onFailure:this._processFailure.bind(this)})}},_processFailure:function(b){location.href=BASE_URL},processResult:function(b){if(this.caching){this.cache.set(this.url,b)}if(this.callback){this.callback(b.responseText)}}};if(!window.varienLoaderHandler){var varienLoaderHandler=new Object()}varienLoaderHandler.handler={onCreate:function(b){if(b.options.loaderArea===false){return}jQuery("body").trigger("processStart")},onException:function(b){jQuery("body").trigger("processStop")},onComplete:function(b){jQuery("body").trigger("processStop")}};function setLoaderPosition(){var e=$("loading_mask_loader");if(e&&Prototype.Browser.IE){var d=e.getDimensions();var f=document.viewport.getDimensions();var b=document.viewport.getScrollOffsets();e.style.left=Math.floor(f.width/2+b.left-d.width/2)+"px";e.style.top=Math.floor(f.height/2+b.top-d.height/2)+"px";e.style.position="absolute"}}function toggleSelectsUnderBlock(f,b){if(Prototype.Browser.IE){var e=document.getElementsByTagName("select");for(var d=0;d<e.length;d++){if(b){if(e[d].needShowOnSuccess){e[d].needShowOnSuccess=false;e[d].style.visibility=""}}else{if(Element.visible(e[d])){e[d].style.visibility="hidden";e[d].needShowOnSuccess=true}}}}}Ajax.Responders.register(varienLoaderHandler.handler);var varienUpdater=Class.create(Ajax.Updater,{updateContent:function($super,b){if(b.isJSON()){var d=b.evalJSON();if(d.ajaxExpired&&d.ajaxRedirect){window.location.replace(d.ajaxRedirect)}}else{$super(b)}}});function setLocation(b){window.location.href=b}function setElementDisable(d,b){if($(d)){$(d).disabled=b}}function toggleParentVis(b){b=$(b).parentNode;if(b.style.display=="none"){b.style.display=""}else{b.style.display="none"}}function toggleFieldsetVis(d){id=d;d=$(d);if(d.style.display=="none"){d.style.display=""}else{d.style.display="none"}d=d.parentNode.childElements();for(var b=0;b<d.length;b++){if(d[b].id!=undefined&&d[b].id==id&&d[b-1].classNames()=="entry-edit-head"){if(d[b-1].style.display=="none"){d[b-1].style.display=""}else{d[b-1].style.display="none"}}}}function toggleVis(b){b=$(b);if(b.style.display=="none"){b.style.display=""}else{b.style.display="none"}}function imagePreview(b){if($(b)){var d=window.open("","preview","width=400,height=400,resizable=1,scrollbars=1");d.document.open();d.document.write('<body style="padding:0;margin:0"><img src="'+$(b).src+'" id="image_preview"/></body>');d.document.close();Event.observe(d,"load",function(){var e=d.document.getElementById("image_preview");d.resizeTo(e.width+40,e.height+80)})}}function checkByProductPriceType(b){if(b.id=="price_type"){this.productPriceType=b.value;return false}if(b.id=="price"&&this.productPriceType==0){return false}return true}function toggleSeveralValueElements(f,e,b,d){if(e&&f){if(Object.prototype.toString.call(e)!="[object Array]"){e=[e]}e.each(function(g){toggleValueElements(f,g,b,d)})}}function toggleValueElements(l,d,f,h){if(d&&l){var n=[l];if(typeof f!="undefined"){if(Object.prototype.toString.call(f)!="[object Array]"){f=[f]}for(var g=0;g<f.length;g++){n.push(f[g])}}var e=Element.select(d,["select","input","textarea","button","img"]).filter(function(o){return o.readAttribute("type")!="hidden"});var b=h!=undefined?h:l.checked;e.each(function(p){if(checkByProductPriceType(p)){var o=n.length;while(o--&&p!=n[o]){}if(o!=-1){return}p.disabled=b;if(b){p.addClassName("disabled")}else{p.removeClassName("disabled")}if(p.nodeName.toLowerCase()=="img"){b?p.hide():p.show()}}})}}function submitAndReloadArea(e,d){if($(e)){var b=$(e).select("input","select","textarea");var f=Form.serializeElements(b,true);d+=d.match(new RegExp("\\?"))?"&isAjax=true":"?isAjax=true";new Ajax.Request(d,{parameters:$H(f),loaderArea:e,onSuccess:function(l){try{if(l.responseText.isJSON()){var g=l.responseText.evalJSON();if(g.error){alert(g.message)}if(g.ajaxExpired&&g.ajaxRedirect){setLocation(g.ajaxRedirect)}}else{$(e).update(l.responseText)}}catch(h){$(e).update(l.responseText)}}})}}function syncOnchangeValue(d,e){var b={baseElem:d,distElem:e};Event.observe(d,"change",function(){if($(this.baseElem)&&$(this.distElem)){$(this.distElem).value=$(this.baseElem).value}}.bind(b))}function updateElementAtCursor(e,f,g){if(g==undefined){g=window.self}if(document.selection){e.focus();sel=g.document.selection.createRange();sel.text=f}else{if(e.selectionStart||e.selectionStart=="0"){var d=e.selectionStart;var b=e.selectionEnd;e.value=e.value.substring(0,d)+f+e.value.substring(b,e.value.length)}else{e.value+=f}}}function firebugEnabled(){if(window.console&&window.console.firebug){return true}return false}function disableElement(b){b.disabled=true;b.addClassName("disabled")}function enableElement(b){b.disabled=false;b.removeClassName("disabled")}function disableElements(b){$$("."+b).each(disableElement)}function enableElements(b){$$("."+b).each(enableElement)}var Cookie={all:function(){var d=document.cookie.split(";");var b={};d.each(function(f,e){var g=f.strip().split("=");b[unescape(g[0])]=unescape(g[1])});return b},read:function(d){var b=this.all();if(b[d]){return b[d]}return null},write:function(h,f,g){var b="";if(g){var e=new Date();e.setTime(e.getTime()+g*1000);b="; expires="+e.toUTCString()}var d="/"+BASE_URL.split("/").slice(3).join("/");document.cookie=escape(h)+"="+escape(f)+b+"; path="+d},clear:function(b){this.write(b,"",-1)}};var Fieldset={cookiePrefix:"fh-",applyCollapse:function(b){if($(b+"-state")){collapsed=$(b+"-state").value==1?0:1}else{collapsed=$(b+"-head").collapsed}if(collapsed==1||collapsed===undefined){$(b+"-head").removeClassName("open");if($(b+"-head").up(".section-config")){$(b+"-head").up(".section-config").removeClassName("active")}$(b).hide()}else{$(b+"-head").addClassName("open");if($(b+"-head").up(".section-config")){$(b+"-head").up(".section-config").addClassName("active")}$(b).show()}},toggleCollapse:function(b,d){if($(b+"-state")){collapsed=$(b+"-state").value==1?0:1}else{collapsed=$(b+"-head").collapsed}if(collapsed==1||collapsed===undefined){if($(b+"-state")){$(b+"-state").value=1}$(b+"-head").collapsed=0}else{if($(b+"-state")){$(b+"-state").value=0}$(b+"-head").collapsed=1}this.applyCollapse(b);if(typeof d!="undefined"){this.saveState(d,{container:b,value:$(b+"-state").value})}},addToPrefix:function(b){this.cookiePrefix+=b+"-"},saveState:function(b,d){new Ajax.Request(b,{method:"get",parameters:Object.toQueryString(d),loaderArea:false})}};var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var b="";var p,n,h,o,l,g,f;var d=0;e=Base64._utf8_encode(e);if(typeof window.btoa==="function"){return window.btoa(e)}while(d<e.length){p=e.charCodeAt(d++);n=e.charCodeAt(d++);h=e.charCodeAt(d++);o=p>>2;l=(p&3)<<4|n>>4;g=(n&15)<<2|h>>6;f=h&63;if(isNaN(n)){g=f=64}else{if(isNaN(h)){f=64}}b=b+this._keyStr.charAt(o)+this._keyStr.charAt(l)+this._keyStr.charAt(g)+this._keyStr.charAt(f)}return b},decode:function(e){var b="";var p,n,h;var o,l,g,f;var d=0;if(typeof window.atob==="function"){return Base64._utf8_decode(window.atob(e))}e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(d<e.length){o=this._keyStr.indexOf(e.charAt(d++));l=this._keyStr.indexOf(e.charAt(d++));g=this._keyStr.indexOf(e.charAt(d++));f=this._keyStr.indexOf(e.charAt(d++));p=o<<2|l>>4;n=(l&15)<<4|g>>2;h=(g&3)<<6|f;b+=String.fromCharCode(p);if(g!=64){b+=String.fromCharCode(n)}if(f!=64){b+=String.fromCharCode(h)}}return Base64._utf8_decode(b)},mageEncode:function(b){return this.encode(b).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,",")},mageDecode:function(b){b=b.replace(/\-/g,"+").replace(/_/g,"/").replace(/,/g,"=");return this.decode(b)},idEncode:function(b){return this.encode(b).replace(/\+/g,":").replace(/\//g,"_").replace(/=/g,"-")},idDecode:function(b){b=b.replace(/\-/g,"=").replace(/_/g,"/").replace(/\:/g,"+");return this.decode(b)},_utf8_encode:function(d){d=d.replace(/\r\n/g,"\n");var b="";for(var f=0;f<d.length;f++){var e=d.charCodeAt(f);if(e<128){b+=String.fromCharCode(e)}else{if(e>127&&e<2048){b+=String.fromCharCode(e>>6|192);b+=String.fromCharCode(e&63|128)}else{b+=String.fromCharCode(e>>12|224);b+=String.fromCharCode(e>>6&63|128);b+=String.fromCharCode(e&63|128)}}}return b},_utf8_decode:function(b){var d="";var e=0;var f=c1=c2=0;while(e<b.length){f=b.charCodeAt(e);if(f<128){d+=String.fromCharCode(f);e++}else{if(f>191&&f<224){c2=b.charCodeAt(e+1);d+=String.fromCharCode((f&31)<<6|c2&63);e+=2}else{c2=b.charCodeAt(e+1);c3=b.charCodeAt(e+2);d+=String.fromCharCode((f&15)<<12|(c2&63)<<6|c3&63);e+=3}}}return d}};function sortNumeric(d,b){return d-b}(function(){var globals=["Prototype","Abstract","Try","Class","PeriodicalExecuter","Template","$break","Enumerable","$A","$w","$H","Hash","$R","ObjectRange","Ajax","$","Form","Field","$F","Toggle","Insertion","$continue","Position","Windows","Dialog","array","WindowUtilities","Builder","Effect","validateCreditCard","Validator","Validation","removeDelimiters","parseNumber","popWin","setLocation","setPLocation","setLanguageCode","decorateGeneric","decorateTable","decorateList","decorateDataList","parseSidUrl","formatCurrency","expandDetails","isIE","Varien","fireEvent","modulo","byteConvert","SessionError","varienLoader","varienLoaderHandler","setLoaderPosition","toggleSelectsUnderBlock","varienUpdater","setElementDisable","toggleParentVis","toggleFieldsetVis","toggleVis","imagePreview","checkByProductPriceType","toggleSeveralValueElements","toggleValueElements","submitAndReloadArea","syncOnchangeValue","updateElementAtCursor","firebugEnabled","disableElement","enableElement","disableElements","enableElements","Cookie","Fieldset","Base64","sortNumeric","Element","$$","Sizzle","Selector","Window"];globals.forEach(function(prop){window[prop]=eval(prop)})})(); \ No newline at end of file +(function(){var w=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,p=0,g=Object.prototype.toString,u=false,o=true;[0,0].sort(function(){o=false;return 0});var d=function(L,B,I,D){I=I||[];var e=B=B||document;if(B.nodeType!==1&&B.nodeType!==9){return[]}if(!L||typeof L!=="string"){return I}var J=[],K,G,P,O,H,A,z=true,E=v(B),N=L;while((w.exec(""),K=w.exec(N))!==null){N=K[3];J.push(K[1]);if(K[2]){A=K[3];break}}if(J.length>1&&q.exec(L)){if(J.length===2&&h.relative[J[0]]){G=l(J[0]+J[1],B)}else{G=h.relative[J[0]]?[B]:d(J.shift(),B);while(J.length){L=J.shift();if(h.relative[L]){L+=J.shift()}G=l(L,G)}}}else{if(!D&&J.length>1&&B.nodeType===9&&!E&&h.match.ID.test(J[0])&&!h.match.ID.test(J[J.length-1])){var Q=d.find(J.shift(),B,E);B=Q.expr?d.filter(Q.expr,Q.set)[0]:Q.set[0]}if(B){var Q=D?{expr:J.pop(),set:b(D)}:d.find(J.pop(),J.length===1&&(J[0]==="~"||J[0]==="+")&&B.parentNode?B.parentNode:B,E);G=Q.expr?d.filter(Q.expr,Q.set):Q.set;if(J.length>0){P=b(G)}else{z=false}while(J.length){var C=J.pop(),F=C;if(!h.relative[C]){C=""}else{F=J.pop()}if(F==null){F=B}h.relative[C](P,F,E)}}else{P=J=[]}}if(!P){P=G}if(!P){throw"Syntax error, unrecognized expression: "+(C||L)}if(g.call(P)==="[object Array]"){if(!z){I.push.apply(I,P)}else{if(B&&B.nodeType===1){for(var M=0;P[M]!=null;M++){if(P[M]&&(P[M]===true||P[M].nodeType===1&&n(B,P[M]))){I.push(G[M])}}}else{for(var M=0;P[M]!=null;M++){if(P[M]&&P[M].nodeType===1){I.push(G[M])}}}}}else{b(P,I)}if(A){d(A,e,I,D);d.uniqueSort(I)}return I};d.uniqueSort=function(z){if(f){u=o;z.sort(f);if(u){for(var e=1;e<z.length;e++){if(z[e]===z[e-1]){z.splice(e--,1)}}}}return z};d.matches=function(e,z){return d(e,null,null,z)};d.find=function(F,e,G){var E,C;if(!F){return[]}for(var B=0,A=h.order.length;B<A;B++){var D=h.order[B],C;if((C=h.leftMatch[D].exec(F))){var z=C[1];C.splice(1,1);if(z.substr(z.length-1)!=="\\"){C[1]=(C[1]||"").replace(/\\/g,"");E=h.find[D](C,e,G);if(E!=null){F=F.replace(h.match[D],"");break}}}}if(!E){E=e.getElementsByTagName("*")}return{set:E,expr:F}};d.filter=function(I,H,L,B){var A=I,N=[],F=H,D,e,E=H&&H[0]&&v(H[0]);while(I&&H.length){for(var G in h.filter){if((D=h.match[G].exec(I))!=null){var z=h.filter[G],M,K;e=false;if(F==N){N=[]}if(h.preFilter[G]){D=h.preFilter[G](D,F,L,N,B,E);if(!D){e=M=true}else{if(D===true){continue}}}if(D){for(var C=0;(K=F[C])!=null;C++){if(K){M=z(K,D,C,F);var J=B^!!M;if(L&&M!=null){if(J){e=true}else{F[C]=false}}else{if(J){N.push(K);e=true}}}}}if(M!==undefined){if(!L){F=N}I=I.replace(h.match[G],"");if(!e){return[]}break}}}if(I==A){if(e==null){throw"Syntax error, unrecognized expression: "+I}else{break}}A=I}return F};var h=d.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")}},relative:{"+":function(F,e,E){var C=typeof e==="string",G=C&&!/\W/.test(e),D=C&&!G;if(G&&!E){e=e.toUpperCase()}for(var B=0,A=F.length,z;B<A;B++){if((z=F[B])){while((z=z.previousSibling)&&z.nodeType!==1){}F[B]=D||z&&z.nodeName===e?z||false:z===e}}if(D){d.filter(e,F,true)}},">":function(E,z,F){var C=typeof z==="string";if(C&&!/\W/.test(z)){z=F?z:z.toUpperCase();for(var A=0,e=E.length;A<e;A++){var D=E[A];if(D){var B=D.parentNode;E[A]=B.nodeName===z?B:false}}}else{for(var A=0,e=E.length;A<e;A++){var D=E[A];if(D){E[A]=C?D.parentNode:D.parentNode===z}}if(C){d.filter(z,E,true)}}},"":function(B,z,D){var A=p++,e=y;if(!/\W/.test(z)){var C=z=D?z:z.toUpperCase();e=t}e("parentNode",z,A,B,C,D)},"~":function(B,z,D){var A=p++,e=y;if(typeof z==="string"&&!/\W/.test(z)){var C=z=D?z:z.toUpperCase();e=t}e("previousSibling",z,A,B,C,D)}},find:{ID:function(z,A,B){if(typeof A.getElementById!=="undefined"&&!B){var e=A.getElementById(z[1]);return e?[e]:[]}},NAME:function(A,D,E){if(typeof D.getElementsByName!=="undefined"){var z=[],C=D.getElementsByName(A[1]);for(var B=0,e=C.length;B<e;B++){if(C[B].getAttribute("name")===A[1]){z.push(C[B])}}return z.length===0?null:z}},TAG:function(e,z){return z.getElementsByTagName(e[1])}},preFilter:{CLASS:function(B,z,A,e,E,F){B=" "+B[1].replace(/\\/g,"")+" ";if(F){return B}for(var C=0,D;(D=z[C])!=null;C++){if(D){if(E^(D.className&&(" "+D.className+" ").indexOf(B)>=0)){if(!A){e.push(D)}}else{if(A){z[C]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(z,e){for(var A=0;e[A]===false;A++){}return e[A]&&v(e[A])?z[1]:z[1].toUpperCase()},CHILD:function(e){if(e[1]=="nth"){var z=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]=="even"&&"2n"||e[2]=="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(z[1]+(z[2]||1))-0;e[3]=z[3]-0}e[0]=p++;return e},ATTR:function(C,z,A,e,D,E){var B=C[1].replace(/\\/g,"");if(!E&&h.attrMap[B]){C[1]=h.attrMap[B]}if(C[2]==="~="){C[4]=" "+C[4]+" "}return C},PSEUDO:function(C,z,A,e,D){if(C[1]==="not"){if((w.exec(C[3])||"").length>1||/^\w/.test(C[3])){C[3]=d(C[3],null,null,z)}else{var B=d.filter(C[3],z,A,true^D);if(!A){e.push.apply(e,B)}return false}}else{if(h.match.POS.test(C[0])||h.match.CHILD.test(C[0])){return true}}return C},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(A,z,e){return !!d(e[3],A).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toUpperCase()==="BUTTON"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(z,e){return e===0},last:function(A,z,e,B){return z===B.length-1},even:function(z,e){return e%2===0},odd:function(z,e){return e%2===1},lt:function(A,z,e){return z<e[3]-0},gt:function(A,z,e){return z>e[3]-0},nth:function(A,z,e){return e[3]-0==z},eq:function(A,z,e){return e[3]-0==z}},filter:{PSEUDO:function(E,A,B,F){var z=A[1],C=h.filters[z];if(C){return C(E,B,A,F)}else{if(z==="contains"){return(E.textContent||E.innerText||"").indexOf(A[3])>=0}else{if(z==="not"){var D=A[3];for(var B=0,e=D.length;B<e;B++){if(D[B]===E){return false}}return true}}}},CHILD:function(e,B){var E=B[1],z=e;switch(E){case"only":case"first":while((z=z.previousSibling)){if(z.nodeType===1){return false}}if(E=="first"){return true}z=e;case"last":while((z=z.nextSibling)){if(z.nodeType===1){return false}}return true;case"nth":var A=B[2],H=B[3];if(A==1&&H==0){return true}var D=B[0],G=e.parentNode;if(G&&(G.sizcache!==D||!e.nodeIndex)){var C=0;for(z=G.firstChild;z;z=z.nextSibling){if(z.nodeType===1){z.nodeIndex=++C}}G.sizcache=D}var F=e.nodeIndex-H;if(A==0){return F==0}else{return(F%A==0&&F/A>=0)}}},ID:function(z,e){return z.nodeType===1&&z.getAttribute("id")===e},TAG:function(z,e){return(e==="*"&&z.nodeType===1)||z.nodeName===e},CLASS:function(z,e){return(" "+(z.className||z.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(D,B){var A=B[1],e=h.attrHandle[A]?h.attrHandle[A](D):D[A]!=null?D[A]:D.getAttribute(A),E=e+"",C=B[2],z=B[4];return e==null?C==="!=":C==="="?E===z:C==="*="?E.indexOf(z)>=0:C==="~="?(" "+E+" ").indexOf(z)>=0:!z?E&&e!==false:C==="!="?E!=z:C==="^="?E.indexOf(z)===0:C==="$="?E.substr(E.length-z.length)===z:C==="|="?E===z||E.substr(0,z.length+1)===z+"-":false},POS:function(C,z,A,D){var e=z[2],B=h.setFilters[e];if(B){return B(C,A,z,D)}}}};var q=h.match.POS;for(var s in h.match){h.match[s]=new RegExp(h.match[s].source+/(?![^\[]*\])(?![^\(]*\))/.source);h.leftMatch[s]=new RegExp(/(^(?:.|\r|\n)*?)/.source+h.match[s].source)}var b=function(z,e){z=Array.prototype.slice.call(z,0);if(e){e.push.apply(e,z);return e}return z};try{Array.prototype.slice.call(document.documentElement.childNodes,0)}catch(r){b=function(C,B){var z=B||[];if(g.call(C)==="[object Array]"){Array.prototype.push.apply(z,C)}else{if(typeof C.length==="number"){for(var A=0,e=C.length;A<e;A++){z.push(C[A])}}else{for(var A=0;C[A];A++){z.push(C[A])}}}return z}}var f;if(document.documentElement.compareDocumentPosition){f=function(z,e){if(!z.compareDocumentPosition||!e.compareDocumentPosition){if(z==e){u=true}return 0}var A=z.compareDocumentPosition(e)&4?-1:z===e?0:1;if(A===0){u=true}return A}}else{if("sourceIndex" in document.documentElement){f=function(z,e){if(!z.sourceIndex||!e.sourceIndex){if(z==e){u=true}return 0}var A=z.sourceIndex-e.sourceIndex;if(A===0){u=true}return A}}else{if(document.createRange){f=function(B,z){if(!B.ownerDocument||!z.ownerDocument){if(B==z){u=true}return 0}var A=B.ownerDocument.createRange(),e=z.ownerDocument.createRange();A.setStart(B,0);A.setEnd(B,0);e.setStart(z,0);e.setEnd(z,0);var C=A.compareBoundaryPoints(Range.START_TO_END,e);if(C===0){u=true}return C}}}}(function(){var z=document.createElement("div"),A="script"+(new Date).getTime();z.innerHTML="<a name='"+A+"'/>";var e=document.documentElement;e.insertBefore(z,e.firstChild);if(!!document.getElementById(A)){h.find.ID=function(C,D,E){if(typeof D.getElementById!=="undefined"&&!E){var B=D.getElementById(C[1]);return B?B.id===C[1]||typeof B.getAttributeNode!=="undefined"&&B.getAttributeNode("id").nodeValue===C[1]?[B]:undefined:[]}};h.filter.ID=function(D,B){var C=typeof D.getAttributeNode!=="undefined"&&D.getAttributeNode("id");return D.nodeType===1&&C&&C.nodeValue===B}}e.removeChild(z);e=z=null})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){h.find.TAG=function(z,D){var C=D.getElementsByTagName(z[1]);if(z[1]==="*"){var B=[];for(var A=0;C[A];A++){if(C[A].nodeType===1){B.push(C[A])}}C=B}return C}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){h.attrHandle.href=function(z){return z.getAttribute("href",2)}}e=null})();if(document.querySelectorAll){(function(){var e=d,A=document.createElement("div");A.innerHTML="<p class='TEST'></p>";if(A.querySelectorAll&&A.querySelectorAll(".TEST").length===0){return}d=function(E,D,B,C){D=D||document;if(!C&&D.nodeType===9&&!v(D)){try{return b(D.querySelectorAll(E),B)}catch(F){}}return e(E,D,B,C)};for(var z in e){d[z]=e[z]}A=null})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}h.order.splice(1,0,"CLASS");h.find.CLASS=function(z,A,B){if(typeof A.getElementsByClassName!=="undefined"&&!B){return A.getElementsByClassName(z[1])}};e=null})()}function t(z,E,D,I,F,H){var G=z=="previousSibling"&&!H;for(var B=0,A=I.length;B<A;B++){var e=I[B];if(e){if(G&&e.nodeType===1){e.sizcache=D;e.sizset=B}e=e[z];var C=false;while(e){if(e.sizcache===D){C=I[e.sizset];break}if(e.nodeType===1&&!H){e.sizcache=D;e.sizset=B}if(e.nodeName===E){C=e;break}e=e[z]}I[B]=C}}}function y(z,E,D,I,F,H){var G=z=="previousSibling"&&!H;for(var B=0,A=I.length;B<A;B++){var e=I[B];if(e){if(G&&e.nodeType===1){e.sizcache=D;e.sizset=B}e=e[z];var C=false;while(e){if(e.sizcache===D){C=I[e.sizset];break}if(e.nodeType===1){if(!H){e.sizcache=D;e.sizset=B}if(typeof E!=="string"){if(e===E){C=true;break}}else{if(d.filter(E,[e]).length>0){C=e;break}}}e=e[z]}I[B]=C}}}var n=document.compareDocumentPosition?function(z,e){return z.compareDocumentPosition(e)&16}:function(z,e){return z!==e&&(z.contains?z.contains(e):true)};var v=function(e){return e.nodeType===9&&e.documentElement.nodeName!=="HTML"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!=="HTML"};var l=function(e,F){var B=[],C="",D,A=F.nodeType?[F]:F;while((D=h.match.PSEUDO.exec(e))){C+=D[0];e=e.replace(h.match.PSEUDO,"")}e=h.relative[e]?e+"*":e;for(var E=0,z=A.length;E<z;E++){d(e,A[E],B)}return d.filter(C,B)};window.Sizzle=d})();(function(e){var f=Prototype.Selector.extendElements;function b(g,h){return f(e(g,h||document))}function d(h,g){return e.matches(g,[h]).length==1}Prototype.Selector.engine=e;Prototype.Selector.select=b;Prototype.Selector.match=d})(Sizzle);window.Sizzle=Prototype._original_property;delete Prototype._original_property;var Form={reset:function(b){b=$(b);b.reset();return b},serializeElements:function(n,f){if(typeof f!="object"){f={hash:!!f}}else{if(Object.isUndefined(f.hash)){f.hash=true}}var g,l,b=false,h=f.submit,d,e;if(f.hash){e={};d=function(o,p,q){if(p in o){if(!Object.isArray(o[p])){o[p]=[o[p]]}o[p].push(q)}else{o[p]=q}return o}}else{e="";d=function(o,p,q){return o+(o?"&":"")+encodeURIComponent(p)+"="+encodeURIComponent(q)}}return n.inject(e,function(o,p){if(!p.disabled&&p.name){g=p.name;l=$(p).getValue();if(l!=null&&p.type!="file"&&(p.type!="submit"||(!b&&h!==false&&(!h||g==h)&&(b=true)))){o=d(o,g,l)}}return o})}};Form.Methods={serialize:function(d,b){return Form.serializeElements(Form.getElements(d),b)},getElements:function(g){var h=$(g).getElementsByTagName("*"),f,b=[],e=Form.Element.Serializers;for(var d=0;f=h[d];d++){b.push(f)}return b.inject([],function(l,n){if(e[n.tagName.toLowerCase()]){l.push(Element.extend(n))}return l})},getInputs:function(l,e,f){l=$(l);var b=l.getElementsByTagName("input");if(!e&&!f){return $A(b).map(Element.extend)}for(var g=0,n=[],h=b.length;g<h;g++){var d=b[g];if((e&&d.type!=e)||(f&&d.name!=f)){continue}n.push(Element.extend(d))}return n},disable:function(b){b=$(b);Form.getElements(b).invoke("disable");return b},enable:function(b){b=$(b);Form.getElements(b).invoke("enable");return b},findFirstElement:function(d){var e=$(d).getElements().findAll(function(f){return"hidden"!=f.type&&!f.disabled});var b=e.findAll(function(f){return f.hasAttribute("tabIndex")&&f.tabIndex>=0}).sortBy(function(f){return f.tabIndex}).first();return b?b:e.find(function(f){return/^(?:input|select|textarea)$/i.test(f.tagName)})},focusFirstElement:function(d){d=$(d);var b=d.findFirstElement();if(b){b.activate()}return d},request:function(d,b){d=$(d),b=Object.clone(b||{});var f=b.parameters,e=d.readAttribute("action")||"";if(e.blank()){e=window.location.href}b.parameters=d.serialize(true);if(f){if(Object.isString(f)){f=f.toQueryParams()}Object.extend(b.parameters,f)}if(d.hasAttribute("method")&&!b.method){b.method=d.method}return new Ajax.Request(e,b)}};Form.Element={focus:function(b){$(b).focus();return b},select:function(b){$(b).select();return b}};Form.Element.Methods={serialize:function(b){b=$(b);if(!b.disabled&&b.name){var d=b.getValue();if(d!=undefined){var e={};e[b.name]=d;return Object.toQueryString(e)}}return""},getValue:function(b){b=$(b);var d=b.tagName.toLowerCase();return Form.Element.Serializers[d](b)},setValue:function(b,d){b=$(b);var e=b.tagName.toLowerCase();Form.Element.Serializers[e](b,d);return b},clear:function(b){$(b).value="";return b},present:function(b){return $(b).value!=""},activate:function(b){b=$(b);try{b.focus();if(b.select&&(b.tagName.toLowerCase()!="input"||!(/^(?:button|reset|submit)$/i.test(b.type)))){b.select()}}catch(d){}return b},disable:function(b){b=$(b);b.disabled=true;return b},enable:function(b){b=$(b);b.disabled=false;return b}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers=(function(){function d(n,o){switch(n.type.toLowerCase()){case"checkbox":case"radio":return h(n,o);default:return g(n,o)}}function h(n,o){if(Object.isUndefined(o)){return n.checked?n.value:null}else{n.checked=!!o}}function g(n,o){if(Object.isUndefined(o)){return n.value}else{n.value=o}}function b(p,s){if(Object.isUndefined(s)){return(p.type==="select-one"?e:f)(p)}var o,q,t=!Object.isArray(s);for(var n=0,r=p.length;n<r;n++){o=p.options[n];q=this.optionValue(o);if(t){if(q==s){o.selected=true;return}}else{o.selected=s.include(q)}}}function e(o){var n=o.selectedIndex;return n>=0?l(o.options[n]):null}function f(q){var n,r=q.length;if(!r){return null}for(var p=0,n=[];p<r;p++){var o=q.options[p];if(o.selected){n.push(l(o))}}return n}function l(n){return Element.hasAttribute(n,"value")?n.value:n.text}return{input:d,inputSelector:h,textarea:g,select:b,selectOne:e,selectMany:f,optionValue:l,button:g}})();Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function($super,b,d,e){$super(e,d);this.element=$(b);this.lastValue=this.getValue()},execute:function(){var b=this.getValue();if(Object.isString(this.lastValue)&&Object.isString(b)?this.lastValue!=b:String(this.lastValue)!=String(b)){this.callback(this.element,b);this.lastValue=b}}});Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){return Form.serialize(this.element)}});Abstract.EventObserver=Class.create({initialize:function(b,d){this.element=$(b);this.callback=d;this.lastValue=this.getValue();if(this.element.tagName.toLowerCase()=="form"){this.registerFormCallbacks()}else{this.registerCallback(this.element)}},onElementEvent:function(){var b=this.getValue();if(this.lastValue!=b){this.callback(this.element,b);this.lastValue=b}},registerFormCallbacks:function(){Form.getElements(this.element).each(this.registerCallback,this)},registerCallback:function(b){if(b.type){switch(b.type.toLowerCase()){case"checkbox":case"radio":Event.observe(b,"click",this.onElementEvent.bind(this));break;default:Event.observe(b,"change",this.onElementEvent.bind(this));break}}}});Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.Element.getValue(this.element)}});Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){return Form.serialize(this.element)}});(function(){var J={KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{}};var h=document.documentElement;var K="onmouseenter" in h&&"onmouseleave" in h;var b=function(L){return false};if(window.attachEvent){if(window.addEventListener){b=function(L){return !(L instanceof window.Event)}}else{b=function(L){return true}}}var y;function H(M,L){return M.which?(M.which===L+1):(M.button===L)}var u={0:1,1:4,2:2};function F(M,L){return M.button===u[L]}function I(M,L){switch(L){case 0:return M.which==1&&!M.metaKey;case 1:return M.which==2||(M.which==1&&M.metaKey);case 2:return M.which==3;default:return false}}if(window.attachEvent){if(!window.addEventListener){y=F}else{y=function(M,L){return b(M)?F(M,L):H(M,L)}}}else{if(Prototype.Browser.WebKit){y=I}else{y=H}}function C(L){return y(L,0)}function A(L){return y(L,1)}function t(L){return y(L,2)}function f(N){N=J.extend(N);var M=N.target,L=N.type,O=N.currentTarget;if(O&&O.tagName){if(L==="load"||L==="error"||(L==="click"&&O.tagName.toLowerCase()==="input"&&O.type==="radio")){M=O}}if(M.nodeType==Node.TEXT_NODE){M=M.parentNode}return Element.extend(M)}function v(M,N){var L=J.element(M);if(!N){return L}while(L){if(Object.isElement(L)&&Prototype.Selector.match(L,N)){return Element.extend(L)}L=L.parentNode}}function z(L){return{x:e(L),y:d(L)}}function e(N){var M=document.documentElement,L=document.body||{scrollLeft:0};return N.pageX||(N.clientX+(M.scrollLeft||L.scrollLeft)-(M.clientLeft||0))}function d(N){var M=document.documentElement,L=document.body||{scrollTop:0};return N.pageY||(N.clientY+(M.scrollTop||L.scrollTop)-(M.clientTop||0))}function w(L){J.extend(L);L.preventDefault();L.stopPropagation();L.stopped=true}J.Methods={isLeftClick:C,isMiddleClick:A,isRightClick:t,element:f,findElement:v,pointer:z,pointerX:e,pointerY:d,stop:w};var E=Object.keys(J.Methods).inject({},function(L,M){L[M]=J.Methods[M].methodize();return L});if(window.attachEvent){function o(M){var L;switch(M.type){case"mouseover":case"mouseenter":L=M.fromElement;break;case"mouseout":case"mouseleave":L=M.toElement;break;default:return null}return Element.extend(L)}var B={stopPropagation:function(){this.cancelBubble=true},preventDefault:function(){this.returnValue=false},inspect:function(){return"[object Event]"}};J.extend=function(M,L){if(!M){return false}if(!b(M)){return M}if(M._extendedByPrototype){return M}M._extendedByPrototype=Prototype.emptyFunction;var N=J.pointer(M);Object.extend(M,{target:M.srcElement||L,relatedTarget:o(M),pageX:N.x,pageY:N.y});Object.extend(M,E);Object.extend(M,B);return M}}else{J.extend=Prototype.K}if(window.addEventListener){J.prototype=window.Event.prototype||document.createEvent("HTMLEvents").__proto__;Object.extend(J.prototype,E)}function s(P,O,Q){var N=Element.retrieve(P,"prototype_event_registry");if(Object.isUndefined(N)){g.push(P);N=Element.retrieve(P,"prototype_event_registry",$H())}var L=N.get(O);if(Object.isUndefined(L)){L=[];N.set(O,L)}if(L.pluck("handler").include(Q)){return false}var M;if(O.include(":")){M=function(R){if(Object.isUndefined(R.eventName)){return false}if(R.eventName!==O){return false}J.extend(R,P);Q.call(P,R)}}else{if(!K&&(O==="mouseenter"||O==="mouseleave")){if(O==="mouseenter"||O==="mouseleave"){M=function(S){J.extend(S,P);var R=S.relatedTarget;while(R&&R!==P){try{R=R.parentNode}catch(T){R=P}}if(R===P){return}Q.call(P,S)}}}else{M=function(R){J.extend(R,P);Q.call(P,R)}}}M.handler=Q;L.push(M);return M}function n(){for(var L=0,M=g.length;L<M;L++){J.stopObserving(g[L]);g[L]=null}}var g=[];if(Prototype.Browser.IE){window.attachEvent("onunload",n)}if(Prototype.Browser.WebKit){window.addEventListener("unload",Prototype.emptyFunction,false)}var r=Prototype.K,l={mouseenter:"mouseover",mouseleave:"mouseout"};if(!K){r=function(L){return(l[L]||L)}}function D(O,N,P){O=$(O);var M=s(O,N,P);if(!M){return O}if(N.include(":")){if(O.addEventListener){O.addEventListener("dataavailable",M,false)}else{O.attachEvent("ondataavailable",M);O.attachEvent("onlosecapture",M)}}else{var L=r(N);if(O.addEventListener){O.addEventListener(L,M,false)}else{O.attachEvent("on"+L,M)}}return O}function q(R,O,S){R=$(R);var N=Element.retrieve(R,"prototype_event_registry");if(!N){return R}if(!O){N.each(function(U){var T=U.key;q(R,T)});return R}var P=N.get(O);if(!P){return R}if(!S){P.each(function(T){q(R,O,T.handler)});return R}var Q=P.length,M;while(Q--){if(P[Q].handler===S){M=P[Q];break}}if(!M){return R}if(O.include(":")){if(R.removeEventListener){R.removeEventListener("dataavailable",M,false)}else{R.detachEvent("ondataavailable",M);R.detachEvent("onlosecapture",M)}}else{var L=r(O);if(R.removeEventListener){R.removeEventListener(L,M,false)}else{R.detachEvent("on"+L,M)}}N.set(O,P.without(M));return R}function G(O,N,M,L){O=$(O);if(Object.isUndefined(L)){L=true}if(O==document&&document.createEvent&&!O.dispatchEvent){O=document.documentElement}var P;if(document.createEvent){P=document.createEvent("HTMLEvents");P.initEvent("dataavailable",L,true)}else{P=document.createEventObject();P.eventType=L?"ondataavailable":"onlosecapture"}P.eventName=N;P.memo=M||{};if(document.createEvent){O.dispatchEvent(P)}else{O.fireEvent(P.eventType,P)}return J.extend(P)}J.Handler=Class.create({initialize:function(N,M,L,O){this.element=$(N);this.eventName=M;this.selector=L;this.callback=O;this.handler=this.handleEvent.bind(this)},start:function(){J.observe(this.element,this.eventName,this.handler);return this},stop:function(){J.stopObserving(this.element,this.eventName,this.handler);return this},handleEvent:function(M){var L=J.findElement(M,this.selector);if(L){this.callback.call(this.element,M,L)}}});function p(N,M,L,O){N=$(N);if(Object.isFunction(L)&&Object.isUndefined(O)){O=L,L=null}return new J.Handler(N,M,L,O).start()}Object.extend(J,J.Methods);Object.extend(J,{fire:G,observe:D,stopObserving:q,on:p});Element.addMethods({fire:G,observe:D,stopObserving:q,on:p});Object.extend(document,{fire:G.methodize(),observe:D.methodize(),stopObserving:q.methodize(),on:p.methodize(),loaded:false});if(window.Event){Object.extend(window.Event,J)}else{window.Event=J}})();(function(){var e;function b(){if(document.loaded){return}if(e){window.clearTimeout(e)}document.loaded=true;document.fire("dom:loaded")}function d(){if(document.readyState==="complete"){document.stopObserving("readystatechange",d);b()}}if(document.addEventListener){document.addEventListener("DOMContentLoaded",b,false)}else{document.observe("readystatechange",d);if(window==top){var e=window.setInterval(function(){try{document.documentElement.doScroll("left")}catch(f){return}window.clearInterval(e);b()},5)}}Event.observe(window,"load",b)})();Element.addMethods();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(b,d){return Element.insert(b,{before:d})},Top:function(b,d){return Element.insert(b,{top:d})},Bottom:function(b,d){return Element.insert(b,{bottom:d})},After:function(b,d){return Element.insert(b,{after:d})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(d,b,e){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(d,b,e)}this.xcomp=b;this.ycomp=e;this.offset=Element.cumulativeOffset(d);return(e>=this.offset[1]&&e<this.offset[1]+d.offsetHeight&&b>=this.offset[0]&&b<this.offset[0]+d.offsetWidth)},withinIncludingScrolloffsets:function(d,b,f){var e=Element.cumulativeScrollOffset(d);this.xcomp=b+e[0]-this.deltaX;this.ycomp=f+e[1]-this.deltaY;this.offset=Element.cumulativeOffset(d);return(this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+d.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+d.offsetWidth)},overlap:function(d,b){if(!d){return 0}if(d=="vertical"){return((this.offset[1]+b.offsetHeight)-this.ycomp)/b.offsetHeight}if(d=="horizontal"){return((this.offset[0]+b.offsetWidth)-this.xcomp)/b.offsetWidth}},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(b){Position.prepare();return Element.absolutize(b)},relativize:function(b){Position.prepare();return Element.relativize(b)},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(d,e,b){b=b||{};return Element.clonePosition(e,d,b)}};if(!document.getElementsByClassName){document.getElementsByClassName=function(d){function b(e){return e.blank()?null:"[contains(concat(' ', @class, ' '), ' "+e+" ')]"}d.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(e,g){g=g.toString().strip();var f=/\s/.test(g)?$w(g).map(b).join(""):b(g);return f?document._getElementsByXPath(".//*"+f,e):[]}:function(g,h){h=h.toString().strip();var l=[],n=(/\s/.test(h)?$w(h):null);if(!n&&!h){return l}var e=$(g).getElementsByTagName("*");h=" "+h+" ";for(var f=0,p,o;p=e[f];f++){if(p.className&&(o=" "+p.className+" ")&&(o.include(h)||(n&&n.all(function(q){return !q.toString().blank()&&o.include(" "+q+" ")})))){l.push(Element.extend(p))}}return l};return function(f,e){return $(e||document.body).getElementsByClassName(f)}}(Element.Methods)}Element.ClassNames=Class.create();Element.ClassNames.prototype={initialize:function(b){this.element=$(b)},_each:function(b){this.element.className.split(/\s+/).select(function(d){return d.length>0})._each(b)},set:function(b){this.element.className=b},add:function(b){if(this.include(b)){return}this.set($A(this).concat(b).join(" "))},remove:function(b){if(!this.include(b)){return}this.set($A(this).without(b).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);(function(){window.Selector=Class.create({initialize:function(b){this.expression=b.strip()},findElements:function(b){return Prototype.Selector.select(this.expression,b)},match:function(b){return Prototype.Selector.match(b,this.expression)},toString:function(){return this.expression},inspect:function(){return"#<Selector: "+this.expression+">"}});Object.extend(Selector,{matchElements:function(h,l){var b=Prototype.Selector.match,f=[];for(var e=0,g=h.length;e<g;e++){var d=h[e];if(b(d,l)){f.push(Element.extend(d))}}return f},findElement:function(h,l,d){d=d||0;var b=0,f;for(var e=0,g=h.length;e<g;e++){f=h[e];if(Prototype.Selector.match(f,l)&&d===b++){return Element.extend(f)}}},findChildElements:function(d,e){var b=e.toArray().join(", ");return Prototype.Selector.select(b,d||document)}})})();var Window=Class.create();Window.keepMultiModalWindow=false;Window.hasEffectLib=(typeof Effect!="undefined");Window.resizeEffectDuration=0.4;Window.prototype={initialize:function(){var e;var d=0;if(arguments.length>0){if(typeof arguments[0]=="string"){e=arguments[0];d=1}else{e=arguments[0]?arguments[0].id:null}}if(!e){e="window_"+new Date().getTime()}if($(e)){alert("Window "+e+" is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor")}this.options=Object.extend({className:"dialog",windowClassName:null,blurClassName:null,minWidth:100,minHeight:20,resizable:true,closable:true,minimizable:true,maximizable:true,draggable:true,userData:null,showEffect:(Window.hasEffectLib?Effect.Appear:Element.show),hideEffect:(Window.hasEffectLib?Effect.Fade:Element.hide),showEffectOptions:{},hideEffectOptions:{},effectOptions:null,parent:document.body,title:" ",url:null,onload:Prototype.emptyFunction,width:200,height:300,opacity:1,recenterAuto:true,wiredDrag:false,closeOnEsc:true,closeCallback:null,destroyOnClose:false,gridX:1,gridY:1},arguments[d]||{});if(this.options.blurClassName){this.options.focusClassName=this.options.className}if(typeof this.options.top=="undefined"&&typeof this.options.bottom=="undefined"){this.options.top=this._round(Math.random()*500,this.options.gridY)}if(typeof this.options.left=="undefined"&&typeof this.options.right=="undefined"){this.options.left=this._round(Math.random()*500,this.options.gridX)}if(this.options.effectOptions){Object.extend(this.options.hideEffectOptions,this.options.effectOptions);Object.extend(this.options.showEffectOptions,this.options.effectOptions);if(this.options.showEffect==Element.Appear){this.options.showEffectOptions.to=this.options.opacity}}if(Window.hasEffectLib){if(this.options.showEffect==Effect.Appear){this.options.showEffectOptions.to=this.options.opacity}if(this.options.hideEffect==Effect.Fade){this.options.hideEffectOptions.from=this.options.opacity}}if(this.options.hideEffect==Element.hide){this.options.hideEffect=function(){Element.hide(this.element);if(this.options.destroyOnClose){this.destroy()}}.bind(this)}if(this.options.parent!=document.body){this.options.parent=$(this.options.parent)}this.element=this._createWindow(e);this.element.win=this;this.eventMouseDown=this._initDrag.bindAsEventListener(this);this.eventMouseUp=this._endDrag.bindAsEventListener(this);this.eventMouseMove=this._updateDrag.bindAsEventListener(this);this.eventOnLoad=this._getWindowBorderSize.bindAsEventListener(this);this.eventMouseDownContent=this.toFront.bindAsEventListener(this);this.eventResize=this._recenter.bindAsEventListener(this);this.eventKeyUp=this._keyUp.bindAsEventListener(this);this.topbar=$(this.element.id+"_top");this.bottombar=$(this.element.id+"_bottom");this.content=$(this.element.id+"_content");Event.observe(this.topbar,"mousedown",this.eventMouseDown);Event.observe(this.bottombar,"mousedown",this.eventMouseDown);Event.observe(this.content,"mousedown",this.eventMouseDownContent);Event.observe(window,"load",this.eventOnLoad);Event.observe(window,"resize",this.eventResize);Event.observe(window,"scroll",this.eventResize);Event.observe(document,"keyup",this.eventKeyUp);Event.observe(this.options.parent,"scroll",this.eventResize);if(this.options.draggable){var b=this;[this.topbar,this.topbar.up().previous(),this.topbar.up().next()].each(function(f){f.observe("mousedown",b.eventMouseDown);f.addClassName("top_draggable")});[this.bottombar.up(),this.bottombar.up().previous(),this.bottombar.up().next()].each(function(f){f.observe("mousedown",b.eventMouseDown);f.addClassName("bottom_draggable")})}if(this.options.resizable){this.sizer=$(this.element.id+"_sizer");Event.observe(this.sizer,"mousedown",this.eventMouseDown)}this.useLeft=null;this.useTop=null;if(typeof this.options.left!="undefined"){this.element.setStyle({left:parseFloat(this.options.left)+"px"});this.useLeft=true}else{this.element.setStyle({right:parseFloat(this.options.right)+"px"});this.useLeft=false}if(typeof this.options.top!="undefined"){this.element.setStyle({top:parseFloat(this.options.top)+"px"});this.useTop=true}else{this.element.setStyle({bottom:parseFloat(this.options.bottom)+"px"});this.useTop=false}this.storedLocation=null;this.setOpacity(this.options.opacity);if(this.options.zIndex){this.setZIndex(this.options.zIndex)}else{this.setZIndex(this.getMaxZIndex())}if(this.options.destroyOnClose){this.setDestroyOnClose(true)}this._getWindowBorderSize();this.width=this.options.width;this.height=this.options.height;this.visible=false;this.constraint=false;this.constraintPad={top:0,left:0,bottom:0,right:0};if(this.width&&this.height){this.setSize(this.options.width,this.options.height)}this.setTitle(this.options.title);Windows.register(this)},getMaxZIndex:function(){var b=0,d;var g=document.body.childNodes;for(d=0;d<g.length;d++){var e=g[d];var f=e.nodeType==1?parseInt(e.style.zIndex,10)||0:0;if(f<10000){b=Math.max(b,f)}}return b+10},destroy:function(){this._notify("onDestroy");Event.stopObserving(this.topbar,"mousedown",this.eventMouseDown);Event.stopObserving(this.bottombar,"mousedown",this.eventMouseDown);Event.stopObserving(this.content,"mousedown",this.eventMouseDownContent);Event.stopObserving(window,"load",this.eventOnLoad);Event.stopObserving(window,"resize",this.eventResize);Event.stopObserving(window,"scroll",this.eventResize);Event.stopObserving(this.content,"load",this.options.onload);Event.stopObserving(document,"keyup",this.eventKeyUp);if(this._oldParent){var e=this.getContent();var b=null;for(var d=0;d<e.childNodes.length;d++){b=e.childNodes[d];if(b.nodeType==1){break}b=null}if(b){this._oldParent.appendChild(b)}this._oldParent=null}if(this.sizer){Event.stopObserving(this.sizer,"mousedown",this.eventMouseDown)}if(this.options.url){this.content.src=null}if(this.iefix){Element.remove(this.iefix)}Element.remove(this.element);Windows.unregister(this)},setCloseCallback:function(b){this.options.closeCallback=b},getContent:function(){return this.content},setContent:function(n,l,e){var b=$(n);if(null==b){throw"Unable to find element '"+n+"' in DOM"}this._oldParent=b.parentNode;var h=null;var g=null;if(l){h=Element.getDimensions(b)}if(e){g=Position.cumulativeOffset(b)}var f=this.getContent();this.setHTMLContent("");f=this.getContent();f.appendChild(b);b.show();if(l){this.setSize(h.width,h.height)}if(e){this.setLocation(g[1]-this.heightN,g[0]-this.widthW)}},setHTMLContent:function(b){if(this.options.url){this.content.src=null;this.options.url=null;var d='<div id="'+this.getId()+'_content" class="'+this.options.className+'_content"> </div>';$(this.getId()+"_table_content").innerHTML=d;this.content=$(this.element.id+"_content")}this.getContent().innerHTML=b},setAjaxContent:function(d,b,f,e){this.showFunction=f?"showCenter":"show";this.showModal=e||false;b=b||{};this.setHTMLContent("");this.onComplete=b.onComplete;if(!this._onCompleteHandler){this._onCompleteHandler=this._setAjaxContent.bind(this)}b.onComplete=this._onCompleteHandler;new Ajax.Request(d,b);b.onComplete=this.onComplete},_setAjaxContent:function(b){Element.update(this.getContent(),b.responseText);if(this.onComplete){this.onComplete(b)}this.onComplete=null;this[this.showFunction](this.showModal)},setURL:function(b){if(this.options.url){this.content.src=null}this.options.url=b;var d="<iframe frameborder='0' name='"+this.getId()+"_content' id='"+this.getId()+"_content' src='"+b+"' width='"+this.width+"' height='"+this.height+"'> </iframe>";$(this.getId()+"_table_content").innerHTML=d;this.content=$(this.element.id+"_content")},getURL:function(){return this.options.url?this.options.url:null},refresh:function(){if(this.options.url){$(this.element.getAttribute("id")+"_content").src=this.options.url}},setCookie:function(d,e,t,g,b){d=d||this.element.id;this.cookie=[d,e,t,g,b];var r=WindowUtilities.getCookie(d);if(r){var s=r.split(",");var p=s[0].split(":");var o=s[1].split(":");var q=parseFloat(s[2]),l=parseFloat(s[3]);var n=s[4];var f=s[5];this.setSize(q,l);if(n=="true"){this.doMinimize=true}else{if(f=="true"){this.doMaximize=true}}this.useLeft=p[0]=="l";this.useTop=o[0]=="t";this.element.setStyle(this.useLeft?{left:p[1]}:{right:p[1]});this.element.setStyle(this.useTop?{top:o[1]}:{bottom:o[1]})}},getId:function(){return this.element.id},setDestroyOnClose:function(){this.options.destroyOnClose=true},setConstraint:function(b,d){this.constraint=b;this.constraintPad=Object.extend(this.constraintPad,d||{});if(this.useTop&&this.useLeft){this.setLocation(parseFloat(this.element.style.top),parseFloat(this.element.style.left))}},_initDrag:function(d){if(Event.element(d)==this.sizer&&this.isMinimized()){return}if(Event.element(d)!=this.sizer&&this.isMaximized()){return}if(Prototype.Browser.IE&&this.heightN==0){this._getWindowBorderSize()}this.pointer=[this._round(Event.pointerX(d),this.options.gridX),this._round(Event.pointerY(d),this.options.gridY)];if(this.options.wiredDrag){this.currentDrag=this._createWiredElement()}else{this.currentDrag=this.element}if(Event.element(d)==this.sizer){this.doResize=true;this.widthOrg=this.width;this.heightOrg=this.height;this.bottomOrg=parseFloat(this.element.getStyle("bottom"));this.rightOrg=parseFloat(this.element.getStyle("right"));this._notify("onStartResize")}else{this.doResize=false;var b=$(this.getId()+"_close");if(b&&Position.within(b,this.pointer[0],this.pointer[1])){this.currentDrag=null;return}this.toFront();if(!this.options.draggable){return}this._notify("onStartMove")}Event.observe(document,"mouseup",this.eventMouseUp,false);Event.observe(document,"mousemove",this.eventMouseMove,false);WindowUtilities.disableScreen("__invisible__","__invisible__",this.overlayOpacity);document.body.ondrag=function(){return false};document.body.onselectstart=function(){return false};this.currentDrag.show();Event.stop(d)},_round:function(d,b){return b==1?d:d=Math.floor(d/b)*b},_updateDrag:function(d){var b=[this._round(Event.pointerX(d),this.options.gridX),this._round(Event.pointerY(d),this.options.gridY)];var q=b[0]-this.pointer[0];var p=b[1]-this.pointer[1];if(this.doResize){var o=this.widthOrg+q;var f=this.heightOrg+p;q=this.width-this.widthOrg;p=this.height-this.heightOrg;if(this.useLeft){o=this._updateWidthConstraint(o)}else{this.currentDrag.setStyle({right:(this.rightOrg-q)+"px"})}if(this.useTop){f=this._updateHeightConstraint(f)}else{this.currentDrag.setStyle({bottom:(this.bottomOrg-p)+"px"})}this.setSize(o,f);this._notify("onResize")}else{this.pointer=b;if(this.useLeft){var e=parseFloat(this.currentDrag.getStyle("left"))+q;var n=this._updateLeftConstraint(e);this.pointer[0]+=n-e;this.currentDrag.setStyle({left:n+"px"})}else{this.currentDrag.setStyle({right:parseFloat(this.currentDrag.getStyle("right"))-q+"px"})}if(this.useTop){var l=parseFloat(this.currentDrag.getStyle("top"))+p;var g=this._updateTopConstraint(l);this.pointer[1]+=g-l;this.currentDrag.setStyle({top:g+"px"})}else{this.currentDrag.setStyle({bottom:parseFloat(this.currentDrag.getStyle("bottom"))-p+"px"})}this._notify("onMove")}if(this.iefix){this._fixIEOverlapping()}this._removeStoreLocation();Event.stop(d)},_endDrag:function(b){WindowUtilities.enableScreen("__invisible__");if(this.doResize){this._notify("onEndResize")}else{this._notify("onEndMove")}Event.stopObserving(document,"mouseup",this.eventMouseUp,false);Event.stopObserving(document,"mousemove",this.eventMouseMove,false);Event.stop(b);this._hideWiredElement();this._saveCookie();document.body.ondrag=null;document.body.onselectstart=null},_updateLeftConstraint:function(d){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowWidth:this.options.parent.getDimensions().width;if(d<this.constraintPad.left){d=this.constraintPad.left}if(d+this.width+this.widthE+this.widthW>b-this.constraintPad.right){d=b-this.constraintPad.right-this.width-this.widthE-this.widthW}}return d},_updateTopConstraint:function(e){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowHeight:this.options.parent.getDimensions().height;var d=this.height+this.heightN+this.heightS;if(e<this.constraintPad.top){e=this.constraintPad.top}if(e+d>b-this.constraintPad.bottom){e=b-this.constraintPad.bottom-d}}return e},_updateWidthConstraint:function(b){if(this.constraint&&this.useLeft&&this.useTop){var d=this.options.parent==document.body?WindowUtilities.getPageSize().windowWidth:this.options.parent.getDimensions().width;var e=parseFloat(this.element.getStyle("left"));if(e+b+this.widthE+this.widthW>d-this.constraintPad.right){b=d-this.constraintPad.right-e-this.widthE-this.widthW}}return b},_updateHeightConstraint:function(d){if(this.constraint&&this.useLeft&&this.useTop){var b=this.options.parent==document.body?WindowUtilities.getPageSize().windowHeight:this.options.parent.getDimensions().height;var e=parseFloat(this.element.getStyle("top"));if(e+d+this.heightN+this.heightS>b-this.constraintPad.bottom){d=b-this.constraintPad.bottom-e-this.heightN-this.heightS}}return d},_createWindow:function(b){var h=this.options.className;var f=document.createElement("div");f.setAttribute("id",b);f.className="dialog";if(this.options.windowClassName){f.className+=" "+this.options.windowClassName}var g;if(this.options.url){g='<iframe frameborder="0" name="'+b+'_content" id="'+b+'_content" src="'+this.options.url+'"> </iframe>'}else{g='<div id="'+b+'_content" class="'+h+'_content"> </div>'}var l=this.options.closable?"<div class='"+h+"_close' id='"+b+"_close' onclick='Windows.close(\""+b+"\", event)'> </div>":"";var n=this.options.minimizable?"<div class='"+h+"_minimize' id='"+b+"_minimize' onclick='Windows.minimize(\""+b+"\", event)'> </div>":"";var o=this.options.maximizable?"<div class='"+h+"_maximize' id='"+b+"_maximize' onclick='Windows.maximize(\""+b+"\", event)'> </div>":"";var e=this.options.resizable?"class='"+h+"_sizer' id='"+b+"_sizer'":"class='"+h+"_se'";var d="../themes/default/blank.gif";f.innerHTML=l+n+o+" <a href='#' id='"+b+"_focus_anchor'><!-- --></a> <table id='"+b+"_row1' class=\"top table_window\"> <tr> <td class='"+h+"_nw'></td> <td class='"+h+"_n'><div id='"+b+"_top' class='"+h+"_title title_window'>"+this.options.title+"</div></td> <td class='"+h+"_ne'></td> </tr> </table> <table id='"+b+"_row2' class=\"mid table_window\"> <tr> <td class='"+h+"_w'></td> <td id='"+b+"_table_content' class='"+h+"_content' valign='top'>"+g+"</td> <td class='"+h+"_e'></td> </tr> </table> <table id='"+b+"_row3' class=\"bot table_window\"> <tr> <td class='"+h+"_sw'></td> <td class='"+h+"_s'><div id='"+b+"_bottom' class='status_bar'><span style='float:left; width:1px; height:1px'></span></div></td> <td "+e+"></td> </tr> </table> ";Element.hide(f);this.options.parent.insertBefore(f,this.options.parent.firstChild);Event.observe($(b+"_content"),"load",this.options.onload);return f},changeClassName:function(b){var d=this.options.className;var e=this.getId();$A(["_close","_minimize","_maximize","_sizer","_content"]).each(function(f){this._toggleClassName($(e+f),d+f,b+f)}.bind(this));this._toggleClassName($(e+"_top"),d+"_title",b+"_title");$$("#"+e+" td").each(function(f){f.className=f.className.sub(d,b)});this.options.className=b},_toggleClassName:function(e,d,b){if(e){e.removeClassName(d);e.addClassName(b)}},setLocation:function(f,d){f=this._updateTopConstraint(f);d=this._updateLeftConstraint(d);var b=this.currentDrag||this.element;b.setStyle({top:f+"px"});b.setStyle({left:d+"px"});this.useLeft=true;this.useTop=true},getLocation:function(){var b={};if(this.useTop){b=Object.extend(b,{top:this.element.getStyle("top")})}else{b=Object.extend(b,{bottom:this.element.getStyle("bottom")})}if(this.useLeft){b=Object.extend(b,{left:this.element.getStyle("left")})}else{b=Object.extend(b,{right:this.element.getStyle("right")})}return b},getSize:function(){return{width:this.width,height:this.height}},setSize:function(f,d,b){f=parseFloat(f);d=parseFloat(d);if(!this.minimized&&f<this.options.minWidth){f=this.options.minWidth}if(!this.minimized&&d<this.options.minHeight){d=this.options.minHeight}if(this.options.maxHeight&&d>this.options.maxHeight){d=this.options.maxHeight}if(this.options.maxWidth&&f>this.options.maxWidth){f=this.options.maxWidth}if(this.useTop&&this.useLeft&&Window.hasEffectLib&&Effect.ResizeWindow&&b){new Effect.ResizeWindow(this,null,null,f,d,{duration:Window.resizeEffectDuration})}else{this.width=f;this.height=d;var h=this.currentDrag?this.currentDrag:this.element;h.setStyle({width:f+this.widthW+this.widthE+"px"});h.setStyle({height:d+this.heightN+this.heightS+"px"});if(!this.currentDrag||this.currentDrag==this.element){var g=$(this.element.id+"_content");g.setStyle({height:d+"px"});g.setStyle({width:f+"px"})}}},updateHeight:function(){this.setSize(this.width,this.content.scrollHeight,true)},updateWidth:function(){this.setSize(this.content.scrollWidth,this.height,true)},toFront:function(){if(this.element.style.zIndex<Windows.maxZIndex){this.setZIndex(Windows.maxZIndex+1)}if(this.iefix){this._fixIEOverlapping()}},getBounds:function(d){if(!this.width||!this.height||!this.visible){this.computeBounds()}var b=this.width;var e=this.height;if(!d){b+=this.widthW+this.widthE;e+=this.heightN+this.heightS}var f=Object.extend(this.getLocation(),{width:b+"px",height:e+"px"});return f},computeBounds:function(){if(!this.width||!this.height){var b=WindowUtilities._computeSize(this.content.innerHTML,this.content.id,this.width,this.height,0,this.options.className);if(this.height){this.width=b+5}else{this.height=b+5}}this.setSize(this.width,this.height);if(this.centered){this._center(this.centerTop,this.centerLeft)}},show:function(d){this.visible=true;if(d){if(typeof this.overlayOpacity=="undefined"){var b=this;setTimeout(function(){b.show(d)},10);return}Windows.addModalWindow(this);this.modal=true;this.setZIndex(Windows.maxZIndex+1);Windows.unsetOverflow(this)}else{if(!this.element.style.zIndex){this.setZIndex(Windows.maxZIndex+1)}}if(this.oldStyle){this.getContent().setStyle({overflow:this.oldStyle})}this.computeBounds();this._notify("onBeforeShow");if(this.options.showEffect!=Element.show&&this.options.showEffectOptions){this.options.showEffect(this.element,this.options.showEffectOptions)}else{this.options.showEffect(this.element)}this._checkIEOverlapping();WindowUtilities.focusedWindow=this;this._notify("onShow");$(this.element.id+"_focus_anchor").focus()},showCenter:function(b,e,d){this.centered=true;this.centerTop=e;this.centerLeft=d;this.show(b)},isVisible:function(){return this.visible},_center:function(e,d){var f=WindowUtilities.getWindowScroll(this.options.parent);var b=WindowUtilities.getPageSize(this.options.parent);if(typeof e=="undefined"){e=(b.windowHeight-(this.height+this.heightN+this.heightS))/2}e+=f.top;if(typeof d=="undefined"){d=(b.windowWidth-(this.width+this.widthW+this.widthE))/2}d+=f.left;this.setLocation(e,d);this.toFront()},_recenter:function(d){if(this.centered){var b=WindowUtilities.getPageSize(this.options.parent);var e=WindowUtilities.getWindowScroll(this.options.parent);if(this.pageSize&&this.pageSize.windowWidth==b.windowWidth&&this.pageSize.windowHeight==b.windowHeight&&this.windowScroll.left==e.left&&this.windowScroll.top==e.top){return}this.pageSize=b;this.windowScroll=e;if($("overlay_modal")){$("overlay_modal").setStyle({height:(b.pageHeight+"px")})}if(this.options.recenterAuto){this._center(this.centerTop,this.centerLeft)}}},hide:function(){this.visible=false;if(this.modal){Windows.removeModalWindow(this);Windows.resetOverflow()}this.oldStyle=this.getContent().getStyle("overflow")||"auto";this.getContent().setStyle({overflow:"hidden"});this.options.hideEffect(this.element,this.options.hideEffectOptions);if(this.iefix){this.iefix.hide()}if(!this.doNotNotifyHide){this._notify("onHide")}},close:function(){if(this.visible){if(this.options.closeCallback&&!this.options.closeCallback(this)){return}if(this.options.destroyOnClose){var b=this.destroy.bind(this);if(this.options.hideEffectOptions.afterFinish){var d=this.options.hideEffectOptions.afterFinish;this.options.hideEffectOptions.afterFinish=function(){d();b()}}else{this.options.hideEffectOptions.afterFinish=function(){b()}}}Windows.updateFocusedWindow();this.doNotNotifyHide=true;this.hide();this.doNotNotifyHide=false;this._notify("onClose")}},minimize:function(){if(this.resizing){return}var b=$(this.getId()+"_row2");if(!this.minimized){this.minimized=true;var f=b.getDimensions().height;this.r2Height=f;var e=this.element.getHeight()-f;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,null,null,null,this.height-f,{duration:Window.resizeEffectDuration})}else{this.height-=f;this.element.setStyle({height:e+"px"});b.hide()}if(!this.useTop){var d=parseFloat(this.element.getStyle("bottom"));this.element.setStyle({bottom:(d+f)+"px"})}}else{this.minimized=false;var f=this.r2Height;this.r2Height=null;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,null,null,null,this.height+f,{duration:Window.resizeEffectDuration})}else{var e=this.element.getHeight()+f;this.height+=f;this.element.setStyle({height:e+"px"});b.show()}if(!this.useTop){var d=parseFloat(this.element.getStyle("bottom"));this.element.setStyle({bottom:(d-f)+"px"})}this.toFront()}this._notify("onMinimize");this._saveCookie()},maximize:function(){if(this.isMinimized()||this.resizing){return}if(Prototype.Browser.IE&&this.heightN==0){this._getWindowBorderSize()}if(this.storedLocation!=null){this._restoreLocation();if(this.iefix){this.iefix.hide()}}else{this._storeLocation();Windows.unsetOverflow(this);var l=WindowUtilities.getWindowScroll(this.options.parent);var d=WindowUtilities.getPageSize(this.options.parent);var h=l.left;var g=l.top;if(this.options.parent!=document.body){l={top:0,left:0,bottom:0,right:0};var f=this.options.parent.getDimensions();d.windowWidth=f.width;d.windowHeight=f.height;g=0;h=0}if(this.constraint){d.windowWidth-=Math.max(0,this.constraintPad.left)+Math.max(0,this.constraintPad.right);d.windowHeight-=Math.max(0,this.constraintPad.top)+Math.max(0,this.constraintPad.bottom);h+=Math.max(0,this.constraintPad.left);g+=Math.max(0,this.constraintPad.top)}var e=d.windowWidth-this.widthW-this.widthE;var b=d.windowHeight-this.heightN-this.heightS;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,g,h,e,b,{duration:Window.resizeEffectDuration})}else{this.setSize(e,b);this.element.setStyle(this.useLeft?{left:h}:{right:h});this.element.setStyle(this.useTop?{top:g}:{bottom:g})}this.toFront();if(this.iefix){this._fixIEOverlapping()}}this._notify("onMaximize");this._saveCookie()},isMinimized:function(){return this.minimized},isMaximized:function(){return(this.storedLocation!=null)},setOpacity:function(b){if(Element.setOpacity){Element.setOpacity(this.element,b)}},setZIndex:function(b){this.element.setStyle({zIndex:b});Windows.updateZindex(b,this)},setTitle:function(b){if(!b||b==""){b=" "}Element.update(this.element.id+"_top",b)},getTitle:function(){return $(this.element.id+"_top").innerHTML},setStatusBar:function(d){var b=$(this.getId()+"_bottom");if(typeof(d)=="object"){if(this.bottombar.firstChild){this.bottombar.replaceChild(d,this.bottombar.firstChild)}else{this.bottombar.appendChild(d)}}else{this.bottombar.innerHTML=d}},_checkIEOverlapping:function(){if(!this.iefix&&(navigator.appVersion.indexOf("MSIE")>0)&&(navigator.userAgent.indexOf("Opera")<0)&&(this.element.getStyle("position")=="absolute")){new Insertion.After(this.element.id,'<iframe id="'+this.element.id+'_iefix" style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" src="javascript:false;" frameborder="0" scrolling="no"></iframe>');this.iefix=$(this.element.id+"_iefix")}if(this.iefix){setTimeout(this._fixIEOverlapping.bind(this),50)}},_fixIEOverlapping:function(){Position.clone(this.element,this.iefix);this.iefix.style.zIndex=this.element.style.zIndex-1;this.iefix.show()},_keyUp:function(b){if(27==b.keyCode&&this.options.closeOnEsc){this.close()}},_getWindowBorderSize:function(d){var e=this._createHiddenDiv(this.options.className+"_n");this.heightN=Element.getDimensions(e).height;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_s");this.heightS=Element.getDimensions(e).height;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_e");this.widthE=Element.getDimensions(e).width;e.parentNode.removeChild(e);var e=this._createHiddenDiv(this.options.className+"_w");this.widthW=Element.getDimensions(e).width;e.parentNode.removeChild(e);var e=document.createElement("div");e.className="overlay_"+this.options.className;document.body.appendChild(e);var b=this;setTimeout(function(){b.overlayOpacity=($(e).getStyle("opacity"));e.parentNode.removeChild(e)},10);if(Prototype.Browser.IE){this.heightS=$(this.getId()+"_row3").getDimensions().height;this.heightN=$(this.getId()+"_row1").getDimensions().height}if(Prototype.Browser.WebKit&&Prototype.Browser.WebKitVersion<420){this.setSize(this.width,this.height)}if(this.doMaximize){this.maximize()}if(this.doMinimize){this.minimize()}},_createHiddenDiv:function(d){var b=document.body;var e=document.createElement("div");e.setAttribute("id",this.element.id+"_tmp");e.className=d;e.style.display="none";e.innerHTML="";b.insertBefore(e,b.firstChild);return e},_storeLocation:function(){if(this.storedLocation==null){this.storedLocation={useTop:this.useTop,useLeft:this.useLeft,top:this.element.getStyle("top"),bottom:this.element.getStyle("bottom"),left:this.element.getStyle("left"),right:this.element.getStyle("right"),width:this.width,height:this.height}}},_restoreLocation:function(){if(this.storedLocation!=null){this.useLeft=this.storedLocation.useLeft;this.useTop=this.storedLocation.useTop;if(this.useLeft&&this.useTop&&Window.hasEffectLib&&Effect.ResizeWindow){new Effect.ResizeWindow(this,this.storedLocation.top,this.storedLocation.left,this.storedLocation.width,this.storedLocation.height,{duration:Window.resizeEffectDuration})}else{this.element.setStyle(this.useLeft?{left:this.storedLocation.left}:{right:this.storedLocation.right});this.element.setStyle(this.useTop?{top:this.storedLocation.top}:{bottom:this.storedLocation.bottom});this.setSize(this.storedLocation.width,this.storedLocation.height)}Windows.resetOverflow();this._removeStoreLocation()}},_removeStoreLocation:function(){this.storedLocation=null},_saveCookie:function(){if(this.cookie){var b="";if(this.useLeft){b+="l:"+(this.storedLocation?this.storedLocation.left:this.element.getStyle("left"))}else{b+="r:"+(this.storedLocation?this.storedLocation.right:this.element.getStyle("right"))}if(this.useTop){b+=",t:"+(this.storedLocation?this.storedLocation.top:this.element.getStyle("top"))}else{b+=",b:"+(this.storedLocation?this.storedLocation.bottom:this.element.getStyle("bottom"))}b+=","+(this.storedLocation?this.storedLocation.width:this.width);b+=","+(this.storedLocation?this.storedLocation.height:this.height);b+=","+this.isMinimized();b+=","+this.isMaximized();WindowUtilities.setCookie(b,this.cookie)}},_createWiredElement:function(){if(!this.wiredElement){if(Prototype.Browser.IE){this._getWindowBorderSize()}var d=document.createElement("div");d.className="wired_frame "+this.options.className+"_wired_frame";d.style.position="absolute";this.options.parent.insertBefore(d,this.options.parent.firstChild);this.wiredElement=$(d)}if(this.useLeft){this.wiredElement.setStyle({left:this.element.getStyle("left")})}else{this.wiredElement.setStyle({right:this.element.getStyle("right")})}if(this.useTop){this.wiredElement.setStyle({top:this.element.getStyle("top")})}else{this.wiredElement.setStyle({bottom:this.element.getStyle("bottom")})}var b=this.element.getDimensions();this.wiredElement.setStyle({width:b.width+"px",height:b.height+"px"});this.wiredElement.setStyle({zIndex:Windows.maxZIndex+30});return this.wiredElement},_hideWiredElement:function(){if(!this.wiredElement||!this.currentDrag){return}if(this.currentDrag==this.element){this.currentDrag=null}else{if(this.useLeft){this.element.setStyle({left:this.currentDrag.getStyle("left")})}else{this.element.setStyle({right:this.currentDrag.getStyle("right")})}if(this.useTop){this.element.setStyle({top:this.currentDrag.getStyle("top")})}else{this.element.setStyle({bottom:this.currentDrag.getStyle("bottom")})}this.currentDrag.hide();this.currentDrag=null;if(this.doResize){this.setSize(this.width,this.height)}}},_notify:function(b){if(this.options[b]){this.options[b](this)}else{Windows.notify(b,this)}}};var Windows={windows:[],modalWindows:[],observers:[],focusedWindow:null,maxZIndex:0,overlayShowEffectOptions:{duration:0.5},overlayHideEffectOptions:{duration:0.5},addObserver:function(b){this.removeObserver(b);this.observers.push(b)},removeObserver:function(b){this.observers=this.observers.reject(function(d){return d==b})},notify:function(b,d){this.observers.each(function(e){if(e[b]){e[b](b,d)}})},getWindow:function(b){return this.windows.detect(function(e){return e.getId()==b})},getFocusedWindow:function(){return this.focusedWindow},updateFocusedWindow:function(){this.focusedWindow=this.windows.length>=2?this.windows[this.windows.length-2]:null},register:function(b){this.windows.push(b)},addModalWindow:function(b){if(this.modalWindows.length==0){WindowUtilities.disableScreen(b.options.className,"overlay_modal",b.overlayOpacity,b.getId(),b.options.parent)}else{if(Window.keepMultiModalWindow){$("overlay_modal").style.zIndex=Windows.maxZIndex+1;Windows.maxZIndex+=1;WindowUtilities._hideSelect(this.modalWindows.last().getId())}else{this.modalWindows.last().element.hide()}WindowUtilities._showSelect(b.getId())}this.modalWindows.push(b)},removeModalWindow:function(b){this.modalWindows.pop();if(this.modalWindows.length==0){WindowUtilities.enableScreen()}else{if(Window.keepMultiModalWindow){this.modalWindows.last().toFront();WindowUtilities._showSelect(this.modalWindows.last().getId())}else{this.modalWindows.last().element.show()}}},register:function(b){this.windows.push(b)},unregister:function(b){this.windows=this.windows.reject(function(e){return e==b})},closeAll:function(){this.windows.each(function(b){Windows.close(b.getId())})},closeAllModalWindows:function(){WindowUtilities.enableScreen();this.modalWindows.each(function(b){if(b){b.close()}})},minimize:function(e,b){var d=this.getWindow(e);if(d&&d.visible){d.minimize()}Event.stop(b)},maximize:function(e,b){var d=this.getWindow(e);if(d&&d.visible){d.maximize()}Event.stop(b)},close:function(e,b){var d=this.getWindow(e);if(d){d.close()}if(b){Event.stop(b)}},blur:function(d){var b=this.getWindow(d);if(!b){return}if(b.options.blurClassName){b.changeClassName(b.options.blurClassName)}if(this.focusedWindow==b){this.focusedWindow=null}b._notify("onBlur")},focus:function(d){var b=this.getWindow(d);if(!b){return}if(this.focusedWindow){this.blur(this.focusedWindow.getId())}if(b.options.focusClassName){b.changeClassName(b.options.focusClassName)}this.focusedWindow=b;b._notify("onFocus")},unsetOverflow:function(b){this.windows.each(function(e){e.oldOverflow=e.getContent().getStyle("overflow")||"auto";e.getContent().setStyle({overflow:"hidden"})});if(b&&b.oldOverflow){b.getContent().setStyle({overflow:b.oldOverflow})}},resetOverflow:function(){this.windows.each(function(b){if(b.oldOverflow){b.getContent().setStyle({overflow:b.oldOverflow})}})},updateZindex:function(b,d){if(b>this.maxZIndex){this.maxZIndex=b;if(this.focusedWindow){this.blur(this.focusedWindow.getId())}}this.focusedWindow=d;if(this.focusedWindow){this.focus(this.focusedWindow.getId())}}};var Dialog={dialogId:null,onCompleteFunc:null,callFunc:null,parameters:null,confirm:function(f,e){if(f&&typeof f!="string"){Dialog._runAjaxRequest(f,e,Dialog.confirm);return}f=f||"";e=e||{};var h=e.okLabel?e.okLabel:"Ok";var b=e.cancelLabel?e.cancelLabel:"Cancel";e=Object.extend(e,e.windowParameters||{});e.windowParameters=e.windowParameters||{};e.className=e.className||"alert";var d="class ='"+(e.buttonClass?e.buttonClass+" ":"")+" ok_button'";var g="class ='"+(e.buttonClass?e.buttonClass+" ":"")+" cancel_button'";var f=" <div class='"+e.className+"_message'>"+f+"</div> <div class='"+e.className+"_buttons'> <button type='button' title='"+h+"' onclick='Dialog.okCallback()' "+d+"><span><span><span>"+h+"</span></span></span></button> <button type='button' title='"+b+"' onclick='Dialog.cancelCallback()' "+g+"><span><span><span>"+b+"</span></span></span></button> </div> ";return this._openDialog(f,e)},alert:function(e,d){if(e&&typeof e!="string"){Dialog._runAjaxRequest(e,d,Dialog.alert);return}e=e||"";d=d||{};var f=d.okLabel?d.okLabel:"Ok";d=Object.extend(d,d.windowParameters||{});d.windowParameters=d.windowParameters||{};d.className=d.className||"alert";var b="class ='"+(d.buttonClass?d.buttonClass+" ":"")+" ok_button'";var e=" <div class='"+d.className+"_message'>"+e+"</div> <div class='"+d.className+"_buttons'> <button type='button' title='"+f+"' onclick='Dialog.okCallback()' "+b+"><span><span><span>"+f+"</span></span></span></button> </div>";return this._openDialog(e,d)},info:function(d,b){if(d&&typeof d!="string"){Dialog._runAjaxRequest(d,b,Dialog.info);return}d=d||"";b=b||{};b=Object.extend(b,b.windowParameters||{});b.windowParameters=b.windowParameters||{};b.className=b.className||"alert";var d="<div id='modal_dialog_message' class='"+b.className+"_message'>"+d+"</div>";if(b.showProgress){d+="<div id='modal_dialog_progress' class='"+b.className+"_progress'> </div>"}b.ok=null;b.cancel=null;return this._openDialog(d,b)},setInfoMessage:function(b){$("modal_dialog_message").update(b)},closeInfo:function(){Windows.close(this.dialogId)},_openDialog:function(g,f){var e=f.className;if(!f.height&&!f.width){f.width=WindowUtilities.getPageSize(f.options.parent||document.body).pageWidth/2}if(f.id){this.dialogId=f.id}else{var d=new Date();this.dialogId="modal_dialog_"+d.getTime();f.id=this.dialogId}if(!f.height||!f.width){var b=WindowUtilities._computeSize(g,this.dialogId,f.width,f.height,5,e);if(f.height){f.width=b+5}else{f.height=b+5}}f.effectOptions=f.effectOptions;f.resizable=f.resizable||false;f.minimizable=f.minimizable||false;f.maximizable=f.maximizable||false;f.draggable=f.draggable||false;f.closable=f.closable||false;var h=new Window(f);h.getContent().innerHTML=g;h.showCenter(true,f.top,f.left);h.setDestroyOnClose();h.cancelCallback=f.onCancel||f.cancel;h.okCallback=f.onOk||f.ok;return h},_getAjaxContent:function(b){Dialog.callFunc(b.responseText,Dialog.parameters)},_runAjaxRequest:function(e,d,b){if(e.options==null){e.options={}}Dialog.onCompleteFunc=e.options.onComplete;Dialog.parameters=d;Dialog.callFunc=b;e.options.onComplete=Dialog._getAjaxContent;new Ajax.Request(e.url,e.options)},okCallback:function(){var b=Windows.focusedWindow;if(!b.okCallback||b.okCallback(b)){$$("#"+b.getId()+" input").each(function(d){d.onclick=null});b.close()}},cancelCallback:function(){var b=Windows.focusedWindow;$$("#"+b.getId()+" input").each(function(d){d.onclick=null});b.close();if(b.cancelCallback){b.cancelCallback(b)}}};if(Prototype.Browser.WebKit){var array=navigator.userAgent.match(new RegExp(/AppleWebKit\/([\d\.\+]*)/));Prototype.Browser.WebKitVersion=parseFloat(array[1])}var WindowUtilities={getWindowScroll:function(parent){var T,L,W,H;parent=parent||document.body;if(parent!=document.body){T=parent.scrollTop;L=parent.scrollLeft;W=parent.scrollWidth;H=parent.scrollHeight}else{var w=window;with(w.document){if(w.document.documentElement&&documentElement.scrollTop){T=documentElement.scrollTop;L=documentElement.scrollLeft}else{if(w.document.body){T=body.scrollTop;L=body.scrollLeft}}if(w.innerWidth){W=w.innerWidth;H=w.innerHeight}else{if(w.document.documentElement&&documentElement.clientWidth){W=documentElement.clientWidth;H=documentElement.clientHeight}else{W=body.offsetWidth;H=body.offsetHeight}}}}return{top:T,left:L,width:W,height:H}},getPageSize:function(f){f=f||document.body;var e,l;var g,d;if(f!=document.body){e=f.getWidth();l=f.getHeight();d=f.scrollWidth;g=f.scrollHeight}else{var h,b;if(window.innerHeight&&window.scrollMaxY){h=document.body.scrollWidth;b=window.innerHeight+window.scrollMaxY}else{if(document.body.scrollHeight>document.body.offsetHeight){h=document.body.scrollWidth;b=document.body.scrollHeight}else{h=document.body.offsetWidth;b=document.body.offsetHeight}}if(self.innerHeight){e=document.documentElement.clientWidth;l=self.innerHeight}else{if(document.documentElement&&document.documentElement.clientHeight){e=document.documentElement.clientWidth;l=document.documentElement.clientHeight}else{if(document.body){e=document.body.clientWidth;l=document.body.clientHeight}}}if(b<l){g=l}else{g=b}if(h<e){d=e}else{d=h}}return{pageWidth:d,pageHeight:g,windowWidth:e,windowHeight:l}},disableScreen:function(e,b,f,g,d){WindowUtilities.initLightbox(b,e,function(){this._disableScreen(e,b,f,g)}.bind(this),d||document.body)},_disableScreen:function(e,d,g,h){var f=$(d);var b=WindowUtilities.getPageSize(f.parentNode);if(h&&Prototype.Browser.IE){WindowUtilities._hideSelect();WindowUtilities._showSelect(h)}f.style.height=(b.pageHeight+"px");f.style.display="none";if(d=="overlay_modal"&&Window.hasEffectLib&&Windows.overlayShowEffectOptions){f.overlayOpacity=g;new Effect.Appear(f,Object.extend({from:0,to:g},Windows.overlayShowEffectOptions))}else{f.style.display="block"}},enableScreen:function(d){d=d||"overlay_modal";var b=$(d);if(b){if(d=="overlay_modal"&&Window.hasEffectLib&&Windows.overlayHideEffectOptions){new Effect.Fade(b,Object.extend({from:b.overlayOpacity,to:0},Windows.overlayHideEffectOptions))}else{b.style.display="none";b.parentNode.removeChild(b)}if(d!="__invisible__"){WindowUtilities._showSelect()}}},_hideSelect:function(b){if(Prototype.Browser.IE){b=b==null?"":"#"+b+" ";$$(b+"select").each(function(d){if(!WindowUtilities.isDefined(d.oldVisibility)){d.oldVisibility=d.style.visibility?d.style.visibility:"visible";d.style.visibility="hidden"}})}},_showSelect:function(b){if(Prototype.Browser.IE){b=b==null?"":"#"+b+" ";$$(b+"select").each(function(d){if(WindowUtilities.isDefined(d.oldVisibility)){try{d.style.visibility=d.oldVisibility}catch(f){d.style.visibility="visible"}d.oldVisibility=null}else{if(d.style.visibility){d.style.visibility="visible"}}})}},isDefined:function(b){return typeof(b)!="undefined"&&b!=null},initLightbox:function(g,e,b,d){if($(g)){Element.setStyle(g,{zIndex:Windows.maxZIndex+1});Windows.maxZIndex++;b()}else{var f=document.createElement("div");f.setAttribute("id",g);f.className="overlay_"+e;f.style.display="none";f.style.position="absolute";f.style.top="0";f.style.left="0";f.style.zIndex=Windows.maxZIndex+1;Windows.maxZIndex++;f.style.width="100%";d.insertBefore(f,d.firstChild);if(Prototype.Browser.WebKit&&g=="overlay_modal"){setTimeout(function(){b()},10)}else{b()}}},setCookie:function(d,b){document.cookie=b[0]+"="+escape(d)+((b[1])?"; expires="+b[1].toUTCString():"")+((b[2])?"; path="+b[2]:"")+((b[3])?"; domain="+b[3]:"")+((b[4])?"; secure":"")},getCookie:function(e){var d=document.cookie;var g=e+"=";var f=d.indexOf("; "+g);if(f==-1){f=d.indexOf(g);if(f!=0){return null}}else{f+=2}var b=document.cookie.indexOf(";",f);if(b==-1){b=d.length}return unescape(d.substring(f+g.length,b))},_computeSize:function(g,b,d,l,f,h){var o=document.body;var e=document.createElement("div");e.setAttribute("id",b);e.className=h+"_content";if(l){e.style.height=l+"px"}else{e.style.width=d+"px"}e.style.position="absolute";e.style.top="0";e.style.left="0";e.style.display="none";e.innerHTML=g;o.insertBefore(e,o.firstChild);var n;if(l){n=$(e).getDimensions().width+f}else{n=$(e).getDimensions().height+f}o.removeChild(e);return n}};var Builder={NODEMAP:{AREA:"map",CAPTION:"table",COL:"table",COLGROUP:"table",LEGEND:"fieldset",OPTGROUP:"select",OPTION:"select",PARAM:"object",TBODY:"table",TD:"table",TFOOT:"table",TH:"table",THEAD:"table",TR:"table"},node:function(b){b=b.toUpperCase();var l=this.NODEMAP[b]||"div";var d=document.createElement(l);try{d.innerHTML="<"+b+"></"+b+">"}catch(h){}var g=d.firstChild||null;if(g&&(g.tagName.toUpperCase()!=b)){g=g.getElementsByTagName(b)[0]}if(!g){g=document.createElement(b)}if(!g){return}if(arguments[1]){if(this._isStringOrNumber(arguments[1])||(arguments[1] instanceof Array)||arguments[1].tagName){this._children(g,arguments[1])}else{var f=this._attributes(arguments[1]);if(f.length){try{d.innerHTML="<"+b+" "+f+"></"+b+">"}catch(h){}g=d.firstChild||null;if(!g){g=document.createElement(b);for(attr in arguments[1]){g[attr=="class"?"className":attr]=arguments[1][attr]}}if(g.tagName.toUpperCase()!=b){g=d.getElementsByTagName(b)[0]}}}}if(arguments[2]){this._children(g,arguments[2])}return $(g)},_text:function(b){return document.createTextNode(b)},ATTR_MAP:{className:"class",htmlFor:"for"},_attributes:function(b){var d=[];for(attribute in b){d.push((attribute in this.ATTR_MAP?this.ATTR_MAP[attribute]:attribute)+'="'+b[attribute].toString().escapeHTML().gsub(/"/,""")+'"')}return d.join(" ")},_children:function(d,b){if(b.tagName){d.appendChild(b);return}if(typeof b=="object"){b.flatten().each(function(f){if(typeof f=="object"){d.appendChild(f)}else{if(Builder._isStringOrNumber(f)){d.appendChild(Builder._text(f))}}})}else{if(Builder._isStringOrNumber(b)){d.appendChild(Builder._text(b))}}},_isStringOrNumber:function(b){return(typeof b=="string"||typeof b=="number")},build:function(d){var b=this.node("div");$(b).update(d.strip());return b.down()},dump:function(d){if(typeof d!="object"&&typeof d!="function"){d=window}var b=("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);b.each(function(e){d[e]=function(){return Builder.node.apply(Builder,[e].concat($A(arguments)))}})}};String.prototype.parseColor=function(){var b="#";if(this.slice(0,4)=="rgb("){var e=this.slice(4,this.length-1).split(",");var d=0;do{b+=parseInt(e[d]).toColorPart()}while(++d<3)}else{if(this.slice(0,1)=="#"){if(this.length==4){for(var d=1;d<4;d++){b+=(this.charAt(d)+this.charAt(d)).toLowerCase()}}if(this.length==7){b=this.toLowerCase()}}}return(b.length==7?b:(arguments[0]||this))};Element.collectTextNodes=function(b){return $A($(b).childNodes).collect(function(d){return(d.nodeType==3?d.nodeValue:(d.hasChildNodes()?Element.collectTextNodes(d):""))}).flatten().join("")};Element.collectTextNodesIgnoreClass=function(b,d){return $A($(b).childNodes).collect(function(e){return(e.nodeType==3?e.nodeValue:((e.hasChildNodes()&&!Element.hasClassName(e,d))?Element.collectTextNodesIgnoreClass(e,d):""))}).flatten().join("")};Element.setContentZoom=function(b,d){b=$(b);b.setStyle({fontSize:(d/100)+"em"});if(Prototype.Browser.WebKit){window.scrollBy(0,0)}return b};Element.getInlineOpacity=function(b){return $(b).style.opacity||""};Element.forceRerendering=function(b){try{b=$(b);var f=document.createTextNode(" ");b.appendChild(f);b.removeChild(f)}catch(d){}};var Effect={_elementDoesNotExistError:{name:"ElementDoesNotExistError",message:"The specified DOM element does not exist, but is required for this effect to operate"},Transitions:{linear:Prototype.K,sinoidal:function(b){return(-Math.cos(b*Math.PI)/2)+0.5},reverse:function(b){return 1-b},flicker:function(b){var b=((-Math.cos(b*Math.PI)/4)+0.75)+Math.random()/4;return b>1?1:b},wobble:function(b){return(-Math.cos(b*Math.PI*(9*b))/2)+0.5},pulse:function(d,b){return(-Math.cos((d*((b||5)-0.5)*2)*Math.PI)/2)+0.5},spring:function(b){return 1-(Math.cos(b*4.5*Math.PI)*Math.exp(-b*6))},none:function(b){return 0},full:function(b){return 1}},DefaultOptions:{duration:1,fps:100,sync:false,from:0,to:1,delay:0,queue:"parallel"},tagifyText:function(b){var d="position:relative";if(Prototype.Browser.IE){d+=";zoom:1"}b=$(b);$A(b.childNodes).each(function(e){if(e.nodeType==3){e.nodeValue.toArray().each(function(f){b.insertBefore(new Element("span",{style:d}).update(f==" "?String.fromCharCode(160):f),e)});Element.remove(e)}})},multiple:function(d,e){var g;if(((typeof d=="object")||Object.isFunction(d))&&(d.length)){g=d}else{g=$(d).childNodes}var b=Object.extend({speed:0.1,delay:0},arguments[2]||{});var f=b.delay;$A(g).each(function(l,h){new e(l,Object.extend(b,{delay:h*b.speed+f}))})},PAIRS:{slide:["SlideDown","SlideUp"],blind:["BlindDown","BlindUp"],appear:["Appear","Fade"]},toggle:function(d,e){d=$(d);e=(e||"appear").toLowerCase();var b=Object.extend({queue:{position:"end",scope:(d.id||"global"),limit:1}},arguments[2]||{});Effect[d.visible()?Effect.PAIRS[e][1]:Effect.PAIRS[e][0]](d,b)}};Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;Effect.ScopedQueue=Class.create(Enumerable,{initialize:function(){this.effects=[];this.interval=null},_each:function(b){this.effects._each(b)},add:function(d){var e=new Date().getTime();var b=Object.isString(d.options.queue)?d.options.queue:d.options.queue.position;switch(b){case"front":this.effects.findAll(function(f){return f.state=="idle"}).each(function(f){f.startOn+=d.finishOn;f.finishOn+=d.finishOn});break;case"with-last":e=this.effects.pluck("startOn").max()||e;break;case"end":e=this.effects.pluck("finishOn").max()||e;break}d.startOn+=e;d.finishOn+=e;if(!d.options.queue.limit||(this.effects.length<d.options.queue.limit)){this.effects.push(d)}if(!this.interval){this.interval=setInterval(this.loop.bind(this),15)}},remove:function(b){this.effects=this.effects.reject(function(d){return d==b});if(this.effects.length==0){clearInterval(this.interval);this.interval=null}},loop:function(){var e=new Date().getTime();for(var d=0,b=this.effects.length;d<b;d++){this.effects[d]&&this.effects[d].loop(e)}}});Effect.Queues={instances:$H(),get:function(b){if(!Object.isString(b)){return b}return this.instances.get(b)||this.instances.set(b,new Effect.ScopedQueue())}};Effect.Queue=Effect.Queues.get("global");Effect.Base=Class.create({position:null,start:function(b){function d(f,e){return((f[e+"Internal"]?"this.options."+e+"Internal(this);":"")+(f[e]?"this.options."+e+"(this);":""))}if(b&&b.transition===false){b.transition=Effect.Transitions.linear}this.options=Object.extend(Object.extend({},Effect.DefaultOptions),b||{});this.currentFrame=0;this.state="idle";this.startOn=this.options.delay*1000;this.finishOn=this.startOn+(this.options.duration*1000);this.fromToDelta=this.options.to-this.options.from;this.totalTime=this.finishOn-this.startOn;this.totalFrames=this.options.fps*this.options.duration;this.render=(function(){function e(g,f){if(g.options[f+"Internal"]){g.options[f+"Internal"](g)}if(g.options[f]){g.options[f](g)}}return function(f){if(this.state==="idle"){this.state="running";e(this,"beforeSetup");if(this.setup){this.setup()}e(this,"afterSetup")}if(this.state==="running"){f=(this.options.transition(f)*this.fromToDelta)+this.options.from;this.position=f;e(this,"beforeUpdate");if(this.update){this.update(f)}e(this,"afterUpdate")}}})();this.event("beforeStart");if(!this.options.sync){Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).add(this)}},loop:function(e){if(e>=this.startOn){if(e>=this.finishOn){this.render(1);this.cancel();this.event("beforeFinish");if(this.finish){this.finish()}this.event("afterFinish");return}var d=(e-this.startOn)/this.totalTime,b=(d*this.totalFrames).round();if(b>this.currentFrame){this.render(d);this.currentFrame=b}}},cancel:function(){if(!this.options.sync){Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).remove(this)}this.state="finished"},event:function(b){if(this.options[b+"Internal"]){this.options[b+"Internal"](this)}if(this.options[b]){this.options[b](this)}},inspect:function(){var b=$H();for(property in this){if(!Object.isFunction(this[property])){b.set(property,this[property])}}return"#<Effect:"+b.inspect()+",options:"+$H(this.options).inspect()+">"}});Effect.Parallel=Class.create(Effect.Base,{initialize:function(b){this.effects=b||[];this.start(arguments[1])},update:function(b){this.effects.invoke("render",b)},finish:function(b){this.effects.each(function(d){d.render(1);d.cancel();d.event("beforeFinish");if(d.finish){d.finish(b)}d.event("afterFinish")})}});Effect.Tween=Class.create(Effect.Base,{initialize:function(e,h,g){e=Object.isString(e)?$(e):e;var d=$A(arguments),f=d.last(),b=d.length==5?d[3]:null;this.method=Object.isFunction(f)?f.bind(e):Object.isFunction(e[f])?e[f].bind(e):function(l){e[f]=l};this.start(Object.extend({from:h,to:g},b||{}))},update:function(b){this.method(b)}});Effect.Event=Class.create(Effect.Base,{initialize:function(){this.start(Object.extend({duration:0},arguments[0]||{}))},update:Prototype.emptyFunction});Effect.Opacity=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}var b=Object.extend({from:this.element.getOpacity()||0,to:1},arguments[1]||{});this.start(b)},update:function(b){this.element.setOpacity(b)}});Effect.Move=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({x:0,y:0,mode:"relative"},arguments[1]||{});this.start(b)},setup:function(){this.element.makePositioned();this.originalLeft=parseFloat(this.element.getStyle("left")||"0");this.originalTop=parseFloat(this.element.getStyle("top")||"0");if(this.options.mode=="absolute"){this.options.x=this.options.x-this.originalLeft;this.options.y=this.options.y-this.originalTop}},update:function(b){this.element.setStyle({left:(this.options.x*b+this.originalLeft).round()+"px",top:(this.options.y*b+this.originalTop).round()+"px"})}});Effect.MoveBy=function(d,b,e){return new Effect.Move(d,Object.extend({x:e,y:b},arguments[3]||{}))};Effect.Scale=Class.create(Effect.Base,{initialize:function(d,e){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:"box",scaleFrom:100,scaleTo:e},arguments[2]||{});this.start(b)},setup:function(){this.restoreAfterFinish=this.options.restoreAfterFinish||false;this.elementPositioning=this.element.getStyle("position");this.originalStyle={};["top","left","width","height","fontSize"].each(function(d){this.originalStyle[d]=this.element.style[d]}.bind(this));this.originalTop=this.element.offsetTop;this.originalLeft=this.element.offsetLeft;var b=this.element.getStyle("font-size")||"100%";["em","px","%","pt"].each(function(d){if(b.indexOf(d)>0){this.fontSize=parseFloat(b);this.fontSizeType=d}}.bind(this));this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;this.dims=null;if(this.options.scaleMode=="box"){this.dims=[this.element.offsetHeight,this.element.offsetWidth]}if(/^content/.test(this.options.scaleMode)){this.dims=[this.element.scrollHeight,this.element.scrollWidth]}if(!this.dims){this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth]}},update:function(b){var d=(this.options.scaleFrom/100)+(this.factor*b);if(this.options.scaleContent&&this.fontSize){this.element.setStyle({fontSize:this.fontSize*d+this.fontSizeType})}this.setDimensions(this.dims[0]*d,this.dims[1]*d)},finish:function(b){if(this.restoreAfterFinish){this.element.setStyle(this.originalStyle)}},setDimensions:function(b,g){var h={};if(this.options.scaleX){h.width=g.round()+"px"}if(this.options.scaleY){h.height=b.round()+"px"}if(this.options.scaleFromCenter){var f=(b-this.dims[0])/2;var e=(g-this.dims[1])/2;if(this.elementPositioning=="absolute"){if(this.options.scaleY){h.top=this.originalTop-f+"px"}if(this.options.scaleX){h.left=this.originalLeft-e+"px"}}else{if(this.options.scaleY){h.top=-f+"px"}if(this.options.scaleX){h.left=-e+"px"}}}this.element.setStyle(h)}});Effect.Highlight=Class.create(Effect.Base,{initialize:function(d){this.element=$(d);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({startcolor:"#ffff99"},arguments[1]||{});this.start(b)},setup:function(){if(this.element.getStyle("display")=="none"){this.cancel();return}this.oldStyle={};if(!this.options.keepBackgroundImage){this.oldStyle.backgroundImage=this.element.getStyle("background-image");this.element.setStyle({backgroundImage:"none"})}if(!this.options.endcolor){this.options.endcolor=this.element.getStyle("background-color").parseColor("#ffffff")}if(!this.options.restorecolor){this.options.restorecolor=this.element.getStyle("background-color")}this._base=$R(0,2).map(function(b){return parseInt(this.options.startcolor.slice(b*2+1,b*2+3),16)}.bind(this));this._delta=$R(0,2).map(function(b){return parseInt(this.options.endcolor.slice(b*2+1,b*2+3),16)-this._base[b]}.bind(this))},update:function(b){this.element.setStyle({backgroundColor:$R(0,2).inject("#",function(d,e,f){return d+((this._base[f]+(this._delta[f]*b)).round().toColorPart())}.bind(this))})},finish:function(){this.element.setStyle(Object.extend(this.oldStyle,{backgroundColor:this.options.restorecolor}))}});Effect.ScrollTo=function(e){var d=arguments[1]||{},b=document.viewport.getScrollOffsets(),f=$(e).cumulativeOffset();if(d.offset){f[1]+=d.offset}return new Effect.Tween(null,b.top,f[1],d,function(g){scrollTo(b.left,g.round())})};Effect.Fade=function(e){e=$(e);var b=e.getInlineOpacity();var d=Object.extend({from:e.getOpacity()||1,to:0,afterFinishInternal:function(f){if(f.options.to!=0){return}f.element.hide().setStyle({opacity:b})}},arguments[1]||{});return new Effect.Opacity(e,d)};Effect.Appear=function(d){d=$(d);var b=Object.extend({from:(d.getStyle("display")=="none"?0:d.getOpacity()||0),to:1,afterFinishInternal:function(e){e.element.forceRerendering()},beforeSetup:function(e){e.element.setOpacity(e.options.from).show()}},arguments[1]||{});return new Effect.Opacity(d,b)};Effect.Puff=function(d){d=$(d);var b={opacity:d.getInlineOpacity(),position:d.getStyle("position"),top:d.style.top,left:d.style.left,width:d.style.width,height:d.style.height};return new Effect.Parallel([new Effect.Scale(d,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new Effect.Opacity(d,{sync:true,to:0})],Object.extend({duration:1,beforeSetupInternal:function(e){Position.absolutize(e.effects[0].element)},afterFinishInternal:function(e){e.effects[0].element.hide().setStyle(b)}},arguments[1]||{}))};Effect.BlindUp=function(b){b=$(b);b.makeClipping();return new Effect.Scale(b,0,Object.extend({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(d){d.element.hide().undoClipping()}},arguments[1]||{}))};Effect.BlindDown=function(d){d=$(d);var b=d.getDimensions();return new Effect.Scale(d,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:b.height,originalWidth:b.width},restoreAfterFinish:true,afterSetup:function(e){e.element.makeClipping().setStyle({height:"0px"}).show()},afterFinishInternal:function(e){e.element.undoClipping()}},arguments[1]||{}))};Effect.SwitchOff=function(d){d=$(d);var b=d.getInlineOpacity();return new Effect.Appear(d,Object.extend({duration:0.4,from:0,transition:Effect.Transitions.flicker,afterFinishInternal:function(e){new Effect.Scale(e.element,1,{duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetup:function(f){f.element.makePositioned().makeClipping()},afterFinishInternal:function(f){f.element.hide().undoClipping().undoPositioned().setStyle({opacity:b})}})}},arguments[1]||{}))};Effect.DropOut=function(d){d=$(d);var b={top:d.getStyle("top"),left:d.getStyle("left"),opacity:d.getInlineOpacity()};return new Effect.Parallel([new Effect.Move(d,{x:0,y:100,sync:true}),new Effect.Opacity(d,{sync:true,to:0})],Object.extend({duration:0.5,beforeSetup:function(e){e.effects[0].element.makePositioned()},afterFinishInternal:function(e){e.effects[0].element.hide().undoPositioned().setStyle(b)}},arguments[1]||{}))};Effect.Shake=function(f){f=$(f);var d=Object.extend({distance:20,duration:0.5},arguments[1]||{});var g=parseFloat(d.distance);var e=parseFloat(d.duration)/10;var b={top:f.getStyle("top"),left:f.getStyle("left")};return new Effect.Move(f,{x:g,y:0,duration:e,afterFinishInternal:function(h){new Effect.Move(h.element,{x:-g*2,y:0,duration:e*2,afterFinishInternal:function(l){new Effect.Move(l.element,{x:g*2,y:0,duration:e*2,afterFinishInternal:function(n){new Effect.Move(n.element,{x:-g*2,y:0,duration:e*2,afterFinishInternal:function(o){new Effect.Move(o.element,{x:g*2,y:0,duration:e*2,afterFinishInternal:function(p){new Effect.Move(p.element,{x:-g,y:0,duration:e,afterFinishInternal:function(q){q.element.undoPositioned().setStyle(b)}})}})}})}})}})}})};Effect.SlideDown=function(e){e=$(e).cleanWhitespace();var b=e.down().getStyle("bottom");var d=e.getDimensions();return new Effect.Scale(e,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:window.opera?0:1,scaleMode:{originalHeight:d.height,originalWidth:d.width},restoreAfterFinish:true,afterSetup:function(f){f.element.makePositioned();f.element.down().makePositioned();if(window.opera){f.element.setStyle({top:""})}f.element.makeClipping().setStyle({height:"0px"}).show()},afterUpdateInternal:function(f){f.element.down().setStyle({bottom:(f.dims[0]-f.element.clientHeight)+"px"})},afterFinishInternal:function(f){f.element.undoClipping().undoPositioned();f.element.down().undoPositioned().setStyle({bottom:b})}},arguments[1]||{}))};Effect.SlideUp=function(e){e=$(e).cleanWhitespace();var b=e.down().getStyle("bottom");var d=e.getDimensions();return new Effect.Scale(e,window.opera?0:1,Object.extend({scaleContent:false,scaleX:false,scaleMode:"box",scaleFrom:100,scaleMode:{originalHeight:d.height,originalWidth:d.width},restoreAfterFinish:true,afterSetup:function(f){f.element.makePositioned();f.element.down().makePositioned();if(window.opera){f.element.setStyle({top:""})}f.element.makeClipping().show()},afterUpdateInternal:function(f){f.element.down().setStyle({bottom:(f.dims[0]-f.element.clientHeight)+"px"})},afterFinishInternal:function(f){f.element.hide().undoClipping().undoPositioned();f.element.down().undoPositioned().setStyle({bottom:b})}},arguments[1]||{}))};Effect.Squish=function(b){return new Effect.Scale(b,window.opera?1:0,{restoreAfterFinish:true,beforeSetup:function(d){d.element.makeClipping()},afterFinishInternal:function(d){d.element.hide().undoClipping()}})};Effect.Grow=function(e){e=$(e);var d=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.full},arguments[1]||{});var b={top:e.style.top,left:e.style.left,height:e.style.height,width:e.style.width,opacity:e.getInlineOpacity()};var l=e.getDimensions();var n,h;var g,f;switch(d.direction){case"top-left":n=h=g=f=0;break;case"top-right":n=l.width;h=f=0;g=-l.width;break;case"bottom-left":n=g=0;h=l.height;f=-l.height;break;case"bottom-right":n=l.width;h=l.height;g=-l.width;f=-l.height;break;case"center":n=l.width/2;h=l.height/2;g=-l.width/2;f=-l.height/2;break}return new Effect.Move(e,{x:n,y:h,duration:0.01,beforeSetup:function(o){o.element.hide().makeClipping().makePositioned()},afterFinishInternal:function(o){new Effect.Parallel([new Effect.Opacity(o.element,{sync:true,to:1,from:0,transition:d.opacityTransition}),new Effect.Move(o.element,{x:g,y:f,sync:true,transition:d.moveTransition}),new Effect.Scale(o.element,100,{scaleMode:{originalHeight:l.height,originalWidth:l.width},sync:true,scaleFrom:window.opera?1:0,transition:d.scaleTransition,restoreAfterFinish:true})],Object.extend({beforeSetup:function(p){p.effects[0].element.setStyle({height:"0px"}).show()},afterFinishInternal:function(p){p.effects[0].element.undoClipping().undoPositioned().setStyle(b)}},d))}})};Effect.Shrink=function(e){e=$(e);var d=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.none},arguments[1]||{});var b={top:e.style.top,left:e.style.left,height:e.style.height,width:e.style.width,opacity:e.getInlineOpacity()};var h=e.getDimensions();var g,f;switch(d.direction){case"top-left":g=f=0;break;case"top-right":g=h.width;f=0;break;case"bottom-left":g=0;f=h.height;break;case"bottom-right":g=h.width;f=h.height;break;case"center":g=h.width/2;f=h.height/2;break}return new Effect.Parallel([new Effect.Opacity(e,{sync:true,to:0,from:1,transition:d.opacityTransition}),new Effect.Scale(e,window.opera?1:0,{sync:true,transition:d.scaleTransition,restoreAfterFinish:true}),new Effect.Move(e,{x:g,y:f,sync:true,transition:d.moveTransition})],Object.extend({beforeStartInternal:function(l){l.effects[0].element.makePositioned().makeClipping()},afterFinishInternal:function(l){l.effects[0].element.hide().undoClipping().undoPositioned().setStyle(b)}},d))};Effect.Pulsate=function(e){e=$(e);var d=arguments[1]||{},b=e.getInlineOpacity(),g=d.transition||Effect.Transitions.linear,f=function(h){return 1-g((-Math.cos((h*(d.pulses||5)*2)*Math.PI)/2)+0.5)};return new Effect.Opacity(e,Object.extend(Object.extend({duration:2,from:0,afterFinishInternal:function(h){h.element.setStyle({opacity:b})}},d),{transition:f}))};Effect.Fold=function(d){d=$(d);var b={top:d.style.top,left:d.style.left,width:d.style.width,height:d.style.height};d.makeClipping();return new Effect.Scale(d,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(e){new Effect.Scale(d,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(f){f.element.hide().undoClipping().setStyle(b)}})}},arguments[1]||{}))};Effect.Morph=Class.create(Effect.Base,{initialize:function(e){this.element=$(e);if(!this.element){throw (Effect._elementDoesNotExistError)}var b=Object.extend({style:{}},arguments[1]||{});if(!Object.isString(b.style)){this.style=$H(b.style)}else{if(b.style.include(":")){this.style=b.style.parseStyle()}else{this.element.addClassName(b.style);this.style=$H(this.element.getStyles());this.element.removeClassName(b.style);var d=this.element.getStyles();this.style=this.style.reject(function(f){return f.value==d[f.key]});b.afterFinishInternal=function(f){f.element.addClassName(f.options.style);f.transforms.each(function(g){f.element.style[g.style]=""})}}}this.start(b)},setup:function(){function b(d){if(!d||["rgba(0, 0, 0, 0)","transparent"].include(d)){d="#ffffff"}d=d.parseColor();return $R(0,2).map(function(e){return parseInt(d.slice(e*2+1,e*2+3),16)})}this.transforms=this.style.map(function(l){var h=l[0],g=l[1],f=null;if(g.parseColor("#zzzzzz")!="#zzzzzz"){g=g.parseColor();f="color"}else{if(h=="opacity"){g=parseFloat(g);if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){this.element.setStyle({zoom:1})}}else{if(Element.CSS_LENGTH.test(g)){var e=g.match(/^([\+\-]?[0-9\.]+)(.*)$/);g=parseFloat(e[1]);f=(e.length==3)?e[2]:null}}}var d=this.element.getStyle(h);return{style:h.camelize(),originalValue:f=="color"?b(d):parseFloat(d||0),targetValue:f=="color"?b(g):g,unit:f}}.bind(this)).reject(function(d){return((d.originalValue==d.targetValue)||(d.unit!="color"&&(isNaN(d.originalValue)||isNaN(d.targetValue))))})},update:function(b){var f={},d,e=this.transforms.length;while(e--){f[(d=this.transforms[e]).style]=d.unit=="color"?"#"+(Math.round(d.originalValue[0]+(d.targetValue[0]-d.originalValue[0])*b)).toColorPart()+(Math.round(d.originalValue[1]+(d.targetValue[1]-d.originalValue[1])*b)).toColorPart()+(Math.round(d.originalValue[2]+(d.targetValue[2]-d.originalValue[2])*b)).toColorPart():(d.originalValue+(d.targetValue-d.originalValue)*b).toFixed(3)+(d.unit===null?"":d.unit)}this.element.setStyle(f,true)}});Effect.Transform=Class.create({initialize:function(b){this.tracks=[];this.options=arguments[1]||{};this.addTracks(b)},addTracks:function(b){b.each(function(d){d=$H(d);var e=d.values().first();this.tracks.push($H({ids:d.keys().first(),effect:Effect.Morph,options:{style:e}}))}.bind(this));return this},play:function(){return new Effect.Parallel(this.tracks.map(function(b){var f=b.get("ids"),e=b.get("effect"),d=b.get("options");var g=[$(f)||$$(f)].flatten();return g.map(function(h){return new e(h,Object.extend({sync:true},d))})}).flatten(),this.options)}});Element.CSS_PROPERTIES=$w("backgroundColor backgroundPosition borderBottomColor borderBottomStyle borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth borderRightColor borderRightStyle borderRightWidth borderSpacing borderTopColor borderTopStyle borderTopWidth bottom clip color fontSize fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop markerOffset maxHeight maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft paddingRight paddingTop right textIndent top width wordSpacing zIndex");Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;String.__parseStyleElement=document.createElement("div");String.prototype.parseStyle=function(){var d,b=$H();if(Prototype.Browser.WebKit){d=new Element("div",{style:this}).style}else{String.__parseStyleElement.innerHTML='<div style="'+this+'"></div>';d=String.__parseStyleElement.childNodes[0].style}Element.CSS_PROPERTIES.each(function(e){if(d[e]){b.set(e,d[e])}});if(Prototype.Browser.IE&&this.include("opacity")){b.set("opacity",this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1])}return b};if(document.defaultView&&document.defaultView.getComputedStyle){Element.getStyles=function(d){var b=document.defaultView.getComputedStyle($(d),null);return Element.CSS_PROPERTIES.inject({},function(e,f){e[f]=b[f];return e})}}else{Element.getStyles=function(d){d=$(d);var b=d.currentStyle,e;e=Element.CSS_PROPERTIES.inject({},function(f,g){f[g]=b[g];return f});if(!e.opacity){e.opacity=d.getOpacity()}return e}}Effect.Methods={morph:function(b,d){b=$(b);new Effect.Morph(b,Object.extend({style:d},arguments[2]||{}));return b},visualEffect:function(e,g,d){e=$(e);var f=g.dasherize().camelize(),b=f.charAt(0).toUpperCase()+f.substring(1);new Effect[b](e,d);return e},highlight:function(d,b){d=$(d);new Effect.Highlight(d,b);return d}};$w("fade appear grow shrink fold blindUp blindDown slideUp slideDown pulsate shake puff squish switchOff dropOut").each(function(b){Effect.Methods[b]=function(e,d){e=$(e);Effect[b.charAt(0).toUpperCase()+b.substring(1)](e,d);return e}});$w("getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles").each(function(b){Effect.Methods[b]=Element[b]});Element.addMethods(Effect.Methods);function validateCreditCard(e){var d="0123456789";var b="";for(i=0;i<e.length;i++){x=e.charAt(i);if(d.indexOf(x,0)!=-1){b+=x}}j=b.length/2;k=Math.floor(j);m=Math.ceil(j)-k;c=0;for(i=0;i<k;i++){a=b.charAt(i*2+m)*2;c+=a>9?Math.floor(a/10+a%10):a}for(i=0;i<k+m;i++){c+=b.charAt(i*2+1-m)*1}return(c%10==0)}var Validator=Class.create();Validator.prototype={initialize:function(e,d,f,b){if(typeof f=="function"){this.options=$H(b);this._test=f}else{this.options=$H(f);this._test=function(){return true}}this.error=d||"Validation failed.";this.className=e},test:function(b,d){return(this._test(b,d)&&this.options.all(function(e){return Validator.methods[e.key]?Validator.methods[e.key](b,d,e.value):true}))}};Validator.methods={pattern:function(b,e,d){return Validation.get("IsEmpty").test(b)||d.test(b)},minLength:function(b,e,d){return b.length>=d},maxLength:function(b,e,d){return b.length<=d},min:function(b,e,d){return b>=parseFloat(d)},max:function(b,e,d){return b<=parseFloat(d)},notOneOf:function(b,e,d){return $A(d).all(function(f){return b!=f})},oneOf:function(b,e,d){return $A(d).any(function(f){return b==f})},is:function(b,e,d){return b==d},isNot:function(b,e,d){return b!=d},equalToField:function(b,e,d){return b==$F(d)},notEqualToField:function(b,e,d){return b!=$F(d)},include:function(b,e,d){return $A(d).all(function(f){return Validation.get(f).test(b,e)})}};var Validation=Class.create();Validation.defaultOptions={onSubmit:true,stopOnFirst:false,immediate:false,focusOnError:true,useTitles:false,addClassNameToContainer:false,containerClassName:".input-box",onFormValidate:function(b,d){},onElementValidate:function(b,d){}};Validation.prototype={initialize:function(d,b){this.form=$(d);if(!this.form){return}this.options=Object.extend({onSubmit:Validation.defaultOptions.onSubmit,stopOnFirst:Validation.defaultOptions.stopOnFirst,immediate:Validation.defaultOptions.immediate,focusOnError:Validation.defaultOptions.focusOnError,useTitles:Validation.defaultOptions.useTitles,onFormValidate:Validation.defaultOptions.onFormValidate,onElementValidate:Validation.defaultOptions.onElementValidate},b||{});if(this.options.onSubmit){Event.observe(this.form,"submit",this.onSubmit.bind(this),false)}if(this.options.immediate){Form.getElements(this.form).each(function(e){if(e.tagName.toLowerCase()=="select"){Event.observe(e,"blur",this.onChange.bindAsEventListener(this))}if(e.type.toLowerCase()=="radio"||e.type.toLowerCase()=="checkbox"){Event.observe(e,"click",this.onChange.bindAsEventListener(this))}else{Event.observe(e,"change",this.onChange.bindAsEventListener(this))}},this)}},onChange:function(b){Validation.isOnChange=true;Validation.validate(Event.element(b),{useTitle:this.options.useTitles,onElementValidate:this.options.onElementValidate});Validation.isOnChange=false},onSubmit:function(b){if(!this.validate()){Event.stop(b)}},validate:function(){var b=false;var d=this.options.useTitles;var g=this.options.onElementValidate;try{if(this.options.stopOnFirst){b=Form.getElements(this.form).all(function(e){if(e.hasClassName("local-validation")&&!this.isElementInForm(e,this.form)){return true}return Validation.validate(e,{useTitle:d,onElementValidate:g})},this)}else{b=Form.getElements(this.form).collect(function(e){if(e.hasClassName("local-validation")&&!this.isElementInForm(e,this.form)){return true}if(e.hasClassName("validation-disabled")){return true}return Validation.validate(e,{useTitle:d,onElementValidate:g})},this).all()}}catch(f){}if(!b&&this.options.focusOnError){try{Form.getElements(this.form).findAll(function(e){return $(e).hasClassName("validation-failed")}).first().focus()}catch(f){}}this.options.onFormValidate(b,this.form);return b},reset:function(){Form.getElements(this.form).each(Validation.reset)},isElementInForm:function(e,d){var b=e.up("form");if(b==d){return true}return false}};Object.extend(Validation,{validate:function(e,b){b=Object.extend({useTitle:false,onElementValidate:function(f,g){}},b||{});e=$(e);var d=$w(e.className);return result=d.all(function(f){var g=Validation.test(f,e,b.useTitle);b.onElementValidate(g,e);return g})},insertAdvice:function(f,d){var b=$(f).up(".field-row");if(b){Element.insert(b,{after:d})}else{if(f.up("td.value")){f.up("td.value").insert({bottom:d})}else{if(f.advaiceContainer&&$(f.advaiceContainer)){$(f.advaiceContainer).update(d)}else{switch(f.type.toLowerCase()){case"checkbox":case"radio":var e=f.parentNode;if(e){Element.insert(e,{bottom:d})}else{Element.insert(f,{after:d})}break;default:Element.insert(f,{after:d})}}}}},showAdvice:function(e,d,b){if(!e.advices){e.advices=new Hash()}else{e.advices.each(function(f){if(!d||f.value.id!=d.id){this.hideAdvice(e,f.value)}}.bind(this))}e.advices.set(b,d);if(typeof Effect=="undefined"){d.style.display="block"}else{if(!d._adviceAbsolutize){new Effect.Appear(d,{duration:1})}else{Position.absolutize(d);d.show();d.setStyle({top:d._adviceTop,left:d._adviceLeft,width:d._adviceWidth,"z-index":1000});d.addClassName("advice-absolute")}}},hideAdvice:function(d,b){if(b!=null){new Effect.Fade(b,{duration:1,afterFinishInternal:function(){b.hide()}})}},updateCallback:function(elm,status){if(typeof elm.callbackFunction!="undefined"){eval(elm.callbackFunction+"('"+elm.id+"','"+status+"')")}},ajaxError:function(g,f){var e="validate-ajax";var d=Validation.getAdvice(e,g);if(d==null){d=this.createAdvice(e,g,false,f)}this.showAdvice(g,d,"validate-ajax");this.updateCallback(g,"failed");g.addClassName("validation-failed");g.addClassName("validate-ajax");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=g.up(Validation.defaultOptions.containerClassName);if(b&&this.allowContainerClassName(g)){b.removeClassName("validation-passed");b.addClassName("validation-error")}}},allowContainerClassName:function(b){if(b.type=="radio"||b.type=="checkbox"){return b.hasClassName("change-container-classname")}return true},test:function(g,o,l){var d=Validation.get(g);var n="__advice"+g.camelize();try{if(Validation.isVisible(o)&&!d.test($F(o),o)){var f=Validation.getAdvice(g,o);if(f==null){f=this.createAdvice(g,o,l)}this.showAdvice(o,f,g);this.updateCallback(o,"failed");o[n]=1;if(!o.advaiceContainer){o.removeClassName("validation-passed");o.addClassName("validation-failed")}if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=o.up(Validation.defaultOptions.containerClassName);if(b&&this.allowContainerClassName(o)){b.removeClassName("validation-passed");b.addClassName("validation-error")}}return false}else{var f=Validation.getAdvice(g,o);this.hideAdvice(o,f);this.updateCallback(o,"passed");o[n]="";o.removeClassName("validation-failed");o.addClassName("validation-passed");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var b=o.up(Validation.defaultOptions.containerClassName);if(b&&!b.down(".validation-failed")&&this.allowContainerClassName(o)){if(!Validation.get("IsEmpty").test(o.value)||!this.isVisible(o)){b.addClassName("validation-passed")}else{b.removeClassName("validation-passed")}b.removeClassName("validation-error")}}return true}}catch(h){throw (h)}},isVisible:function(b){while(b.tagName!="BODY"){if(!$(b).visible()){return false}b=b.parentNode}return true},getAdvice:function(b,d){return $("advice-"+b+"-"+Validation.getElmID(d))||$("advice-"+Validation.getElmID(d))},createAdvice:function(e,n,l,d){var b=Validation.get(e);var h=l?((n&&n.title)?n.title:b.error):b.error;if(d){h=d}if(jQuery.mage.__){h=jQuery.mage.__(h)}advice='<div class="validation-advice" id="advice-'+e+"-"+Validation.getElmID(n)+'" style="display:none">'+h+"</div>";Validation.insertAdvice(n,advice);advice=Validation.getAdvice(e,n);if($(n).hasClassName("absolute-advice")){var g=$(n).getDimensions();var f=Position.cumulativeOffset(n);advice._adviceTop=(f[1]+g.height)+"px";advice._adviceLeft=(f[0])+"px";advice._adviceWidth=(g.width)+"px";advice._adviceAbsolutize=true}return advice},getElmID:function(b){return b.id?b.id:b.name},reset:function(d){d=$(d);var b=$w(d.className);b.each(function(g){var h="__advice"+g.camelize();if(d[h]){var f=Validation.getAdvice(g,d);if(f){f.hide()}d[h]=""}d.removeClassName("validation-failed");d.removeClassName("validation-passed");if(Validation.defaultOptions.addClassNameToContainer&&Validation.defaultOptions.containerClassName!=""){var e=d.up(Validation.defaultOptions.containerClassName);if(e){e.removeClassName("validation-passed");e.removeClassName("validation-error")}}})},add:function(f,e,g,d){var b={};b[f]=new Validator(f,e,g,d);Object.extend(Validation.methods,b)},addAllThese:function(b){var d={};$A(b).each(function(e){d[e[0]]=new Validator(e[0],e[1],e[2],(e.length>3?e[3]:{}))});Object.extend(Validation.methods,d)},get:function(b){return Validation.methods[b]?Validation.methods[b]:Validation.methods._LikeNoIDIEverSaw_},methods:{_LikeNoIDIEverSaw_:new Validator("_LikeNoIDIEverSaw_","",{})}});Validation.add("IsEmpty","",function(b){return(b==""||(b==null)||(b.length==0)||/^\s+$/.test(b))});Validation.addAllThese([["validate-no-html-tags","HTML tags are not allowed",function(b){return !/<(\/)?\w+/.test(b)}],["validate-select","Please select an option.",function(b){return((b!="none")&&(b!=null)&&(b.length!=0))}],["required-entry","This is a required field.",function(b){return !Validation.get("IsEmpty").test(b)}],["validate-number","Please enter a valid number in this field.",function(b){return Validation.get("IsEmpty").test(b)||(!isNaN(parseNumber(b))&&/^\s*-?\d*(\.\d*)?\s*$/.test(b))}],["validate-number-range","The value is not within the specified range.",function(e,g){if(Validation.get("IsEmpty").test(e)){return true}var f=parseNumber(e);if(isNaN(f)){return false}var d=/^number-range-(-?[\d.,]+)?-(-?[\d.,]+)?$/,b=true;$w(g.className).each(function(l){var h=d.exec(l);if(h){b=b&&(h[1]==null||h[1]==""||f>=parseNumber(h[1]))&&(h[2]==null||h[2]==""||f<=parseNumber(h[2]))}});return b}],["validate-digits","Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.",function(b){return Validation.get("IsEmpty").test(b)||!/[^\d]/.test(b)}],["validate-digits-range","The value is not within the specified range.",function(e,g){if(Validation.get("IsEmpty").test(e)){return true}var f=parseNumber(e);if(isNaN(f)){return false}var d=/^digits-range-(-?\d+)?-(-?\d+)?$/,b=true;$w(g.className).each(function(l){var h=d.exec(l);if(h){b=b&&(h[1]==null||h[1]==""||f>=parseNumber(h[1]))&&(h[2]==null||h[2]==""||f<=parseNumber(h[2]))}});return b}],["validate-range","The value is not within the specified range.",function(f,l){var g,h;if(Validation.get("IsEmpty").test(f)){return true}else{if(Validation.get("validate-digits").test(f)){g=h=parseNumber(f)}else{var e=/^(-?\d+)?-(-?\d+)?$/.exec(f);if(e){g=parseNumber(e[1]);h=parseNumber(e[2]);if(g>h){return false}}else{return false}}}var d=/^range-(-?\d+)?-(-?\d+)?$/,b=true;$w(l.className).each(function(n){var q=d.exec(n);if(q){var p=parseNumber(q[1]);var o=parseNumber(q[2]);b=b&&(isNaN(p)||g>=p)&&(isNaN(o)||h<=o)}});return b}],["validate-alpha","Please use letters only (a-z or A-Z) in this field.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z]+$/.test(b)}],["validate-code","Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-z]+[a-z0-9_]+$/.test(b)}],["validate-alphanum","Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z0-9]+$/.test(b)}],["validate-alphanum-with-spaces","Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.",function(b){return Validation.get("IsEmpty").test(b)||/^[a-zA-Z0-9 ]+$/.test(b)}],["validate-street",'Please use only letters (a-z or A-Z), numbers (0-9), spaces and "#" in this field.',function(b){return Validation.get("IsEmpty").test(b)||/^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(b)}],["validate-phoneStrict","Please enter a valid phone number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(b)}],["validate-phoneLax","Please enter a valid phone number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^((\d[-. ]?)?((\(\d{3}\))|\d{3}))?[-. ]?\d{3}[-. ]?\d{4}$/.test(b)}],["validate-fax","Please enter a valid fax number (Ex: 123-456-7890).",function(b){return Validation.get("IsEmpty").test(b)||/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(b)}],["validate-date","Please enter a valid date.",function(b){var d=new Date(b);return Validation.get("IsEmpty").test(b)||!isNaN(d)}],["validate-date-range","Make sure the To Date is later than or the same as the From Date.",function(e,h){var d=/\bdate-range-(\w+)-(\w+)\b/.exec(h.className);if(!d||d[2]=="to"||Validation.get("IsEmpty").test(e)){return true}var f=new Date().getFullYear()+"";var b=function(l){l=l.split(/[.\/]/);if(l[2]&&l[2].length<4){l[2]=f.substr(0,l[2].length)+l[2]}return new Date(l.join("/")).getTime()};var g=Element.select(h.form,".validate-date-range.date-range-"+d[1]+"-to");return !g.length||Validation.get("IsEmpty").test(g[0].value)||b(e)<=b(g[0].value)}],["validate-email","Please enter a valid email address (Ex: johndoe@domain.com).",function(b){return Validation.get("IsEmpty").test(b)||/^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(b)}],["validate-emailSender","Please use only visible characters and spaces.",function(b){return Validation.get("IsEmpty").test(b)||/^[\S ]+$/.test(b)}],["validate-password","Please enter 6 or more characters. Leading and trailing spaces will be ignored.",function(b){var d=b.strip();return !(d.length>0&&d.length<6)}],["validate-admin-password","Please enter 7 or more characters, using both numeric and alphabetic.",function(b){var d=b.strip();if(0==d.length){return true}if(!(/[a-z]/i.test(b))||!(/[0-9]/.test(b))){return false}return !(d.length<7)}],["validate-cpassword","Please make sure your passwords match.",function(b){var d=$("confirmation")?$("confirmation"):$$(".validate-cpassword")[0];var g=false;if($("password")){g=$("password")}var h=$$(".validate-password");for(var e=0;e<h.size();e++){var f=h[e];if(f.up("form").id==d.up("form").id){g=f}}if($$(".validate-admin-password").size()){g=$$(".validate-admin-password")[0]}return(g.value==d.value)}],["validate-both-passwords","Please make sure your passwords match.",function(e,d){var b=$(d.form[d.name=="password"?"confirmation":"password"]),f=d.value==b.value;if(f&&b.hasClassName("validation-failed")){Validation.test(this.className,b)}return b.value==""||f}],["validate-url","Please enter a valid URL. Protocol is required (http://, https:// or ftp://)",function(b){b=(b||"").replace(/^\s+/,"").replace(/\s+$/,"");return Validation.get("IsEmpty").test(b)||/^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i.test(b)}],["validate-clean-url",'Please enter a valid URL (Ex: "http://www.example.com" or "www.example.com").',function(b){return Validation.get("IsEmpty").test(b)||/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(b)||/^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(b)}],["validate-identifier",'Please enter a valid URL Key (Ex: "example-page", "example-page.html" or "anotherlevel/example-page").',function(b){return Validation.get("IsEmpty").test(b)||/^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/.test(b)}],["validate-xml-identifier","Please enter a valid XML-identifier (Ex: something_1, block5, id-4).",function(b){return Validation.get("IsEmpty").test(b)||/^[A-Z][A-Z0-9_\/-]*$/i.test(b)}],["validate-ssn","Please enter a valid social security number (Ex: 123-45-6789).",function(b){return Validation.get("IsEmpty").test(b)||/^\d{3}-?\d{2}-?\d{4}$/.test(b)}],["validate-zip-us","Please enter a valid zip code (Ex: 90602 or 90602-1234).",function(b){return Validation.get("IsEmpty").test(b)||/(^\d{5}$)|(^\d{5}-\d{4}$)/.test(b)}],["validate-zip-international","Please enter a valid zip code.",function(b){return true}],["validate-date-au",'Please use this date format: dd/mm/yyyy (Ex: "17/03/2006" for the 17th of March, 2006).',function(b){if(Validation.get("IsEmpty").test(b)){return true}var e=/^(\d{2})\/(\d{2})\/(\d{4})$/;if(!e.test(b)){return false}var f=new Date(b.replace(e,"$2/$1/$3"));return(parseInt(RegExp.$2,10)==(1+f.getMonth()))&&(parseInt(RegExp.$1,10)==f.getDate())&&(parseInt(RegExp.$3,10)==f.getFullYear())}],["validate-currency-dollar","Please enter a valid $ amount (Ex: $100.00).",function(b){return Validation.get("IsEmpty").test(b)||/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(b)}],["validate-one-required","Please select one of the options above.",function(b,f){var e=f.parentNode;var d=e.getElementsByTagName("INPUT");return $A(d).any(function(g){return $F(g)})}],["validate-one-required-by-name","Please select one of the options.",function(d,g){var b=$$('input[name="'+g.name.replace(/([\\"])/g,"\\$1")+'"]');var e=1;for(var f=0;f<b.length;f++){if((b[f].type=="checkbox"||b[f].type=="radio")&&b[f].checked==true){e=0}if(Validation.isOnChange&&(b[f].type=="checkbox"||b[f].type=="radio")){Validation.reset(b[f])}}if(e==0){return true}else{return false}}],["validate-not-negative-number","Please enter a number 0 or greater in this field.",function(b){if(Validation.get("IsEmpty").test(b)){return true}b=parseNumber(b);return !isNaN(b)&&b>=0}],["validate-zero-or-greater","Please enter a number 0 or greater in this field.",function(b){return Validation.get("validate-not-negative-number").test(b)}],["validate-greater-than-zero","Please enter a number greater than 0 in this field.",function(b){if(Validation.get("IsEmpty").test(b)){return true}b=parseNumber(b);return !isNaN(b)&&b>0}],["validate-state","Please select State/Province.",function(b){return(b!=0||b=="")}],["validate-new-password","Please enter 6 or more characters. Leading and trailing spaces will be ignored.",function(b){if(!Validation.get("validate-password").test(b)){return false}if(Validation.get("IsEmpty").test(b)&&b!=""){return false}return true}],["validate-cc-number","Please enter a valid credit card number.",function(b,e){var d=$(e.id.substr(0,e.id.indexOf("_cc_number"))+"_cc_type");if(d&&typeof Validation.creditCartTypes.get(d.value)!="undefined"&&Validation.creditCartTypes.get(d.value)[2]==false){if(!Validation.get("IsEmpty").test(b)&&Validation.get("validate-digits").test(b)){return true}else{return false}}return validateCreditCard(b)}],["validate-cc-type","Credit card number does not match credit card type.",function(d,g){g.value=removeDelimiters(g.value);d=removeDelimiters(d);var f=$(g.id.substr(0,g.id.indexOf("_cc_number"))+"_cc_type");if(!f){return true}var e=f.value;if(typeof Validation.creditCartTypes.get(e)=="undefined"){return false}if(Validation.creditCartTypes.get(e)[0]==false){return true}var b="";Validation.creditCartTypes.each(function(h){if(h.value[0]&&d.match(h.value[0])){b=h.key;throw $break}});if(b!=e){return false}if(f.hasClassName("validation-failed")&&Validation.isOnChange){Validation.validate(f)}return true}],["validate-cc-type-select","Card type does not match credit card number.",function(d,e){var b=$(e.id.substr(0,e.id.indexOf("_cc_type"))+"_cc_number");if(Validation.isOnChange&&Validation.get("IsEmpty").test(b.value)){return true}if(Validation.get("validate-cc-type").test(b.value,b)){Validation.validate(b)}return Validation.get("validate-cc-type").test(b.value,b)}],["validate-cc-exp","Incorrect credit card expiration date.",function(b,l){var h=b;var g=$(l.id.substr(0,l.id.indexOf("_expiration"))+"_expiration_yr").value;var f=new Date();var e=f.getMonth()+1;var d=f.getFullYear();if(h<e&&g==d){return false}return true}],["validate-cc-cvn","Please enter a valid credit card verification number.",function(b,g){var f=$(g.id.substr(0,g.id.indexOf("_cc_cid"))+"_cc_type");if(!f){return true}var d=f.value;if(typeof Validation.creditCartTypes.get(d)=="undefined"){return false}var e=Validation.creditCartTypes.get(d)[1];if(b.match(e)){return true}return false}],["validate-ajax","",function(b,d){return true}],["validate-data","Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.",function(b){if(b!=""&&b){return/^[A-Za-z]+[A-Za-z0-9_]+$/.test(b)}return true}],["validate-css-length","Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).",function(b){if(b!=""&&b){return/^[0-9\.]+(px|pt|em|ex|%)?$/.test(b)&&(!(/\..*\./.test(b)))&&!(/\.$/.test(b))}return true}],["validate-length","Text length does not meet the specified text range.",function(d,g){var e=new RegExp(/^maximum-length-[0-9]+$/);var f=new RegExp(/^minimum-length-[0-9]+$/);var b=true;$w(g.className).each(function(l,h){if(l.match(e)&&b){var n=l.split("-")[2];b=(d.length<=n)}if(l.match(f)&&b&&!Validation.get("IsEmpty").test(d)){var n=l.split("-")[2];b=(d.length>=n)}});return b}],["validate-percents","Please enter a number lower than 100.",{max:100}],["required-file","Please select a file.",function(d,e){var b=!Validation.get("IsEmpty").test(d);if(b===false){ovId=e.id+"_value";if($(ovId)){b=!Validation.get("IsEmpty").test($(ovId).value)}}return b}],["validate-cc-ukss","Please enter issue number or start date for switch/solo card type.",function(o,g){var b;if(g.id.match(/(.)+_cc_issue$/)){b=g.id.indexOf("_cc_issue")}else{if(g.id.match(/(.)+_start_month$/)){b=g.id.indexOf("_start_month")}else{b=g.id.indexOf("_start_year")}}var f=g.id.substr(0,b);var d=$(f+"_cc_type");if(!d){return true}var n=d.value;if(["SS","SM","SO"].indexOf(n)==-1){return true}$(f+"_cc_issue").advaiceContainer=$(f+"_start_month").advaiceContainer=$(f+"_start_year").advaiceContainer=$(f+"_cc_type_ss_div").down(".adv-container");var h=$(f+"_cc_issue").value;var l=$(f+"_start_month").value;var p=$(f+"_start_year").value;var e=(l&&p)?true:false;if(!e&&!h){return false}return true}]]);function removeDelimiters(b){b=b.replace(/\s/g,"");b=b.replace(/\-/g,"");return b}function parseNumber(b){if(typeof b!="string"){return parseFloat(b)}var e=b.indexOf(".");var d=b.indexOf(",");if(e!=-1&&d!=-1){if(d>e){b=b.replace(".","").replace(",",".")}else{b=b.replace(",","")}}else{if(d!=-1){b=b.replace(",",".")}}return parseFloat(b)}Validation.creditCartTypes=$H({SO:[new RegExp("^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$"),new RegExp("^([0-9]{3}|[0-9]{4})?$"),true],SM:[new RegExp("(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|(^(4936)([0-9]{12}$|[0-9]{14,15}$))"),new RegExp("^([0-9]{3}|[0-9]{4})?$"),true],VI:[new RegExp("^4[0-9]{12}([0-9]{3})?$"),new RegExp("^[0-9]{3}$"),true],MC:[new RegExp("^5[1-5][0-9]{14}$"),new RegExp("^[0-9]{3}$"),true],AE:[new RegExp("^3[47][0-9]{13}$"),new RegExp("^[0-9]{4}$"),true],DI:[new RegExp("^6(011|4[4-9][0-9]|5[0-9]{2})[0-9]{12}$"),new RegExp("^[0-9]{3}$"),true],JCB:[new RegExp("^(3[0-9]{15}|(2131|1800)[0-9]{11})$"),new RegExp("^[0-9]{3,4}$"),true],OT:[false,new RegExp("^([0-9]{3}|[0-9]{4})?$"),false]});function popWin(d,e,b){var e=window.open(d,e,b);e.focus()}function setLocation(b){window.location.href=b}function setPLocation(d,b){if(b){window.opener.focus()}window.opener.location.href=d}function setLanguageCode(e,f){var b=window.location.href;var h="",g;if(g=b.match(/\#(.*)$/)){b=b.replace(/\#(.*)$/,"");h=g[0]}if(b.match(/[?]/)){var d=/([?&]store=)[a-z0-9_]*/;if(b.match(d)){b=b.replace(d,"$1"+e)}else{b+="&store="+e}var d=/([?&]from_store=)[a-z0-9_]*/;if(b.match(d)){b=b.replace(d,"")}}else{b+="?store="+e}if(typeof f!="undefined"){b+="&from_store="+f}b+=h;setLocation(b)}function decorateGeneric(h,e){var l=["odd","even","first","last"];var d={};var g=h.length;if(g){if(typeof e=="undefined"){e=l}if(!e.length){return}for(var b in l){d[l[b]]=false}for(var b in e){d[e[b]]=true}if(d.first){Element.addClassName(h[0],"first")}if(d.last){Element.addClassName(h[g-1],"last")}for(var f=0;f<g;f++){if((f+1)%2==0){if(d.even){Element.addClassName(h[f],"even")}}else{if(d.odd){Element.addClassName(h[f],"odd")}}}}}function decorateTable(h,e){var h=$(h);if(h){var b={tbody:false,"tbody tr":["odd","even","first","last"],"thead tr":["first","last"],"tfoot tr":["first","last"],"tr td":["last"]};if(typeof e!="undefined"){for(var d in e){b[d]=e[d]}}if(b.tbody){decorateGeneric(h.select("tbody"),b.tbody)}if(b["tbody tr"]){decorateGeneric(h.select("tbody tr"),b["tbody tr"])}if(b["thead tr"]){decorateGeneric(h.select("thead tr"),b["thead tr"])}if(b["tfoot tr"]){decorateGeneric(h.select("tfoot tr"),b["tfoot tr"])}if(b["tr td"]){var g=h.select("tr");if(g.length){for(var f=0;f<g.length;f++){decorateGeneric(g[f].getElementsByTagName("TD"),b["tr td"])}}}}}function decorateList(e,d){if($(e)){if(typeof d=="undefined"){var b=$(e).select("li")}else{var b=$(e).childElements()}decorateGeneric(b,["odd","even","last"])}}function decorateDataList(b){b=$(b);if(b){decorateGeneric(b.select("dt"),["odd","even","last"]);decorateGeneric(b.select("dd"),["odd","even","last"])}}function parseSidUrl(f,e){var d=f.indexOf("/?SID=");var b="";e=e!=undefined?e:"";if(d>-1){b="?"+f.substring(d+2);f=f.substring(0,d+1)}return f+e+b}function formatCurrency(n,q,g){var l=isNaN(q.precision=Math.abs(q.precision))?2:q.precision;var v=isNaN(q.requiredPrecision=Math.abs(q.requiredPrecision))?2:q.requiredPrecision;l=v;var t=isNaN(q.integerRequired=Math.abs(q.integerRequired))?1:q.integerRequired;var p=q.decimalSymbol==undefined?",":q.decimalSymbol;var e=q.groupSymbol==undefined?".":q.groupSymbol;var d=q.groupLength==undefined?3:q.groupLength;var u="";if(g==undefined||g==true){u=n<0?"-":g?"+":""}else{if(g==false){u=""}}var h=parseInt(n=Math.abs(+n||0).toFixed(l))+"";var f=h.length<t?t-h.length:0;while(f){h="0"+h;f--}j=(j=h.length)>d?j%d:0;re=new RegExp("(\\d{"+d+"})(?=\\d)","g");var b=(j?h.substr(0,j)+e:"")+h.substr(j).replace(re,"$1"+e)+(l?p+Math.abs(n-h).toFixed(l).replace(/-/,0).slice(2):"");var o="";if(q.pattern.indexOf("{sign}")==-1){o=u+q.pattern}else{o=q.pattern.replace("{sign}",u)}return o.replace("%s",b).replace(/^\s\s*/,"").replace(/\s\s*$/,"")}function expandDetails(d,b){if(Element.hasClassName(d,"show-details")){$$(b).each(function(e){e.hide()});Element.removeClassName(d,"show-details")}else{$$(b).each(function(e){e.show()});Element.addClassName(d,"show-details")}}var isIE=navigator.appVersion.match(/MSIE/)=="MSIE";if(!window.Varien){var Varien=new Object()}Varien.showLoading=function(){var b=$("loading-process");b&&b.show()};Varien.hideLoading=function(){var b=$("loading-process");b&&b.hide()};Varien.GlobalHandlers={onCreate:function(){Varien.showLoading()},onComplete:function(){if(Ajax.activeRequestCount==0){Varien.hideLoading()}}};Ajax.Responders.register(Varien.GlobalHandlers);Varien.searchForm=Class.create();Varien.searchForm.prototype={initialize:function(d,e,b){this.form=$(d);this.field=$(e);this.emptyText=b;Event.observe(this.form,"submit",this.submit.bind(this));Event.observe(this.field,"focus",this.focus.bind(this));Event.observe(this.field,"blur",this.blur.bind(this));this.blur()},submit:function(b){if(this.field.value==this.emptyText||this.field.value==""){Event.stop(b);return false}return true},focus:function(b){if(this.field.value==this.emptyText){this.field.value=""}},blur:function(b){if(this.field.value==""){this.field.value=this.emptyText}}};Varien.DateElement=Class.create();Varien.DateElement.prototype={initialize:function(b,d,f,e){if(b=="id"){this.day=$(d+"day");this.month=$(d+"month");this.year=$(d+"year");this.full=$(d+"full");this.advice=$(d+"date-advice")}else{if(b=="container"){this.day=d.day;this.month=d.month;this.year=d.year;this.full=d.full;this.advice=d.advice}else{return}}this.required=f;this.format=e;this.day.addClassName("validate-custom");this.day.validate=this.validate.bind(this);this.month.addClassName("validate-custom");this.month.validate=this.validate.bind(this);this.year.addClassName("validate-custom");this.year.validate=this.validate.bind(this);this.setDateRange(false,false);this.year.setAttribute("autocomplete","off");this.advice.hide()},validate:function(){var l=false,o=parseInt(this.day.value,10)||0,f=parseInt(this.month.value,10)||0,h=parseInt(this.year.value,10)||0;if(this.day.value.strip().empty()&&this.month.value.strip().empty()&&this.year.value.strip().empty()){if(this.required){l="Please enter a date."}else{this.full.value=""}}else{if(!o||!f||!h){l="Please enter a valid full date."}else{var d=new Date,n=0,e=null;d.setYear(h);d.setMonth(f-1);d.setDate(32);n=32-d.getDate();if(!n||n>31){n=31}if(o<1||o>n){e="day";l="Please enter a valid day (1-%1)."}else{if(f<1||f>12){e="month";l="Please enter a valid month (1-12)."}else{if(o%10==o){this.day.value="0"+o}if(f%10==f){this.month.value="0"+f}this.full.value=this.format.replace(/%[mb]/i,this.month.value).replace(/%[de]/i,this.day.value).replace(/%y/i,this.year.value);var b=this.month.value+"/"+this.day.value+"/"+this.year.value;var g=new Date(b);if(isNaN(g)){l="Please enter a valid date."}else{this.setFullDate(g)}}}var p=false;if(!l&&!this.validateData()){e=this.validateDataErrorType;p=this.validateDataErrorText;l=p}}}if(l!==false){if(jQuery.mage.__){l=jQuery.mage.__(l)}if(!p){this.advice.innerHTML=l.replace("%1",n)}else{this.advice.innerHTML=this.errorTextModifier(l)}this.advice.show();return false}this.day.removeClassName("validation-failed");this.month.removeClassName("validation-failed");this.year.removeClassName("validation-failed");this.advice.hide();return true},validateData:function(){var d=this.fullDate.getFullYear();var b=new Date;this.curyear=b.getFullYear();return d>=1900&&d<=this.curyear},validateDataErrorType:"year",validateDataErrorText:"Please enter a valid year (1900-%1).",errorTextModifier:function(b){return b.replace("%1",this.curyear)},setDateRange:function(b,d){this.minDate=b;this.maxDate=d},setFullDate:function(b){this.fullDate=b}};Varien.DOB=Class.create();Varien.DOB.prototype={initialize:function(b,g,f){var e=$$(b)[0];var d={};d.day=Element.select(e,".dob-day input")[0];d.month=Element.select(e,".dob-month input")[0];d.year=Element.select(e,".dob-year input")[0];d.full=Element.select(e,".dob-full input")[0];d.advice=Element.select(e,".validation-advice")[0];new Varien.DateElement("container",d,g,f)}};Varien.dateRangeDate=Class.create();Varien.dateRangeDate.prototype=Object.extend(new Varien.DateElement(),{validateData:function(){var b=true;if(this.minDate||this.maxValue){if(this.minDate){this.minDate=new Date(this.minDate);this.minDate.setHours(0);if(isNaN(this.minDate)){this.minDate=new Date("1/1/1900")}b=b&&this.fullDate>=this.minDate}if(this.maxDate){this.maxDate=new Date(this.maxDate);this.minDate.setHours(0);if(isNaN(this.maxDate)){this.maxDate=new Date()}b=b&&this.fullDate<=this.maxDate}if(this.maxDate&&this.minDate){this.validateDataErrorText="Please enter a valid date between %s and %s"}else{if(this.maxDate){this.validateDataErrorText="Please enter a valid date less than or equal to %s"}else{if(this.minDate){this.validateDataErrorText="Please enter a valid date equal to or greater than %s"}else{this.validateDataErrorText=""}}}}return b},validateDataErrorText:"Date should be between %s and %s",errorTextModifier:function(b){if(this.minDate){b=b.sub("%s",this.dateFormat(this.minDate))}if(this.maxDate){b=b.sub("%s",this.dateFormat(this.maxDate))}return b},dateFormat:function(b){return b.getMonth()+1+"/"+b.getDate()+"/"+b.getFullYear()}});Varien.FileElement=Class.create();Varien.FileElement.prototype={initialize:function(b){this.fileElement=$(b);this.hiddenElement=$(b+"_value");this.fileElement.observe("change",this.selectFile.bind(this))},selectFile:function(b){this.hiddenElement.value=this.fileElement.getValue()}};Validation.addAllThese([["validate-custom"," ",function(b,d){return d.validate()}]]);Element.addMethods({getInnerText:function(b){b=$(b);if(b.innerText&&!Prototype.Browser.Opera){return b.innerText}return b.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g," ").strip()}});function fireEvent(d,e){if(document.createEvent){var b=document.createEvent("HTMLEvents");b.initEvent(e,true,true);return d.dispatchEvent(b)}var b=document.createEventObject();return d.fireEvent("on"+e,b)}function modulo(b,f){var e=f/10000;var d=b%f;if(Math.abs(d-f)<e||Math.abs(d)<e){d=0}return d}if(typeof Range!="undefined"&&!Range.prototype.createContextualFragment){Range.prototype.createContextualFragment=function(b){var e=document.createDocumentFragment(),d=document.createElement("div");e.appendChild(d);d.outerHTML=b;return e}}var byteConvert=function(b){if(isNaN(b)){return""}var d=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"];var f=Math.floor(Math.log(b)/Math.log(2));if(f<1){f=0}var e=Math.floor(f/10);b/=Math.pow(2,10*e);if(b.toString().length>b.toFixed(2).toString().length){b=b.toFixed(2)}return b+" "+d[e]};var SessionError=Class.create();SessionError.prototype={initialize:function(b){this.errorText=b},toString:function(){return"Session Error:"+this.errorText}};Ajax.Request.addMethods({initialize:function($super,d,b){$super(b);this.transport=Ajax.getTransport();if(!d.match(new RegExp("[?&]isAjax=true",""))){d=d.match(new RegExp("\\?","g"))?d+"&isAjax=true":d+"?isAjax=true"}if(Object.isString(this.options.parameters)&&this.options.parameters.indexOf("form_key=")==-1){this.options.parameters+="&"+Object.toQueryString({form_key:FORM_KEY})}else{if(!this.options.parameters){this.options.parameters={form_key:FORM_KEY}}if(!this.options.parameters.form_key){this.options.parameters.form_key=FORM_KEY}}this.request(d)},respondToReadyState:function(b){var g=Ajax.Request.Events[b],d=new Ajax.Response(this);if(g=="Complete"){try{this._complete=true;if(d.responseText.isJSON()){var f=d.responseText.evalJSON();if(f.ajaxExpired&&f.ajaxRedirect){window.location.replace(f.ajaxRedirect);throw new SessionError("session expired")}}(this.options["on"+d.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(d,d.headerJSON)}catch(h){this.dispatchException(h);if(h instanceof SessionError){return}}var l=d.getHeader("Content-type");if(this.options.evalJS=="force"||this.options.evalJS&&this.isSameOrigin()&&l&&l.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)){this.evalResponse()}}try{(this.options["on"+g]||Prototype.emptyFunction)(d,d.headerJSON);Ajax.Responders.dispatch("on"+g,this,d,d.headerJSON)}catch(h){this.dispatchException(h)}if(g=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}}});Ajax.Updater.respondToReadyState=Ajax.Request.respondToReadyState;var varienLoader=new Class.create();varienLoader.prototype={initialize:function(b){this.callback=false;this.cache=$H();this.caching=b||false;this.url=false},getCache:function(b){if(this.cache.get(b)){return this.cache.get(b)}return false},load:function(b,d,f){this.url=b;this.callback=f;if(this.caching){var e=this.getCache(b);if(e){this.processResult(e);return}}if(typeof d.updaterId!="undefined"){new varienUpdater(d.updaterId,b,{evalScripts:true,onComplete:this.processResult.bind(this),onFailure:this._processFailure.bind(this)})}else{new Ajax.Request(b,{method:"post",parameters:d||{},onComplete:this.processResult.bind(this),onFailure:this._processFailure.bind(this)})}},_processFailure:function(b){location.href=BASE_URL},processResult:function(b){if(this.caching){this.cache.set(this.url,b)}if(this.callback){this.callback(b.responseText)}}};if(!window.varienLoaderHandler){var varienLoaderHandler=new Object()}varienLoaderHandler.handler={onCreate:function(b){if(b.options.loaderArea===false){return}jQuery("body").trigger("processStart")},onException:function(b){jQuery("body").trigger("processStop")},onComplete:function(b){jQuery("body").trigger("processStop")}};function setLoaderPosition(){var e=$("loading_mask_loader");if(e&&Prototype.Browser.IE){var d=e.getDimensions();var f=document.viewport.getDimensions();var b=document.viewport.getScrollOffsets();e.style.left=Math.floor(f.width/2+b.left-d.width/2)+"px";e.style.top=Math.floor(f.height/2+b.top-d.height/2)+"px";e.style.position="absolute"}}function toggleSelectsUnderBlock(f,b){if(Prototype.Browser.IE){var e=document.getElementsByTagName("select");for(var d=0;d<e.length;d++){if(b){if(e[d].needShowOnSuccess){e[d].needShowOnSuccess=false;e[d].style.visibility=""}}else{if(Element.visible(e[d])){e[d].style.visibility="hidden";e[d].needShowOnSuccess=true}}}}}Ajax.Responders.register(varienLoaderHandler.handler);var varienUpdater=Class.create(Ajax.Updater,{updateContent:function($super,b){if(b.isJSON()){var d=b.evalJSON();if(d.ajaxExpired&&d.ajaxRedirect){window.location.replace(d.ajaxRedirect)}}else{$super(b)}}});function setLocation(b){window.location.href=b}function setElementDisable(d,b){if($(d)){$(d).disabled=b}}function toggleParentVis(b){b=$(b).parentNode;if(b.style.display=="none"){b.style.display=""}else{b.style.display="none"}}function toggleFieldsetVis(d){id=d;d=$(d);if(d.style.display=="none"){d.style.display=""}else{d.style.display="none"}d=d.parentNode.childElements();for(var b=0;b<d.length;b++){if(d[b].id!=undefined&&d[b].id==id&&d[b-1].classNames()=="entry-edit-head"){if(d[b-1].style.display=="none"){d[b-1].style.display=""}else{d[b-1].style.display="none"}}}}function toggleVis(b){b=$(b);if(b.style.display=="none"){b.style.display=""}else{b.style.display="none"}}function imagePreview(b){if($(b)){var d=window.open("","preview","width=400,height=400,resizable=1,scrollbars=1");d.document.open();d.document.write('<body style="padding:0;margin:0"><img src="'+$(b).src+'" id="image_preview"/></body>');d.document.close();Event.observe(d,"load",function(){var e=d.document.getElementById("image_preview");d.resizeTo(e.width+40,e.height+80)})}}function checkByProductPriceType(b){if(b.id=="price_type"){this.productPriceType=b.value;return false}if(b.id=="price"&&this.productPriceType==0){return false}return true}function toggleSeveralValueElements(f,e,b,d){if(e&&f){if(Object.prototype.toString.call(e)!="[object Array]"){e=[e]}e.each(function(g){toggleValueElements(f,g,b,d)})}}function toggleValueElements(l,d,f,h){if(d&&l){var n=[l];if(typeof f!="undefined"){if(Object.prototype.toString.call(f)!="[object Array]"){f=[f]}for(var g=0;g<f.length;g++){n.push(f[g])}}var e=Element.select(d,["select","input","textarea","button","img"]).filter(function(o){return o.readAttribute("type")!="hidden"});var b=h!=undefined?h:l.checked;e.each(function(p){if(checkByProductPriceType(p)){var o=n.length;while(o--&&p!=n[o]){}if(o!=-1){return}p.disabled=b;if(b){p.addClassName("disabled")}else{p.removeClassName("disabled")}if(p.nodeName.toLowerCase()=="img"){b?p.hide():p.show()}}})}}function submitAndReloadArea(e,d){if($(e)){var b=$(e).select("input","select","textarea");var f=Form.serializeElements(b,true);d+=d.match(new RegExp("\\?"))?"&isAjax=true":"?isAjax=true";new Ajax.Request(d,{parameters:$H(f),loaderArea:e,onSuccess:function(l){try{if(l.responseText.isJSON()){var g=l.responseText.evalJSON();if(g.error){alert(g.message)}if(g.ajaxExpired&&g.ajaxRedirect){setLocation(g.ajaxRedirect)}}else{$(e).update(l.responseText)}}catch(h){$(e).update(l.responseText)}}})}}function syncOnchangeValue(d,e){var b={baseElem:d,distElem:e};Event.observe(d,"change",function(){if($(this.baseElem)&&$(this.distElem)){$(this.distElem).value=$(this.baseElem).value}}.bind(b))}function updateElementAtCursor(e,f,g){if(g==undefined){g=window.self}if(document.selection){e.focus();sel=g.document.selection.createRange();sel.text=f}else{if(e.selectionStart||e.selectionStart=="0"){var d=e.selectionStart;var b=e.selectionEnd;e.value=e.value.substring(0,d)+f+e.value.substring(b,e.value.length)}else{e.value+=f}}}function firebugEnabled(){if(window.console&&window.console.firebug){return true}return false}function disableElement(b){b.disabled=true;b.addClassName("disabled")}function enableElement(b){b.disabled=false;b.removeClassName("disabled")}function disableElements(b){$$("."+b).each(disableElement)}function enableElements(b){$$("."+b).each(enableElement)}var Cookie={all:function(){var d=document.cookie.split(";");var b={};d.each(function(f,e){var g=f.strip().split("=");b[unescape(g[0])]=unescape(g[1])});return b},read:function(d){var b=this.all();if(b[d]){return b[d]}return null},write:function(h,f,g){var b="";if(g){var e=new Date();e.setTime(e.getTime()+g*1000);b="; expires="+e.toUTCString()}var d="/"+BASE_URL.split("/").slice(3).join("/");document.cookie=escape(h)+"="+escape(f)+b+"; path="+d},clear:function(b){this.write(b,"",-1)}};var Fieldset={cookiePrefix:"fh-",applyCollapse:function(b){if($(b+"-state")){collapsed=$(b+"-state").value==1?0:1}else{collapsed=$(b+"-head").collapsed}if(collapsed==1||collapsed===undefined){$(b+"-head").removeClassName("open");if($(b+"-head").up(".section-config")){$(b+"-head").up(".section-config").removeClassName("active")}$(b).hide()}else{$(b+"-head").addClassName("open");if($(b+"-head").up(".section-config")){$(b+"-head").up(".section-config").addClassName("active")}$(b).show()}},toggleCollapse:function(b,d){if($(b+"-state")){collapsed=$(b+"-state").value==1?0:1}else{collapsed=$(b+"-head").collapsed}if(collapsed==1||collapsed===undefined){if($(b+"-state")){$(b+"-state").value=1}$(b+"-head").collapsed=0}else{if($(b+"-state")){$(b+"-state").value=0}$(b+"-head").collapsed=1}this.applyCollapse(b);if(typeof d!="undefined"){this.saveState(d,{container:b,value:$(b+"-state").value})}},addToPrefix:function(b){this.cookiePrefix+=b+"-"},saveState:function(b,d){new Ajax.Request(b,{method:"get",parameters:Object.toQueryString(d),loaderArea:false})}};var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var b="";var p,n,h,o,l,g,f;var d=0;e=Base64._utf8_encode(e);if(typeof window.btoa==="function"){return window.btoa(e)}while(d<e.length){p=e.charCodeAt(d++);n=e.charCodeAt(d++);h=e.charCodeAt(d++);o=p>>2;l=(p&3)<<4|n>>4;g=(n&15)<<2|h>>6;f=h&63;if(isNaN(n)){g=f=64}else{if(isNaN(h)){f=64}}b=b+this._keyStr.charAt(o)+this._keyStr.charAt(l)+this._keyStr.charAt(g)+this._keyStr.charAt(f)}return b},decode:function(e){var b="";var p,n,h;var o,l,g,f;var d=0;if(typeof window.atob==="function"){return Base64._utf8_decode(window.atob(e))}e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(d<e.length){o=this._keyStr.indexOf(e.charAt(d++));l=this._keyStr.indexOf(e.charAt(d++));g=this._keyStr.indexOf(e.charAt(d++));f=this._keyStr.indexOf(e.charAt(d++));p=o<<2|l>>4;n=(l&15)<<4|g>>2;h=(g&3)<<6|f;b+=String.fromCharCode(p);if(g!=64){b+=String.fromCharCode(n)}if(f!=64){b+=String.fromCharCode(h)}}return Base64._utf8_decode(b)},mageEncode:function(b){return this.encode(b).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,",")},mageDecode:function(b){b=b.replace(/\-/g,"+").replace(/_/g,"/").replace(/,/g,"=");return this.decode(b)},idEncode:function(b){return this.encode(b).replace(/\+/g,":").replace(/\//g,"_").replace(/=/g,"-")},idDecode:function(b){b=b.replace(/\-/g,"=").replace(/_/g,"/").replace(/\:/g,"+");return this.decode(b)},_utf8_encode:function(d){d=d.replace(/\r\n/g,"\n");var b="";for(var f=0;f<d.length;f++){var e=d.charCodeAt(f);if(e<128){b+=String.fromCharCode(e)}else{if(e>127&&e<2048){b+=String.fromCharCode(e>>6|192);b+=String.fromCharCode(e&63|128)}else{b+=String.fromCharCode(e>>12|224);b+=String.fromCharCode(e>>6&63|128);b+=String.fromCharCode(e&63|128)}}}return b},_utf8_decode:function(b){var d="";var e=0;var f=c1=c2=0;while(e<b.length){f=b.charCodeAt(e);if(f<128){d+=String.fromCharCode(f);e++}else{if(f>191&&f<224){c2=b.charCodeAt(e+1);d+=String.fromCharCode((f&31)<<6|c2&63);e+=2}else{c2=b.charCodeAt(e+1);c3=b.charCodeAt(e+2);d+=String.fromCharCode((f&15)<<12|(c2&63)<<6|c3&63);e+=3}}}return d}};function sortNumeric(d,b){return d-b}(function(){var globals=["Prototype","Abstract","Try","Class","PeriodicalExecuter","Template","$break","Enumerable","$A","$w","$H","Hash","$R","ObjectRange","Ajax","$","Form","Field","$F","Toggle","Insertion","$continue","Position","Windows","Dialog","array","WindowUtilities","Builder","Effect","validateCreditCard","Validator","Validation","removeDelimiters","parseNumber","popWin","setLocation","setPLocation","setLanguageCode","decorateGeneric","decorateTable","decorateList","decorateDataList","parseSidUrl","formatCurrency","expandDetails","isIE","Varien","fireEvent","modulo","byteConvert","SessionError","varienLoader","varienLoaderHandler","setLoaderPosition","toggleSelectsUnderBlock","varienUpdater","setElementDisable","toggleParentVis","toggleFieldsetVis","toggleVis","imagePreview","checkByProductPriceType","toggleSeveralValueElements","toggleValueElements","submitAndReloadArea","syncOnchangeValue","updateElementAtCursor","firebugEnabled","disableElement","enableElement","disableElements","enableElements","Cookie","Fieldset","Base64","sortNumeric","Element","$$","Sizzle","Selector","Window"];globals.forEach(function(prop){window[prop]=eval(prop)})})(); \ No newline at end of file diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index d08819ebe94aa..cb45f73f79421 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -982,7 +982,7 @@ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-z]+[a-z0-9_]+$/.test(v); }, - $.mage.__('Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len + $.mage.__('Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len ], 'validate-alphanum': [ function (v) { diff --git a/lib/web/prototype/validation.js b/lib/web/prototype/validation.js index 616d49496e2a7..3cc0f6d8bc6ac 100644 --- a/lib/web/prototype/validation.js +++ b/lib/web/prototype/validation.js @@ -513,7 +513,7 @@ Validation.addAllThese([ ['validate-alpha', 'Please use letters only (a-z or A-Z) in this field.', function (v) { return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v) }], - ['validate-code', 'Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.', function (v) { + ['validate-code', 'Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.', function (v) { return Validation.get('IsEmpty').test(v) || /^[a-z]+[a-z0-9_]+$/.test(v) }], ['validate-alphanum', 'Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.', function(v) { From 199b2c44e8471a8f1e1794a28ca39873dcc5b8ac Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Mon, 27 Aug 2018 20:32:17 +0300 Subject: [PATCH 0031/1415] MAGETWO-91532: Copy tier price for copied products --- .../Attribute/Backend/GroupPrice/AbstractGroupPrice.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index 3779cab431cb7..944d78f79ca34 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -392,11 +392,13 @@ public function afterSave($object) $old = []; $new = []; + $linkFieldName = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(); // prepare original data for compare $origPrices = $object->getOrigData($this->getAttribute()->getName()); - if (!is_array($origPrices)) { + if (!is_array($origPrices) || $object->getData($linkFieldName) != $object->getOrigData($linkFieldName)) { $origPrices = []; } + foreach ($origPrices as $data) { if ($data['website_id'] > 0 || $data['website_id'] == '0' && $isGlobal) { $key = implode( @@ -454,7 +456,7 @@ public function afterSave($object) $update = array_intersect_key($new, $old); $isChanged = false; - $productId = $object->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()); + $productId = $object->getData($linkFieldName); if (!empty($delete)) { foreach ($delete as $data) { @@ -467,7 +469,7 @@ public function afterSave($object) foreach ($insert as $data) { $price = new \Magento\Framework\DataObject($data); $price->setData( - $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(), + $linkFieldName, $productId ); $this->_getResource()->savePriceData($price); From 9ef1afe6ae278615c23c0deb73b9fdd5f16b1b07 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 28 Aug 2018 17:56:51 +0300 Subject: [PATCH 0032/1415] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Used right model to observe gift wrapping options. --- .../GiftMessage/view/frontend/web/js/view/gift-message.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js b/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js index d025f6974f35e..4c455c83a77a9 100644 --- a/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js +++ b/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js @@ -31,8 +31,9 @@ define([ this.itemId = this.itemId || 'orderLevel'; model = new GiftMessage(this.itemId); - giftOptions.addOption(model); this.model = model; + this.isResultBlockVisible(); + giftOptions.addOption(model); this.model.getObservable('isClear').subscribe(function (value) { if (value == true) { //eslint-disable-line eqeqeq @@ -40,8 +41,6 @@ define([ self.model.getObservable('alreadyAdded')(true); } }); - - this.isResultBlockVisible(); }, /** From f2e053a7d6e87252ae526049b2253566d19ee0a7 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 28 Aug 2018 19:23:23 +0400 Subject: [PATCH 0033/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Add automated test --- .../Section/StoreFrontShoppingCartSection.xml | 15 +++++ .../CleanConfigsForGiftOptionsActionGroup.xml | 32 +++++++++++ ...ftWrappingForOrderItemsOnlyActionGroup.xml | 32 +++++++++++ .../Mftf/Section/AdminSalesConfigSection.xml | 16 +++++- .../CheckingGiftOptionsActionGroup.xml | 23 ++++++++ .../Section/GiftOptionsOnFrontSection.xml | 13 +++++ .../StoreFrontCheckingGiftOptionsTest.xml | 57 +++++++++++++++++++ 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml create mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml create mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml new file mode 100644 index 0000000000000..303c5e526423f --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="StoreFrontShoppingCartSection"> + <element name="checkoutWithMultipleAddresses" type="button" selector="//span[text()='Check Out with Multiple Addresses']"/> + <element name="goToShippingInformation" type="button" selector="//button[@title='Go to Shipping Information']"/> + </section> +</sections> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml new file mode 100644 index 0000000000000..72d88b13736cc --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CleanConfigsForGiftOptionsActionGroup"> + <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> + <waitForPageLoad stepKey="waitForConfigPage" time="5"/> + <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" + dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" + stepKey="openGiftOptionsIfItIsClosed"/> + <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> + <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> + <click stepKey="chooseYesForOrderLevel" selector="{{AdminSalesConfigSection.levelYes}}"/> + <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> + <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> + <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> + <click stepKey="chooseYesForReceipt" selector="{{AdminSalesConfigSection.receiptYes}}"/> + <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> + <click stepKey="chooseYesPrintedCard" selector="{{AdminSalesConfigSection.printedCardYes}}"/> + <click stepKey="closeGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> + <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> + <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> + <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> + </actionGroup> +</actionGroups> + diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml new file mode 100644 index 0000000000000..8f5b491575e95 --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup"> + <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> + <waitForPageLoad stepKey="waitForConfigPage" time="5"/> + <scrollTo stepKey="scrollToGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> + <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" + dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" + stepKey="openGiftOptionsIfItIsClosed"/> + <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> + <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> + <click stepKey="chooseNoForOrderLevel" selector="{{AdminSalesConfigSection.levelNo}}"/> + <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> + <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> + <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> + <click stepKey="chooseNoForReceipt" selector="{{AdminSalesConfigSection.receiptNo}}"/> + <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> + <click stepKey="chooseNoPrintedCard" selector="{{AdminSalesConfigSection.printedCardNo}}"/> + <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> + <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> + <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> + </actionGroup> +</actionGroups> + diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml index 4897e8415c1b8..aefb7c5441c5b 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml @@ -5,9 +5,23 @@ * See COPYING.txt for license details. */ --> -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminSalesConfigSection"> <element name="enableMAPUseSystemValue" type="checkbox" selector="#sales_msrp_enabled_inherit"/> <element name="enableMAPSelect" type="select" selector="#sales_msrp_enabled"/> + <element name="giftOptions" type="select" selector="#sales_gift_options-head"/> + <element name="allowGiftWrappingOnOrderLevel" type="select" selector="#sales_gift_options_wrapping_allow_order"/> + <element name="levelNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='No']"/> + <element name="levelYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='Yes']"/> + <element name="allowGiftWrappingForOrderItems" type="select" selector="#sales_gift_options_wrapping_allow_items"/> + <element name="itemsNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='No']"/> + <element name="itemsYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='Yes']"/> + <element name="allowGiftReceipt" type="select" selector="#sales_gift_options_allow_gift_receipt"/> + <element name="receiptNo" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='No']"/> + <element name="receiptYes" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='Yes']"/> + <element name="allowPrintedCard" type="select" selector="#sales_gift_options_allow_printed_card"/> + <element name="printedCardNo" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='No']"/> + <element name="printedCardYes" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='Yes']"/> + <element name="go" type="select" selector="//a[@id='sales_gift_options-head']/ancestor::div[@class='entry-edit-head admin__collapsible-block']"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml new file mode 100644 index 0000000000000..05dad757e287f --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CheckingGiftOptionsActionGroup"> + <click stepKey="clickOnCheckoutWithMultipleAddresses" selector="{{StoreFrontShoppingCartSection.checkoutWithMultipleAddresses}}"/> + <waitForPageLoad stepKey="waitForShipToMultipleAddresses"/> + <click stepKey="goToShippingInformation" selector="{{StoreFrontShoppingCartSection.goToShippingInformation}}"/> + <waitForPageLoad stepKey="waitForGiftOption"/> + <click stepKey="thickAddGiftOptions" selector="{{GiftOptionsOnFrontSection.giftOptionCheckbox}}"/> + <waitForPageLoad stepKey="waitForOptions"/> + <see stepKey="seeAddGiftOptionsForIndividualItems" userInput="Add Gift Options for Individual Items"/> + <dontSee stepKey="dontSeeOtherElement1" userInput="Send Gift Receipt"/> + <dontSee stepKey="dontSeeOtherElement2" userInput="Add Printed Card"/> + </actionGroup> +</actionGroups> + diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml new file mode 100644 index 0000000000000..9856f009197c1 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="GiftOptionsOnFrontSection"> + <element name="giftOptionCheckbox" type="text" selector="//span[text()='Add Gift Options']"/> + <element name="addGiftOptionsForIndividualItems" type="text" selector="//dt[@class='order-title individual']"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml new file mode 100644 index 0000000000000..7b4bd56ae74e8 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StoreFrontCheckingGiftOptionsTest"> + <annotations> + <features value="Gift"/> + <stories value="Checking Gift Options on front end order page"/> + <title value="Checking Gift Options on front end order page"/> + <description value="Admin should be able to control gift options"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94209"/> + <group value="Gift"/> + </annotations> + <before> + <createData stepKey="category" entity="SimpleSubCategory"/> + <createData stepKey="product1" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData stepKey="product2" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="customer"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup" stepKey="configureGiftOptions"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> + <argument name="Customer" value="$$customer$$"/> + </actionGroup> + </before> + + <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct1"> + <argument name="productName" value="$$product1.name$$"/> + </actionGroup> + <amOnPage url="$$product2.name$$.html" stepKey="goToProduct2"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct2"> + <argument name="productName" value="$$product2.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> + <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> + + <after> + <actionGroup ref="CleanConfigsForGiftOptionsActionGroup" stepKey="cleanGiftOptionsConfigs"/> + <deleteData stepKey="deleteCategory" createDataKey="category"/> + <deleteData stepKey="deleteProduct1" createDataKey="product1"/> + <deleteData stepKey="deleteProduct2" createDataKey="product2"/> + <deleteData stepKey="deleteCustomer" createDataKey="customer"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + </test> +</tests> From 7bf456a3eb8e0072ef1e6b22467a75f48336a606 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar <mbalidar@comwrap.com> Date: Wed, 29 Aug 2018 09:54:22 +0200 Subject: [PATCH 0034/1415] add user type for asynchronous operations --- .../Api/Data/BulkSummaryInterface.php | 17 +++++++++++++++++ .../Model/BulkManagement.php | 10 ++++++++++ .../Model/BulkSummary.php | 16 ++++++++++++++++ .../Test/Unit/Model/BulkManagementTest.php | 2 ++ .../AsynchronousOperations/etc/db_schema.xml | 1 + .../AsynchronousOperations/_files/bulk.php | 9 +++++++-- 6 files changed, 53 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php index f5dd5bb13eabb..435cf5e433baa 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php @@ -13,6 +13,8 @@ */ interface BulkSummaryInterface extends \Magento\Framework\Bulk\BulkSummaryInterface { + const USER_TYPE = 'user_type'; + /** * Retrieve existing extension attributes object. * @@ -31,4 +33,19 @@ public function getExtensionAttributes(); public function setExtensionAttributes( \Magento\AsynchronousOperations\Api\Data\BulkSummaryExtensionInterface $extensionAttributes ); + + /** + * Get user type + * + * @return int + */ + public function getUserType(); + + /** + * Set user type + * @param int $operationCount + * @return $this + */ + public function setUserType($userType); + } diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php index 4f086ce8ac2ca..add7d220e8efb 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php @@ -13,6 +13,7 @@ use Magento\Framework\EntityManager\EntityManager; use Magento\Framework\EntityManager\MetadataPool; use Magento\AsynchronousOperations\Model\ResourceModel\Operation\CollectionFactory; +use Magento\Authorization\Model\UserContextInterface; /** * Class BulkManagement @@ -51,6 +52,11 @@ class BulkManagement implements \Magento\Framework\Bulk\BulkManagementInterface */ private $resourceConnection; + /** + * @var \Magento\Authorization\Model\UserContextInterface + */ + private $userContext; + /** * @var \Psr\Log\LoggerInterface */ @@ -73,6 +79,7 @@ public function __construct( BulkPublisherInterface $publisher, MetadataPool $metadataPool, ResourceConnection $resourceConnection, + UserContextInterface $userContext, \Psr\Log\LoggerInterface $logger ) { $this->entityManager = $entityManager; @@ -81,6 +88,7 @@ public function __construct( $this->metadataPool = $metadataPool; $this->resourceConnection = $resourceConnection; $this->publisher = $publisher; + $this->userContext = $userContext; $this->logger = $logger; } @@ -93,6 +101,7 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId $connection = $this->resourceConnection->getConnectionByName($metadata->getEntityConnectionName()); // save bulk summary and related operations $connection->beginTransaction(); + $userType = $this->userContext->getUserType(); try { /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface $bulkSummary */ $bulkSummary = $this->bulkSummaryFactory->create(); @@ -100,6 +109,7 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId $bulkSummary->setBulkId($bulkUuid); $bulkSummary->setDescription($description); $bulkSummary->setUserId($userId); + $bulkSummary->setUserType($userType); $bulkSummary->setOperationCount((int)$bulkSummary->getOperationCount() + count($operations)); $this->entityManager->save($bulkSummary); diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkSummary.php b/app/code/Magento/AsynchronousOperations/Model/BulkSummary.php index e99233d076957..1d834ad10b2e7 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkSummary.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkSummary.php @@ -78,6 +78,22 @@ public function setUserId($userId) return $this->setData(self::USER_ID, $userId); } + /** + * @inheritDoc + */ + public function getUserType() + { + return $this->getData(self::USER_TYPE); + } + + /** + * @inheritDoc + */ + public function setUserType($userType) + { + return $this->setData(self::USER_TYPE, $userType); + } + /** * @inheritDoc */ diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php index 3a45c34df17f8..e9fabb6150d6c 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php @@ -108,6 +108,7 @@ public function testScheduleBulk() $bulkUuid = 'bulk-001'; $description = 'Bulk summary description...'; $userId = 1; + $userType = 2; $connectionName = 'default'; $topicNames = ['topic.name.0', 'topic.name.1']; $operation = $this->getMockBuilder(\Magento\AsynchronousOperations\Api\Data\OperationInterface::class) @@ -131,6 +132,7 @@ public function testScheduleBulk() $bulkSummary->expects($this->once())->method('setBulkId')->with($bulkUuid)->willReturnSelf(); $bulkSummary->expects($this->once())->method('setDescription')->with($description)->willReturnSelf(); $bulkSummary->expects($this->once())->method('setUserId')->with($userId)->willReturnSelf(); + $bulkSummary->expects($this->once())->method('getUserType')->with($userType)->willReturnSelf(); $bulkSummary->expects($this->once())->method('getOperationCount')->willReturn(1); $bulkSummary->expects($this->once())->method('setOperationCount')->with(3)->willReturnSelf(); $this->entityManager->expects($this->once())->method('save')->with($bulkSummary)->willReturn($bulkSummary); diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index a3acb7897580f..c8e733a7956ec 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -15,6 +15,7 @@ comment="Bulk UUID (can be exposed to reference bulk entity)"/> <column xsi:type="int" name="user_id" padding="10" unsigned="true" nullable="true" identity="false" comment="ID of the WebAPI user that performed an action"/> + <column xsi:type="int" name="user_type" nullable="false" comment="Which type of user"/> <column xsi:type="varchar" name="description" nullable="true" length="255" comment="Bulk Description"/> <column xsi:type="int" name="operation_count" padding="10" unsigned="true" nullable="false" identity="false" comment="Total number of operations scheduled within this bulk"/> diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php index 787d2c10a44c4..0c10796a30ef2 100644 --- a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php @@ -18,30 +18,35 @@ 'not_started' => [ 'uuid' => 'bulk-uuid-1', 'user_id' => 1, + 'user_type' => 2, 'description' => 'Bulk Description', 'operation_count' => 1, ], 'in_progress_success' => [ 'uuid' => 'bulk-uuid-2', 'user_id' => 1, + 'user_type' => 2, 'description' => 'Bulk Description', 'operation_count' => 3, ], 'in_progress_failed' => [ 'uuid' => 'bulk-uuid-3', 'user_id' => 1, + 'user_type' => 2, 'description' => 'Bulk Description', 'operation_count' => 2, ], 'finish_success' => [ 'uuid' => 'bulk-uuid-4', 'user_id' => 1, + 'user_type' => 2, 'description' => 'Bulk Description', 'operation_count' => 1, ], 'finish_failed' => [ 'uuid' => 'bulk-uuid-5', 'user_id' => 1, + 'user_type' => 2, 'description' => 'Bulk Description', 'operation_count' => 2, ] @@ -91,8 +96,8 @@ ]; -$bulkQuery = "INSERT INTO {$bulkTable} (`uuid`, `user_id`, `description`, `operation_count`)" - . " VALUES (:uuid, :user_id, :description, :operation_count);"; +$bulkQuery = "INSERT INTO {$bulkTable} (`uuid`, `user_id`, `user_type`, `description`, `operation_count`)" + . " VALUES (:uuid, :user_id, :user_type, :description, :operation_count);"; foreach ($bulks as $bulk) { $connection->query($bulkQuery, $bulk); } From adb3af29f2fc435b193338a80d873689cac82a1d Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoud.beekman@mediact.nl> Date: Sun, 26 Aug 2018 20:41:13 +0200 Subject: [PATCH 0035/1415] Optimize code to remove phpmd suppress warnings By making the order of some checks more efficient the suppress warnings in these two files about CyclomaticComplexity and NPathComplexity. --- .../Magento/Customer/Model/Metadata/Form/Text.php | 11 +++++------ app/code/Magento/Eav/Model/Attribute/Data/Text.php | 13 ++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php index c8b9a1e46a127..dcd3bc93569a4 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php @@ -52,8 +52,6 @@ public function extractValue(\Magento\Framework\App\RequestInterface $request) /** * @inheritdoc - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function validateValue($value) { @@ -66,12 +64,12 @@ public function validateValue($value) $value = $this->_value; } - if ($attribute->isRequired() && empty($value) && $value !== '0') { - $errors[] = __('"%1" is a required value.', $label); + if (!$attribute->isRequired() && empty($value)) { + return true; } - if (!$errors && !$attribute->isRequired() && empty($value)) { - return true; + if (empty($value) && $value !== '0') { + $errors[] = __('"%1" is a required value.', $label); } $errors = $this->validateLength($value, $attribute, $errors); @@ -80,6 +78,7 @@ public function validateValue($value) if ($result !== true) { $errors = array_merge($errors, $result); } + if (count($errors) == 0) { return true; } diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index f81fb2affd3b3..a26a92df385f2 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -55,8 +55,7 @@ public function extractValue(RequestInterface $request) * * @param array|string $value * @return bool|array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws \Magento\Framework\Exception\LocalizedException */ public function validateValue($value) { @@ -68,13 +67,13 @@ public function validateValue($value) $value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode()); } - if ($attribute->getIsRequired() && empty($value) && $value !== '0') { - $label = __($attribute->getStoreLabel()); - $errors[] = __('"%1" is a required value.', $label); + if (!$attribute->isRequired() && empty($value)) { + return true; } - if (!$errors && !$attribute->getIsRequired() && empty($value)) { - return true; + if (empty($value) && $value !== '0') { + $label = __($attribute->getStoreLabel()); + $errors[] = __('"%1" is a required value.', $label); } $result = $this->validateLength($attribute, $value); From 9d112a661e0b892f8d89d6b4d5e65af3f2315ef5 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar <mbalidar@comwrap.com> Date: Thu, 30 Aug 2018 13:31:11 +0200 Subject: [PATCH 0036/1415] add user type of bulk operation --- app/code/Magento/AsynchronousOperations/etc/db_schema.xml | 2 +- .../Magento/AsynchronousOperations/etc/db_schema_whitelist.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index c8e733a7956ec..94ee5a16b5b84 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -15,7 +15,7 @@ comment="Bulk UUID (can be exposed to reference bulk entity)"/> <column xsi:type="int" name="user_id" padding="10" unsigned="true" nullable="true" identity="false" comment="ID of the WebAPI user that performed an action"/> - <column xsi:type="int" name="user_type" nullable="false" comment="Which type of user"/> + <column xsi:type="int" name="user_type" nullable="true" comment="Which type of user"/> <column xsi:type="varchar" name="description" nullable="true" length="255" comment="Bulk Description"/> <column xsi:type="int" name="operation_count" padding="10" unsigned="true" nullable="false" identity="false" comment="Total number of operations scheduled within this bulk"/> diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json index 6b18ac3e29d43..365c8d5b9b0b1 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json @@ -4,6 +4,7 @@ "id": true, "uuid": true, "user_id": true, + "user_type": true, "description": true, "operation_count": true, "start_time": true From 41f81e050ccd25ae379d35fa37cd5e65d6a92b0d Mon Sep 17 00:00:00 2001 From: Roman Leshchenko <rleshchenko@magento.com> Date: Thu, 30 Aug 2018 14:33:50 +0300 Subject: [PATCH 0037/1415] MAGETWO-90725: Wrong session messages behavior --- .../Model/System/Config/Backend/Ttl.php | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/PageCache/Model/System/Config/Backend/Ttl.php b/app/code/Magento/PageCache/Model/System/Config/Backend/Ttl.php index dab8d7be16dd7..d9d26d0848c24 100644 --- a/app/code/Magento/PageCache/Model/System/Config/Backend/Ttl.php +++ b/app/code/Magento/PageCache/Model/System/Config/Backend/Ttl.php @@ -6,6 +6,10 @@ namespace Magento\PageCache\Model\System\Config\Backend; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Escaper; +use Magento\Framework\App\Config\ScopeConfigInterface; + /** * Backend model for processing Public content cache lifetime settings * @@ -13,6 +17,36 @@ */ class Ttl extends \Magento\Framework\App\Config\Value { + /** + * @var Escaper + */ + private $escaper; + + /** + * Ttl constructor. + * @param \Magento\Framework\Model\Context $context + * @param \Magento\Framework\Registry $registry + * @param ScopeConfigInterface $config + * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList + * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource + * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection + * @param array $data + * @param Escaper|null $escaper + */ + public function __construct( + \Magento\Framework\Model\Context $context, + \Magento\Framework\Registry $registry, + ScopeConfigInterface $config, + \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList, + ?\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, + ?\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, + array $data = [], + ?Escaper $escaper = null + ) { + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + $this->escaper = $escaper ?: ObjectManager::getInstance()->create(Escaper::class); + } + /** * Throw exception if Ttl data is invalid or empty * @@ -24,7 +58,10 @@ public function beforeSave() $value = $this->getValue(); if ($value < 0 || !preg_match('/^[0-9]+$/', $value)) { throw new \Magento\Framework\Exception\LocalizedException( - __('Ttl value "%1" is not valid. Please use only numbers equal or greater than zero.', $value) + __( + 'Ttl value "%1" is not valid. Please use only numbers equal or greater than zero.', + $this->escaper->escapeHtml($value) + ) ); } return $this; From a63d23f2f7b734bc2e43764492694897ed7f1447 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 30 Aug 2018 17:21:21 +0300 Subject: [PATCH 0038/1415] MAGETWO-91532: Copy tier price for copied products - Fix CR comments --- .../Attribute/Backend/GroupPrice/AbstractGroupPrice.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index 944d78f79ca34..94b7fff44fd07 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -395,7 +395,10 @@ public function afterSave($object) $linkFieldName = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(); // prepare original data for compare $origPrices = $object->getOrigData($this->getAttribute()->getName()); - if (!is_array($origPrices) || $object->getData($linkFieldName) != $object->getOrigData($linkFieldName)) { + $originalId = $object->getOrigData($linkFieldName); + if (!is_array($origPrices) + || (!empty($originalId) && $object->getData($linkFieldName) != $originalId) + ) { $origPrices = []; } From b613382e6f2baa698e4e6bc9af279a81f698a49e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 30 Aug 2018 17:50:01 +0300 Subject: [PATCH 0039/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Port community contribution fix --- app/code/Magento/Sales/Model/Order.php | 39 ++++++++++++++----- .../Magento/Sales/Model/Order/Creditmemo.php | 31 ++++++++++++++- .../Adminhtml/Order/Creditmemo/SaveTest.php | 4 +- .../Test/Unit/Model/Order/CreditmemoTest.php | 27 ++++++++++++- .../Sales/Test/Unit/Model/OrderTest.php | 15 +++++++ .../Magento/Sales/etc/adminhtml/system.xml | 7 ++++ app/code/Magento/Sales/etc/config.xml | 3 ++ 7 files changed, 112 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 7372d9715c725..4e68f206026fe 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -620,11 +620,8 @@ public function canCreditmemo() return $this->getForcedCanCreditmemo(); } - if ($this->canUnhold() || $this->isPaymentReview()) { - return false; - } - - if ($this->isCanceled() || $this->getState() === self::STATE_CLOSED) { + if ($this->canUnhold() || $this->isPaymentReview() || + $this->isCanceled() || $this->getState() === self::STATE_CLOSED) { return false; } @@ -634,15 +631,39 @@ public function canCreditmemo() * TotalPaid - contains amount, that were not rounded. */ $totalRefunded = $this->priceCurrency->round($this->getTotalPaid()) - $this->getTotalRefunded(); - if (abs($totalRefunded) < .0001) { - return false; + if (abs($this->getGrandTotal()) < .0001) { + return $this->canCreditmemoForZeroTotal($totalRefunded); } + + $isRefundZero = abs($totalRefunded) < .0001; // Case when Adjustment Fee (adjustment_negative) has been used for first creditmemo - if (abs($totalRefunded - $this->getAdjustmentNegative()) < .0001) { + $hasAdjustmentFee = abs($totalRefunded - $this->getAdjustmentNegative()) < .0001; + $hasActinFlag = $this->getActionFlag(self::ACTION_FLAG_EDIT) === false; + if ($isRefundZero || $hasAdjustmentFee || $hasActinFlag) { return false; } - if ($this->getActionFlag(self::ACTION_FLAG_EDIT) === false) { + return true; + } + + /** + * Retrieve credit memo for zero total availability. + * + * @param $totalRefunded + * @return bool + */ + public function canCreditmemoForZeroTotal($totalRefunded) + { + $totalPaid = $this->getTotalPaid(); + //check if total paid is less than grandtotal + $checkAmtTotalPaid = $totalPaid <= $this->getGrandTotal(); + //case when amount is due for invoice + $dueAmountCondition = $this->canInvoice() && ($checkAmtTotalPaid); + //case when paid amount is refunded and order has creditmemo created + $paidAmtIsRefunded = $this->getTotalRefunded() == $totalPaid && count($this->getCreditmemosCollection()) > 0; + if (($dueAmountCondition || $paidAmtIsRefunded) || + (!$checkAmtTotalPaid && + abs($totalRefunded - $this->getAdjustmentNegative()) < .0001)) { return false; } return true; diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index 7ea7e4af3c36e..ec38ad9ad3ae6 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -13,6 +13,7 @@ use Magento\Sales\Model\AbstractModel; use Magento\Sales\Model\EntityInterface; use Magento\Sales\Model\Order\InvoiceFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; /** * Order creditmemo model @@ -40,6 +41,11 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt const REPORT_DATE_TYPE_REFUND_CREATED = 'refund_created'; + /** + * Allow Zero Grandtotal for Creditmemo path + */ + const XML_PATH_ALLOW_ZERO_GRANDTOTAL = 'sales/zerograndtotal_creditmemo/allow_zero_grandtotal'; + /** * Identifier for order history item * @@ -119,6 +125,11 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt */ private $invoiceFactory; + /** + * @var ScopeConfigInterface; + */ + private $scopeConfig; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -154,7 +165,8 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - InvoiceFactory $invoiceFactory = null + InvoiceFactory $invoiceFactory = null, + ScopeConfigInterface $scopeConfig = null ) { $this->_creditmemoConfig = $creditmemoConfig; $this->_orderFactory = $orderFactory; @@ -165,6 +177,7 @@ public function __construct( $this->_commentCollectionFactory = $commentCollectionFactory; $this->priceCurrency = $priceCurrency; $this->invoiceFactory = $invoiceFactory ?: ObjectManager::getInstance()->get(InvoiceFactory::class); + $this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class); parent::__construct( $context, $registry, @@ -610,7 +623,21 @@ public function getIncrementId() */ public function isValidGrandTotal() { - return !($this->getGrandTotal() <= 0 && !$this->getAllowZeroGrandTotal()); + return !($this->getGrandTotal() <= 0 && !$this->isAllowZeroGrandTotal()); + } + + /** + * Return Zero GrandTotal availability. + * + * @return bool + */ + public function isAllowZeroGrandTotal() + { + $isAllowed = $this->scopeConfig->getValue( + self::XML_PATH_ALLOW_ZERO_GRANDTOTAL, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + return $isAllowed; } /** diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/SaveTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/SaveTest.php index 0112d09eb735f..4ad2e314c8317 100644 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/SaveTest.php +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/SaveTest.php @@ -203,10 +203,10 @@ public function testSaveActionWithNegativeCreditmemo() $creditmemoMock = $this->createPartialMock( \Magento\Sales\Model\Order\Creditmemo::class, - ['load', 'getGrandTotal', 'getAllowZeroGrandTotal', '__wakeup'] + ['load', 'getGrandTotal', 'isAllowZeroGrandTotal', '__wakeup'] ); $creditmemoMock->expects($this->once())->method('getGrandTotal')->will($this->returnValue('0')); - $creditmemoMock->expects($this->once())->method('getAllowZeroGrandTotal')->will($this->returnValue(false)); + $creditmemoMock->expects($this->once())->method('isAllowZeroGrandTotal')->will($this->returnValue(false)); $this->memoLoaderMock->expects( $this->once() )->method( diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoTest.php index b872a4ef9fba1..f299cd5accdb8 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoTest.php @@ -10,6 +10,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Sales\Model\ResourceModel\Order\Creditmemo\Item\CollectionFactory; use Magento\Sales\Model\ResourceModel\Order\Creditmemo\Item\Collection as ItemCollection; +use Magento\Framework\App\Config\ScopeConfigInterface; /** * Class CreditmemoTest @@ -28,6 +29,11 @@ class CreditmemoTest extends \PHPUnit\Framework\TestCase */ protected $creditmemo; + /** + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + /** * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -36,6 +42,7 @@ class CreditmemoTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->orderFactory = $this->createPartialMock(\Magento\Sales\Model\OrderFactory::class, ['create']); + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); $objectManagerHelper = new ObjectManagerHelper($this); $this->cmItemCollectionFactoryMock = $this->getMockBuilder( @@ -62,6 +69,7 @@ protected function setUp() 'commentCollectionFactory' => $this->createMock( \Magento\Sales\Model\ResourceModel\Order\Creditmemo\Comment\CollectionFactory::class ), + 'scopeConfig' => $this->scopeConfigMock ]; $this->creditmemo = $objectManagerHelper->getObject( \Magento\Sales\Model\Order\Creditmemo::class, @@ -109,10 +117,27 @@ public function testIsValidGrandTotalGrandTotalEmpty() public function testIsValidGrandTotalGrandTotal() { $this->creditmemo->setGrandTotal(0); - $this->creditmemo->getAllowZeroGrandTotal(true); + $this->creditmemo->isAllowZeroGrandTotal(true); $this->assertFalse($this->creditmemo->isValidGrandTotal()); } + /** + * Test for isAllowZeroGrandTotal method. + * + * @return void + */ + public function testIsAllowZeroGrandTotal() + { + $isAllowed = 0; + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with( + 'sales/zerograndtotal_creditmemo/allow_zero_grandtotal', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + )->willReturn($isAllowed); + $this->assertEquals($isAllowed, $this->creditmemo->isAllowZeroGrandTotal()); + } + public function testIsValidGrandTotal() { $this->creditmemo->setGrandTotal(1); diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php index 7f6363346872c..7ccfa5725a73b 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php @@ -332,6 +332,21 @@ public function testCanCreditMemo() $this->assertTrue($this->order->canCreditmemo()); } + /** + * Test canCreditMemo method when grand total and paid total are zero. + * + * @return void + */ + public function testCanCreditMemoForZeroTotal() + { + $grandTotal = 0; + $totalPaid = 0; + $totalRefunded = 0; + $this->order->setGrandTotal($grandTotal); + $this->order->setTotalPaid($totalPaid); + $this->assertFalse($this->order->canCreditmemoForZeroTotal($totalRefunded)); + } + public function testCanNotCreditMemoWithTotalNull() { $totalPaid = 0; diff --git a/app/code/Magento/Sales/etc/adminhtml/system.xml b/app/code/Magento/Sales/etc/adminhtml/system.xml index 7d06e0f7b74c4..67512e7335013 100644 --- a/app/code/Magento/Sales/etc/adminhtml/system.xml +++ b/app/code/Magento/Sales/etc/adminhtml/system.xml @@ -48,6 +48,13 @@ <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> + <group id="zerograndtotal_creditmemo" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Allow Zero GrandTotal</label> + <field id="allow_zero_grandtotal" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <label>Allow Zero GrandTotal for Creditmemo</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + </field> + </group> <group id="identity" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Invoice and Packing Slip Design</label> <field id="logo" translate="label comment" type="image" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> diff --git a/app/code/Magento/Sales/etc/config.xml b/app/code/Magento/Sales/etc/config.xml index d4d10bfa6dcce..5be06fa3836a7 100644 --- a/app/code/Magento/Sales/etc/config.xml +++ b/app/code/Magento/Sales/etc/config.xml @@ -18,6 +18,9 @@ <reorder> <allow>1</allow> </reorder> + <zerograndtotal_creditmemo> + <allow_zero_grandtotal>1</allow_zero_grandtotal> + </zerograndtotal_creditmemo> <minimum_order> <tax_including>1</tax_including> </minimum_order> From ea9168570ae0f2d5bcf1911b13b46b760a9cb0eb Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 31 Aug 2018 14:42:59 +0300 Subject: [PATCH 0040/1415] MAGETWO-91628: Bundle product price doubled when switching currency - Fixed an issue with quote item options relates to a bundled products. --- .../Magento/Bundle/Model/Product/Type.php | 2 +- .../Plugin/UpdatePriceInQuoteItemOptions.php | 55 +++++++++++++++++++ app/code/Magento/Bundle/etc/di.xml | 3 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 17ecba545efad..c5f3aa0a84995 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -735,7 +735,7 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p $price = $product->getPriceModel() ->getSelectionFinalTotalPrice($product, $selection, 0, $qty); $attributes = [ - 'price' => $this->priceCurrency->convert($price), + 'price' => $price, 'qty' => $qty, 'option_label' => $selection->getOption() ->getTitle(), diff --git a/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php b/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php new file mode 100644 index 0000000000000..d5aafb8ad2b61 --- /dev/null +++ b/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Plugin; + +use Magento\Quote\Model\Quote\Item as OrigQuoteItem; +use Magento\Quote\Model\Quote\Item\AbstractItem; +use Magento\Framework\Serialize\SerializerInterface; + +/** + * Update prices stored in quote item options after calculating quote item's totals + */ +class UpdatePriceInQuoteItemOptions +{ + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @param SerializerInterface $serializer + */ + public function __construct(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } + + /** + * Update price on quote item options level + * + * @param OrigQuoteItem $subject + * @param AbstractItem $result + * @return AbstractItem + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterCalcRowTotal(OrigQuoteItem $subject, AbstractItem $result) + { + $bundleAttributes = $result->getProduct()->getCustomOption('bundle_selection_attributes'); + if ($bundleAttributes !== null) { + $actualPrice = $result->getPrice(); + $parsedValue = $this->serializer->unserialize($bundleAttributes->getValue()); + if (is_array($parsedValue) && array_key_exists('price', $parsedValue)) { + $parsedValue['price'] = $actualPrice; + } + $bundleAttributes->setValue($this->serializer->serialize($parsedValue)); + } + + return $result; + } +} diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index 733b089dccd4b..6f0cc04790cc2 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -123,6 +123,9 @@ </argument> </arguments> </type> + <type name="Magento\Quote\Model\Quote\Item"> + <plugin name="update_price_for_bundle_in_quote_item_option" type="Magento\Bundle\Plugin\UpdatePriceInQuoteItemOptions"/> + </type> <type name="Magento\Quote\Model\Quote\Item\ToOrderItem"> <plugin name="append_bundle_data_to_order" type="Magento\Bundle\Model\Plugin\QuoteItem"/> </type> From 97242021d4fffa02ca7d8e48710a9343f41316d4 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar <mbalidar@comwrap.com> Date: Fri, 31 Aug 2018 16:08:50 +0200 Subject: [PATCH 0041/1415] remove empty line from interface --- .../AsynchronousOperations/Api/Data/BulkSummaryInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php index 435cf5e433baa..4b65f2a207b75 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php @@ -47,5 +47,4 @@ public function getUserType(); * @return $this */ public function setUserType($userType); - } From 1ff16642855a313b3b8e4a7a9a6e836c09769c69 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <dhorytskyi@magento.com> Date: Mon, 3 Sep 2018 18:33:15 +0300 Subject: [PATCH 0042/1415] MAGETWO-94424: [2.3] Wrong product and shipping prices are applying on admin orders --- app/code/Magento/Store/Model/Store.php | 20 ++-- .../Store/Test/Unit/Model/StoreTest.php | 98 ++++++++++++++++++- 2 files changed, 103 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index af25957257421..32c9a78448428 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -902,23 +902,17 @@ public function setCurrentCurrencyCode($code) */ public function getCurrentCurrencyCode() { + $availableCurrencyCodes = \array_values($this->getAvailableCurrencyCodes(true)); // try to get currently set code among allowed - $code = $this->_httpContext->getValue(Context::CONTEXT_CURRENCY); - $code = $code === null ? $this->_getSession()->getCurrencyCode() : $code; - if (empty($code)) { + $code = $this->_httpContext->getValue(Context::CONTEXT_CURRENCY) ?? $this->_getSession()->getCurrencyCode(); + if (empty($code) || !\in_array($code, $availableCurrencyCodes)) { $code = $this->getDefaultCurrencyCode(); - } - if (in_array($code, $this->getAvailableCurrencyCodes(true))) { - return $code; + if (!\in_array($code, $availableCurrencyCodes) && !empty($availableCurrencyCodes)) { + $code = $availableCurrencyCodes[0]; + } } - // take first one of allowed codes - $codes = array_values($this->getAvailableCurrencyCodes(true)); - if (empty($codes)) { - // return default code, if no codes specified at all - return $this->getDefaultCurrencyCode(); - } - return array_shift($codes); + return $code; } /** diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php index f98cf5d892e07..f4a5010e51b88 100644 --- a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php @@ -3,11 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Store\Test\Unit\Model; use Magento\Framework\App\Config\ReinitableConfigInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\Store; @@ -38,6 +38,16 @@ class StoreTest extends \PHPUnit\Framework\TestCase */ protected $filesystemMock; + /** + * @var ReinitableConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var SessionManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $sessionMock; + /** * @var \Magento\Framework\Url\ModifierInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -61,12 +71,22 @@ protected function setUp() 'isSecure', 'getServer', ]); + $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) ->disableOriginalConstructor() ->getMock(); + $this->configMock = $this->getMockBuilder(ReinitableConfigInterface::class) + ->getMock(); + $this->sessionMock = $this->getMockBuilder(SessionManagerInterface::class) + ->setMethods(['getCurrencyCode']) + ->getMockForAbstractClass(); $this->store = $this->objectManagerHelper->getObject( \Magento\Store\Model\Store::class, - ['filesystem' => $this->filesystemMock] + [ + 'filesystem' => $this->filesystemMock, + 'config' => $this->configMock, + 'session' => $this->sessionMock, + ] ); $this->urlModifierMock = $this->createMock(\Magento\Framework\Url\ModifierInterface::class); @@ -694,6 +714,80 @@ public function testGetScopeTypeName() $this->assertEquals('Store View', $this->store->getScopeTypeName()); } + /** + * @param array $availableCodes + * @param string $currencyCode + * @param string $defaultCode + * @param string $expectedCode + * @return void + * @dataProvider currencyCodeDataProvider + */ + public function testGetCurrentCurrencyCode( + array $availableCodes, + string $currencyCode, + string $defaultCode, + string $expectedCode + ): void { + $this->store->setData('available_currency_codes', $availableCodes); + $this->sessionMock->method('getCurrencyCode') + ->willReturn($currencyCode); + $this->configMock->method('getValue') + ->with(\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_DEFAULT) + ->willReturn($defaultCode); + + $code = $this->store->getCurrentCurrencyCode(); + $this->assertEquals($expectedCode, $code); + } + + /** + * @return array + */ + public function currencyCodeDataProvider(): array + { + return [ + [ + [ + 'USD', + ], + 'USD', + 'USD', + 'USD', + ], + [ + [ + 'USD', + 'EUR', + ], + 'EUR', + 'USD', + 'EUR', + ], + [ + [ + 'EUR', + 'USD', + ], + 'GBP', + 'USD', + 'USD', + ], + [ + [ + 'USD', + ], + 'GBP', + 'EUR', + 'USD', + ], + [ + [], + 'GBP', + 'EUR', + 'EUR', + ], + ]; + } + /** * @param \Magento\Store\Model\Store $model */ From 38d5547049a0f2f6bf83b016b1af55961ccd753c Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 4 Sep 2018 13:47:33 +0400 Subject: [PATCH 0043/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Updated automated test --- .../CleanConfigsForGiftOptionsActionGroup.xml | 32 --------------- ...ftWrappingForOrderItemsOnlyActionGroup.xml | 32 --------------- .../Test/Mftf/Data/GiftOptionsData.xml | 40 +++++++++++++++++++ .../Test/Mftf/Metadata/gift_options-meta.xml | 31 ++++++++++++++ .../StoreFrontCheckingGiftOptionsTest.xml | 6 ++- 5 files changed, 75 insertions(+), 66 deletions(-) delete mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml delete mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml deleted file mode 100644 index 72d88b13736cc..0000000000000 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CleanConfigsForGiftOptionsActionGroup"> - <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> - <waitForPageLoad stepKey="waitForConfigPage" time="5"/> - <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" - dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" - stepKey="openGiftOptionsIfItIsClosed"/> - <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> - <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> - <click stepKey="chooseYesForOrderLevel" selector="{{AdminSalesConfigSection.levelYes}}"/> - <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> - <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> - <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> - <click stepKey="chooseYesForReceipt" selector="{{AdminSalesConfigSection.receiptYes}}"/> - <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> - <click stepKey="chooseYesPrintedCard" selector="{{AdminSalesConfigSection.printedCardYes}}"/> - <click stepKey="closeGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> - <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> - <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> - <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> - </actionGroup> -</actionGroups> - diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml deleted file mode 100644 index 8f5b491575e95..0000000000000 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup"> - <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> - <waitForPageLoad stepKey="waitForConfigPage" time="5"/> - <scrollTo stepKey="scrollToGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> - <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" - dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" - stepKey="openGiftOptionsIfItIsClosed"/> - <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> - <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> - <click stepKey="chooseNoForOrderLevel" selector="{{AdminSalesConfigSection.levelNo}}"/> - <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> - <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> - <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> - <click stepKey="chooseNoForReceipt" selector="{{AdminSalesConfigSection.receiptNo}}"/> - <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> - <click stepKey="chooseNoPrintedCard" selector="{{AdminSalesConfigSection.printedCardNo}}"/> - <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> - <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> - <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> - </actionGroup> -</actionGroups> - diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml new file mode 100644 index 0000000000000..b2bc71b5b7a7b --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="ConfigAllowGiftWrappingForOrderItemsOnly" type="gift_options_config_state"> + <requiredEntity type="wrapping_allow_order">wrappingAllowOrder</requiredEntity> + <requiredEntity type="allow_gift_receipt">allowGiftReceipt</requiredEntity> + <requiredEntity type="allow_printed_card">allowPrintedCard</requiredEntity> + </entity> + <entity name="wrappingAllowOrder" type="wrapping_allow_order"> + <data key="value">0</data> + </entity> + <entity name="allowGiftReceipt" type="allow_gift_receipt"> + <data key="value">0</data> + </entity> + <entity name="allowPrintedCard" type="allow_printed_card"> + <data key="value">0</data> + </entity> + + <entity name="DefaultConfigGiftOptions" type="gift_options_config_state"> + <requiredEntity type="wrapping_allow_order">defaultWrappingAllowOrder</requiredEntity> + <requiredEntity type="allow_gift_receipt">defaultAllowGiftReceipt</requiredEntity> + <requiredEntity type="allow_printed_card">defaultAllowPrintedCard</requiredEntity> + </entity> + <entity name="defaultWrappingAllowOrder" type="wrapping_allow_order"> + <data key="value">1</data> + </entity> + <entity name="defaultAllowGiftReceipt" type="allow_gift_receipt"> + <data key="value">1</data> + </entity> + <entity name="defaultAllowPrintedCard" type="allow_printed_card"> + <data key="value">1</data> + </entity> +</entities> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml new file mode 100644 index 0000000000000..a32f5694f2470 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="SalesGiftOptionsConfigState" dataType="gift_options_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="gift_options_config_state"> + <object key="gift_options" dataType="gift_options_config_state"> + <object key="fields" dataType="gift_options_config_state"> + <object key="wrapping_allow_order" dataType="wrapping_allow_order"> + <field key="value">string</field> + </object> + <object key="wrapping_allow_items" dataType="wrapping_allow_items"> + <field key="value">string</field> + </object> + <object key="allow_gift_receipt" dataType="allow_gift_receipt"> + <field key="value">string</field> + </object> + <object key="allow_printed_card" dataType="allow_printed_card"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml index 7b4bd56ae74e8..0bb5bf0e71fa8 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml @@ -27,11 +27,13 @@ <requiredEntity createDataKey="category"/> </createData> <createData entity="Simple_US_Customer" stepKey="customer"/> + <createData entity="ConfigAllowGiftWrappingForOrderItemsOnly" stepKey="configAllowGiftWrappingForOrderItemsOnly"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup" stepKey="configureGiftOptions"/> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> <argument name="Customer" value="$$customer$$"/> </actionGroup> + </before> <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> @@ -46,7 +48,7 @@ <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> <after> - <actionGroup ref="CleanConfigsForGiftOptionsActionGroup" stepKey="cleanGiftOptionsConfigs"/> + <createData entity="DefaultConfigGiftOptions" stepKey="restoreDefaultConfigGiftOptions"/> <deleteData stepKey="deleteCategory" createDataKey="category"/> <deleteData stepKey="deleteProduct1" createDataKey="product1"/> <deleteData stepKey="deleteProduct2" createDataKey="product2"/> From 2a7cd23d460e8ff278730cafbf3a2a1f33ae2461 Mon Sep 17 00:00:00 2001 From: Oleksandr_Hodzevych <Oleksandr_Hodzevych@epam.com> Date: Mon, 3 Sep 2018 18:47:32 +0300 Subject: [PATCH 0044/1415] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fixed widget operator less or more --- .../Rule/Model/Condition/Sql/Builder.php | 4 + .../Unit/Model/Condition/Sql/BuilderTest.php | 119 ++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 2894de0f19b87..1afe995f837ea 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -32,9 +32,13 @@ class Builder '==' => ':field = ?', '!=' => ':field <> ?', '>=' => ':field >= ?', + '>e;' => ':field >= ?', '>' => ':field > ?', + '>' => ':field > ?', '<=' => ':field <= ?', + '<e;' => ':field <= ?', '<' => ':field < ?', + '<' => ':field < ?', '{}' => ':field IN (?)', '!{}' => ':field NOT IN (?)', '()' => ':field IN (?)', diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index daf7b1462c722..b3ddaa51c2605 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -78,4 +78,123 @@ public function testAttachConditionToCollection() $this->_builder->attachConditionToCollection($collection, $combine); } + + /** + * Test for attach condition to collection with operator in html format + * + * @covers \Magento\Rule\Model\Condition\Sql\Builder::attachConditionToCollection() + * @return void; + */ + public function testAttachConditionAsHtmlToCollection() + { + $abstractCondition = $this->getMockForAbstractClass( + \Magento\Rule\Model\Condition\AbstractCondition::class, + [], + '', + false, + false, + true, + ['getOperatorForValidate', 'getMappedSqlField', 'getAttribute', 'getBindArgumentValue'] + ); + + $abstractCondition->expects($this->once()) + ->method('getMappedSqlField') + ->will($this->returnValue('argument')); + + $abstractCondition->expects($this->once()) + ->method('getOperatorForValidate') + ->will($this->returnValue('>')); + + $abstractCondition->expects($this->at(1)) + ->method('getAttribute') + ->will($this->returnValue('attribute')); + + $abstractCondition->expects($this->at(2)) + ->method('getAttribute') + ->will($this->returnValue('attribute')); + + $abstractCondition->expects($this->once()) + ->method('getBindArgumentValue') + ->will($this->returnValue(10)); + + $conditions = [ + $abstractCondition + ]; + + $collection = $this->createPartialMock( + \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, + [ + 'getResource', + 'getSelect', + 'getStoreId', + 'getDefaultStoreId', + ] + ); + + $combine = $this->createPartialMock(\Magento\Rule\Model\Condition\Combine::class, + [ + 'getConditions', + 'getValue', + 'getAggregator' + ] + ); + $resource = $this->createPartialMock(\Magento\Framework\DB\Adapter\Pdo\Mysql::class, ['getConnection']); + $select = $this->createPartialMock(\Magento\Framework\DB\Select::class, ['where']); + $select->expects($this->never()) + ->method('where'); + + $connection = $this->getMockForAbstractClass( + \Magento\Framework\DB\Adapter\AdapterInterface::class, + ['quoteInto'], + '', + false + ); + + $connection->expects($this->once()) + ->method('quoteInto') + ->with(' > ?', 10) + ->will($this->returnValue(' > 10')); + + $collection->expects($this->once()) + ->method('getResource') + ->will($this->returnValue($resource)); + + $collection->expects($this->once()) + ->method('getStoreId') + ->willReturn(1); + + $collection->expects($this->once()) + ->method('getDefaultStoreId') + ->willReturn(1); + + $resource->expects($this->once()) + ->method('getConnection') + ->will($this->returnValue($connection)); + + $combine->expects($this->once()) + ->method('getValue') + ->willReturn('attribute'); + + $combine->expects($this->once()) + ->method('getAggregator') + ->willReturn(' AND '); + + $combine->expects($this->at(0)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(1)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(2)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(3)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $this->_builder->attachConditionToCollection($collection, $combine); + } } From acfa860ad7ae7f9a9a2e169c840c7d1d61667bf0 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 4 Sep 2018 18:40:15 +0300 Subject: [PATCH 0045/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Add automated test --- .../Catalog/Test/Mftf/Data/ProductData.xml | 13 ++ .../Data/ProductExtensionAttributeData.xml | 3 + .../Catalog/Test/Mftf/Data/StockItemData.xml | 4 + ...tedProductToConfigurableOutOfStockTest.xml | 116 ++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 0df091eb5f8ef..fca5c2e0bcfc7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -419,4 +419,17 @@ <data key="status">1</data> <requiredEntity type="product_extension_attribute">EavStock100</requiredEntity> </entity> + <entity name="ApiSimpleSingleQty" type="product2"> + <data key="sku" unique="suffix">api-simple-product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Simple Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-simple-product</data> + <data key="status">1</data> + <data key="quantity">1</data> + <requiredEntity type="product_extension_attribute">EavStock1</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml index 88ff2bbace47a..1c81260cfe714 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml @@ -17,4 +17,7 @@ <entity name="EavStock10" type="product_extension_attribute"> <requiredEntity type="stock_item">Qty_10</requiredEntity> </entity> + <entity name="EavStock1" type="product_extension_attribute"> + <requiredEntity type="stock_item">Qty_1</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml index 4fae51de86c45..3e5f6e4d04fd9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml @@ -28,4 +28,8 @@ <data key="qty">101</data> <data key="is_in_stock">true</data> </entity> + <entity name="Qty_1" type="stock_item"> + <data key="qty">1</data> + <data key="is_in_stock">true</data> + </entity> </entities> diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml new file mode 100644 index 0000000000000..ea07db7b3f951 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AssociatedProductToConfigurableOutOfStockTest"> + <annotations> + <features value="CatalogInventory"/> + <stories value="Add/remove images and videos for all product types and category"/> + <title value="Out of stock associated products to configurable are not full page cache cleaned "/> + <description value="After last configurable product was ordered it becomes out of stock"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94135"/> + <group value="CatalogInventory"/> + </annotations> + + <before> + <createData entity="SimpleSubCategory" stepKey="simplecategory"/> + + <!-- Create configurable product with two options --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="simplecategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create child product with single quantity --> + <createData entity="ApiSimpleSingleQty" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <!-- Create customer --> + <createData entity="Simple_US_Customer" stepKey="createSimpleUsCustomer"> + <field key="group_id">1</field> + </createData> + </before> + + <after> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="simplecategory" stepKey="deleteSimpleCategory"/> + <deleteData createDataKey="createSimpleUsCustomer" stepKey="deleteCustomer"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Login as a customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="signUpNewUser"> + <argument name="Customer" value="$$createSimpleUsCustomer$$"/> + </actionGroup> + + <!-- Go to configurable product page --> + <click userInput="$$simplecategory.name$$" stepKey="clickOnCategoryName"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView" after="clickOnCategoryName"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Order product with single quantity --> + <selectOption userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="configProductFillOption" /> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage"/> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForCategoryLoad"/> + + <!-- Wait till cron job runs for schedule updates --> + <wait time="60" stepKey="waitForUpdateStarts"/> + + <!-- Assert that product with single quantity is not available for order --> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView2" /> + <dontSee userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="assertOptionNotAvailable" /> + </test> +</tests> From 5725c92582a43d15dc58b415e90cb2a1e31ea648 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 5 Sep 2018 05:00:39 +0300 Subject: [PATCH 0046/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Adding maxlength to input validation --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index 9ea0d1a823235..e124edc6a43e1 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -21,7 +21,7 @@ $product = $item->getProduct(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" + <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true,'maxlength':8}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From 73d1e388e9df3945c6410b991da8227b4893c061 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar <mbalidar@comwrap.com> Date: Wed, 5 Sep 2018 11:48:29 +0200 Subject: [PATCH 0047/1415] add user type for asynchronous operations --- .../Api/Data/BulkSummaryInterface.php | 2 +- .../AsynchronousOperations/Model/BulkManagement.php | 3 +++ .../Test/Unit/Model/BulkManagementTest.php | 4 ++-- .../Magento/AsynchronousOperations/_files/bulk.php | 10 +++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php index 4b65f2a207b75..9593cb983950a 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php @@ -43,7 +43,7 @@ public function getUserType(); /** * Set user type - * @param int $operationCount + * @param int $userType * @return $this */ public function setUserType($userType); diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php index add7d220e8efb..169c59aa1c749 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php @@ -102,6 +102,9 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId // save bulk summary and related operations $connection->beginTransaction(); $userType = $this->userContext->getUserType(); + if (is_null($userType)) { + $userType = UserContextInterface::USER_TYPE_ADMIN; + } try { /** @var \Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface $bulkSummary */ $bulkSummary = $this->bulkSummaryFactory->create(); diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php index e9fabb6150d6c..e5951fb129e7e 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php @@ -108,7 +108,7 @@ public function testScheduleBulk() $bulkUuid = 'bulk-001'; $description = 'Bulk summary description...'; $userId = 1; - $userType = 2; + $userType = \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN; $connectionName = 'default'; $topicNames = ['topic.name.0', 'topic.name.1']; $operation = $this->getMockBuilder(\Magento\AsynchronousOperations\Api\Data\OperationInterface::class) @@ -132,7 +132,7 @@ public function testScheduleBulk() $bulkSummary->expects($this->once())->method('setBulkId')->with($bulkUuid)->willReturnSelf(); $bulkSummary->expects($this->once())->method('setDescription')->with($description)->willReturnSelf(); $bulkSummary->expects($this->once())->method('setUserId')->with($userId)->willReturnSelf(); - $bulkSummary->expects($this->once())->method('getUserType')->with($userType)->willReturnSelf(); + $bulkSummary->expects($this->once())->method('setUserType')->with($userType)->willReturnSelf(); $bulkSummary->expects($this->once())->method('getOperationCount')->willReturn(1); $bulkSummary->expects($this->once())->method('setOperationCount')->with(3)->willReturnSelf(); $this->entityManager->expects($this->once())->method('save')->with($bulkSummary)->willReturn($bulkSummary); diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php index d5de12a3503b7..9e215667903d3 100644 --- a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php @@ -18,35 +18,35 @@ 'not_started' => [ 'uuid' => 'bulk-uuid-1', 'user_id' => 1, - 'user_type' => 2, + 'user_type' => \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN, 'description' => 'Bulk Description', 'operation_count' => 1, ], 'in_progress_success' => [ 'uuid' => 'bulk-uuid-2', 'user_id' => 1, - 'user_type' => 2, + 'user_type' => \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN, 'description' => 'Bulk Description', 'operation_count' => 3, ], 'in_progress_failed' => [ 'uuid' => 'bulk-uuid-3', 'user_id' => 1, - 'user_type' => 2, + 'user_type' => \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN, 'description' => 'Bulk Description', 'operation_count' => 2, ], 'finish_success' => [ 'uuid' => 'bulk-uuid-4', 'user_id' => 1, - 'user_type' => 2, + 'user_type' => \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN, 'description' => 'Bulk Description', 'operation_count' => 1, ], 'finish_failed' => [ 'uuid' => 'bulk-uuid-5', 'user_id' => 1, - 'user_type' => 2, + 'user_type' => \Magento\Authorization\Model\UserContextInterface::USER_TYPE_ADMIN, 'description' => 'Bulk Description', 'operation_count' => 2, ], From 5946dc0cc9e9897bbe04bd4202e3c0d286c16063 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 4 Sep 2018 18:40:15 +0300 Subject: [PATCH 0048/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Add automated test --- .../Catalog/Test/Mftf/Data/ProductData.xml | 13 ++ .../Data/ProductExtensionAttributeData.xml | 3 + .../Catalog/Test/Mftf/Data/StockItemData.xml | 4 + ...tedProductToConfigurableOutOfStockTest.xml | 116 ++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 0df091eb5f8ef..fca5c2e0bcfc7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -419,4 +419,17 @@ <data key="status">1</data> <requiredEntity type="product_extension_attribute">EavStock100</requiredEntity> </entity> + <entity name="ApiSimpleSingleQty" type="product2"> + <data key="sku" unique="suffix">api-simple-product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Simple Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-simple-product</data> + <data key="status">1</data> + <data key="quantity">1</data> + <requiredEntity type="product_extension_attribute">EavStock1</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml index 88ff2bbace47a..1c81260cfe714 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml @@ -17,4 +17,7 @@ <entity name="EavStock10" type="product_extension_attribute"> <requiredEntity type="stock_item">Qty_10</requiredEntity> </entity> + <entity name="EavStock1" type="product_extension_attribute"> + <requiredEntity type="stock_item">Qty_1</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml index 4fae51de86c45..3e5f6e4d04fd9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml @@ -28,4 +28,8 @@ <data key="qty">101</data> <data key="is_in_stock">true</data> </entity> + <entity name="Qty_1" type="stock_item"> + <data key="qty">1</data> + <data key="is_in_stock">true</data> + </entity> </entities> diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml new file mode 100644 index 0000000000000..ea07db7b3f951 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AssociatedProductToConfigurableOutOfStockTest"> + <annotations> + <features value="CatalogInventory"/> + <stories value="Add/remove images and videos for all product types and category"/> + <title value="Out of stock associated products to configurable are not full page cache cleaned "/> + <description value="After last configurable product was ordered it becomes out of stock"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94135"/> + <group value="CatalogInventory"/> + </annotations> + + <before> + <createData entity="SimpleSubCategory" stepKey="simplecategory"/> + + <!-- Create configurable product with two options --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="simplecategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create child product with single quantity --> + <createData entity="ApiSimpleSingleQty" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <!-- Create customer --> + <createData entity="Simple_US_Customer" stepKey="createSimpleUsCustomer"> + <field key="group_id">1</field> + </createData> + </before> + + <after> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="simplecategory" stepKey="deleteSimpleCategory"/> + <deleteData createDataKey="createSimpleUsCustomer" stepKey="deleteCustomer"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Login as a customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="signUpNewUser"> + <argument name="Customer" value="$$createSimpleUsCustomer$$"/> + </actionGroup> + + <!-- Go to configurable product page --> + <click userInput="$$simplecategory.name$$" stepKey="clickOnCategoryName"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView" after="clickOnCategoryName"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Order product with single quantity --> + <selectOption userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="configProductFillOption" /> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage"/> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForCategoryLoad"/> + + <!-- Wait till cron job runs for schedule updates --> + <wait time="60" stepKey="waitForUpdateStarts"/> + + <!-- Assert that product with single quantity is not available for order --> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView2" /> + <dontSee userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="assertOptionNotAvailable" /> + </test> +</tests> From 335c173deba047e558f44f69f5538f1a5be2b54a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 5 Sep 2018 15:13:10 +0200 Subject: [PATCH 0049/1415] Adjusted complexity limiter for developer mode --- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 10 ++++++---- .../Magento/Framework/GraphQl/Query/QueryProcessor.php | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index d2d9477e67b1e..a144ef8967f17 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -16,6 +16,8 @@ * Sets limits for query complexity. A single GraphQL query can potentially * generate thousands of database operations so, the very complex queries * should be filtered and rejected. + * + * https://github.com/webonyx/graphql-php/blob/master/docs/security.md#query-complexity-analysis */ class QueryComplexityLimiter { @@ -42,15 +44,15 @@ public function __construct( } /** - * @param bool $disableIntrospection + * @param bool $developerMode */ - public function execute(bool $disableIntrospection = false): void + public function execute(bool $developerMode = false): void { - DocumentValidator::addRule(new QueryDepth($this->queryDepth)); DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); - if ($disableIntrospection) { + if (!$developerMode) { DocumentValidator::addRule(new DisableIntrospection()); + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); } } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index e3a2ea3fa753e..57ff56b665a1e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -24,7 +24,7 @@ class QueryProcessor /** * @var QueryComplexityLimiter */ - protected $queryComplexityLimiter; + private $queryComplexityLimiter; /** * @param ExceptionFormatter $exceptionFormatter @@ -55,8 +55,8 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $disableIntrospection = !$this->exceptionFormatter->shouldShowDetail(); - $this->queryComplexityLimiter->execute($disableIntrospection); + $developerMode = !$this->exceptionFormatter->shouldShowDetail(); + $this->queryComplexityLimiter->execute($developerMode); $rootValue = null; return \GraphQL\GraphQL::executeQuery( From 614ed8af527c004041d7c504f1df3934a10a19b0 Mon Sep 17 00:00:00 2001 From: Munkh-Ulzii Balidar <mbalidar@comwrap.com> Date: Wed, 5 Sep 2018 16:47:43 +0200 Subject: [PATCH 0050/1415] remove redundant dependency --- .../Magento/AsynchronousOperations/Model/BulkManagement.php | 2 +- app/code/Magento/AsynchronousOperations/composer.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php index 169c59aa1c749..1d7d15f84163f 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php @@ -102,7 +102,7 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId // save bulk summary and related operations $connection->beginTransaction(); $userType = $this->userContext->getUserType(); - if (is_null($userType)) { + if ($userType === null) { $userType = UserContextInterface::USER_TYPE_ADMIN; } try { diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 7d5a097eeea3f..18927b5f4ecca 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -10,7 +10,6 @@ "magento/module-authorization": "*", "magento/module-backend": "*", "magento/module-ui": "*", - "magento/module-user": "*", "php": "~7.1.3||~7.2.0" }, "suggest": { From a5b048f9cb84867f5104d288223605f85378e3c9 Mon Sep 17 00:00:00 2001 From: Devagouda Patil <depatil@Devagoudas-MacBook-Pro.local> Date: Wed, 5 Sep 2018 17:24:21 -0500 Subject: [PATCH 0051/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - Updated Functional test path and schema location --- .../Mftf}/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename {dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales => app/code/Magento/Sales/Test/Mftf}/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml (98%) diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml similarity index 98% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml rename to app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index 9b629f410f4e4..3fdbb3eae0b19 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -6,7 +6,7 @@ */ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminAbleToShipPartiallyInvoicedItemsTest"> <annotations> <title value="Ship Action is available for remaining of the partially invoiced items "/> @@ -64,6 +64,7 @@ <!--Submit Order and verify information--> <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="seeCorrectGrandTotal"/> + <waitForPageLoad stepKey="waitForOrderToProcess"/> <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPage" after="clickSubmitOrder"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeSuccessMessage" after="seeViewOrderPage"/> <grabTextFrom selector="|Order # (\d+)|" stepKey="getOrderId" after="seeSuccessMessage"/> From 9d244de1504677845aa7ccbf4a61218f851b790b Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 6 Sep 2018 10:39:17 +0300 Subject: [PATCH 0052/1415] MAGETWO-91650: Translation not working for product alerts - Translate email depending on the store on which the notification button was clicked --- app/code/Magento/ProductAlert/Model/Email.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 7bc4aba351546..d425a0c6b052c 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -307,11 +307,7 @@ public function send() return false; } - if ($this->_customer->getStoreId() > 0) { - $store = $this->_storeManager->getStore($this->_customer->getStoreId()); - } else { - $store = $this->_website->getDefaultStore(); - } + $store = $this->_website->getDefaultStore(); $storeId = $store->getId(); if ($this->_type == 'price' && !$this->_scopeConfig->getValue( From ba589fe20e513bfbda46ab7e045486a4840d76e5 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 6 Sep 2018 14:43:43 +0300 Subject: [PATCH 0053/1415] MAGETWO-91753: Results of filters with color and other filters are not showing product results - Fix added --- .../Model/Search/FilterMapper/CustomAttributeFilter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php index fc93b86f5da5e..8beffab8053b9 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php @@ -141,7 +141,6 @@ private function getJoinConditions($attrId, $mainTable, $joinTable) { return [ sprintf('`%s`.`entity_id` = `%s`.`entity_id`', $mainTable, $joinTable), - sprintf('`%s`.`source_id` = `%s`.`source_id`', $mainTable, $joinTable), $this->conditionManager->generateCondition( sprintf('%s.attribute_id', $joinTable), '=', From 9a15e1f99ec742b96572285a6dd4dfb118c11d94 Mon Sep 17 00:00:00 2001 From: aman3103 <aman.agarwal@charleskeith.com> Date: Thu, 6 Sep 2018 19:45:21 +0800 Subject: [PATCH 0054/1415] making changes for Upload category image with same image name issue #17661 --- .../Category/Attribute/Backend/Image.php | 7 ++++-- .../Magento/Catalog/Model/ImageUploader.php | 23 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index cd450e26cd832..40acd20302c81 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -167,10 +167,13 @@ private function fileResidesOutsideCategoryDir($value) public function afterSave($object) { $value = $object->getData($this->additionalData . $this->getAttribute()->getName()); - + if ($this->isTmpFileAvailable($value) && $imageName = $this->getUploadedImageName($value)) { try { - $this->getImageUploader()->moveFileFromTmp($imageName); + $imageName = $this->getImageUploader()->moveFileFromTmp($imageName); + $attributeName = $this->getAttribute()->getName(); + $object->setData($attributeName, $imageName); + $this->getAttribute()->getEntity()->saveAttribute($object, $attributeName); } catch (\Exception $e) { $this->_logger->critical($e); } diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index ce92a2c1d958d..fb95f67d13c14 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -200,10 +200,21 @@ public function moveFileFromTmp($imageName) { $baseTmpPath = $this->getBaseTmpPath(); $basePath = $this->getBasePath(); - + $baseImagePath = $this->getFilePath($basePath, $imageName); $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName); - + + $destinationFileAbsolutePath = $this->mediaDirectory->getAbsolutePath($baseImagePath); + $fileInfo = pathinfo($destinationFileAbsolutePath); + if (file_exists($destinationFileAbsolutePath)) { + $index = 1; + $imageName = $fileInfo['filename'] . '.' . $fileInfo['extension']; + while (file_exists($fileInfo['dirname'] . '/' . $imageName)) { + $imageName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension']; + $index++; + } + $baseImagePath = $this->getFilePath($basePath, $imageName); + } try { $this->coreFileStorageDatabase->copyFile( $baseTmpImagePath, @@ -222,7 +233,7 @@ public function moveFileFromTmp($imageName) return $imageName; } - /** + /** * Checking file for save and save it to tmp dir * * @param string $fileId @@ -233,7 +244,7 @@ public function moveFileFromTmp($imageName) */ public function saveFileToTmpDir($fileId) { - $baseTmpPath = $this->getBaseTmpPath(); + $baseTmpPath = $this->getBaseTmpPath(); /** @var \Magento\MediaStorage\Model\File\Uploader $uploader */ $uploader = $this->uploaderFactory->create(['fileId' => $fileId]); @@ -241,8 +252,8 @@ public function saveFileToTmpDir($fileId) $uploader->setAllowRenameFiles(true); if (!$uploader->checkMimeType($this->allowedMimeTypes)) { throw new \Magento\Framework\Exception\LocalizedException(__('File validation failed.')); - } - $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); + } + $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); unset($result['path']); if (!$result) { From 6a0485ffdcd0af8bcff9b01fee06bde60c427858 Mon Sep 17 00:00:00 2001 From: aman3103 <aman.agarwal@charleskeith.com> Date: Thu, 6 Sep 2018 19:48:49 +0800 Subject: [PATCH 0055/1415] Revert "making changes for Upload category image with same image name issue #17661" This reverts commit 9a15e1f99ec742b96572285a6dd4dfb118c11d94. --- .../Category/Attribute/Backend/Image.php | 7 ++---- .../Magento/Catalog/Model/ImageUploader.php | 23 +++++-------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index 40acd20302c81..cd450e26cd832 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -167,13 +167,10 @@ private function fileResidesOutsideCategoryDir($value) public function afterSave($object) { $value = $object->getData($this->additionalData . $this->getAttribute()->getName()); - + if ($this->isTmpFileAvailable($value) && $imageName = $this->getUploadedImageName($value)) { try { - $imageName = $this->getImageUploader()->moveFileFromTmp($imageName); - $attributeName = $this->getAttribute()->getName(); - $object->setData($attributeName, $imageName); - $this->getAttribute()->getEntity()->saveAttribute($object, $attributeName); + $this->getImageUploader()->moveFileFromTmp($imageName); } catch (\Exception $e) { $this->_logger->critical($e); } diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index fb95f67d13c14..ce92a2c1d958d 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -200,21 +200,10 @@ public function moveFileFromTmp($imageName) { $baseTmpPath = $this->getBaseTmpPath(); $basePath = $this->getBasePath(); - + $baseImagePath = $this->getFilePath($basePath, $imageName); $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName); - - $destinationFileAbsolutePath = $this->mediaDirectory->getAbsolutePath($baseImagePath); - $fileInfo = pathinfo($destinationFileAbsolutePath); - if (file_exists($destinationFileAbsolutePath)) { - $index = 1; - $imageName = $fileInfo['filename'] . '.' . $fileInfo['extension']; - while (file_exists($fileInfo['dirname'] . '/' . $imageName)) { - $imageName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension']; - $index++; - } - $baseImagePath = $this->getFilePath($basePath, $imageName); - } + try { $this->coreFileStorageDatabase->copyFile( $baseTmpImagePath, @@ -233,7 +222,7 @@ public function moveFileFromTmp($imageName) return $imageName; } - /** + /** * Checking file for save and save it to tmp dir * * @param string $fileId @@ -244,7 +233,7 @@ public function moveFileFromTmp($imageName) */ public function saveFileToTmpDir($fileId) { - $baseTmpPath = $this->getBaseTmpPath(); + $baseTmpPath = $this->getBaseTmpPath(); /** @var \Magento\MediaStorage\Model\File\Uploader $uploader */ $uploader = $this->uploaderFactory->create(['fileId' => $fileId]); @@ -252,8 +241,8 @@ public function saveFileToTmpDir($fileId) $uploader->setAllowRenameFiles(true); if (!$uploader->checkMimeType($this->allowedMimeTypes)) { throw new \Magento\Framework\Exception\LocalizedException(__('File validation failed.')); - } - $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); + } + $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); unset($result['path']); if (!$result) { From 9294de3c69360ee3af2471ba2a6e634b2ef7f397 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 6 Sep 2018 17:30:15 +0300 Subject: [PATCH 0056/1415] MAGETWO-67779: Datetime attribute break fulltextsearch in case of Elasticseach - Eliminated attribute with type 'datetime' from ElasticSearch --- .../Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php | 2 +- app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php | 2 +- .../Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index d11603295453d..855ebbb76393c 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -37,7 +37,7 @@ public function getFieldType($attribute) $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); - if (in_array($backendType, ['timestamp', 'datetime'], true)) { + if ($backendType === 'timestamp') { $fieldType = self::ES_DATA_TYPE_DATE; } elseif ((in_array($backendType, ['int', 'smallint'], true) || (in_array($frontendInput, ['select', 'boolean'], true) && $backendType !== 'varchar')) diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 4315597a3cf58..28587bca3cc85 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -36,7 +36,7 @@ public function getFieldType($attribute) $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); - if (in_array($backendType, ['timestamp', 'datetime'], true)) { + if ($backendType === 'timestamp') { $fieldType = self::ES_DATA_TYPE_DATE; } elseif ((in_array($backendType, ['int', 'smallint'], true) || (in_array($frontendInput, ['select', 'boolean'], true) && $backendType !== 'varchar')) diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php index 63c993e27c9a9..e9ce18ef0d3ff 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php @@ -94,7 +94,7 @@ public static function attributeTypesProvider() ['attr1', 'static', 'select', 'integer'], ['attr1', 'static', 'text', 'text'], ['attr1', 'timestamp', 'select', 'date'], - ['attr1', 'datetime', 'text', 'date'], + ['attr1', 'datetime', 'text', 'text'], ['attr1', 'int', 'select', 'integer'], ['attr1', 'decimal', 'text', 'float'], ['attr1', 'varchar', 'select', 'text'], From df6bc3769f1d5b6c2afc394586aa21113d915d1f Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 6 Sep 2018 17:11:24 -0500 Subject: [PATCH 0057/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Catalog/view/adminhtml/web/js/options.js | 12 ++++++-- .../adminhtml/web/js/product-attributes.js | 29 ++++++++++++------- lib/web/mage/backend/validation.js | 2 ++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 6ea005915763c..a4b3ca95e45da 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -145,7 +145,9 @@ define([ return optionDefaultInputType; } - }; + }, + formContent = jQuery(), + optionTable = optionPanel.find('table'); if ($('add_new_option_button')) { Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true)); @@ -180,7 +182,7 @@ define([ }); }); } - editForm.on('submit', function () { + editForm.on('beforeSubmit', function () { optionPanel.find('input') .each(function () { if (this.disabled) { @@ -202,9 +204,13 @@ define([ }) .val(JSON.stringify(optionsValues)) .prependTo(editForm); - optionPanel.find('table') + formContent = optionTable.clone(true); + optionTable .replaceWith(jQuery('<div>').text(jQuery.mage.__('Sending attribute values as package.'))); }); + editForm.on('afterValidate.error', function () { + optionTable.replaceWith(formContent); + }); window.attributeOption = attributeOption; window.optionDefaultInputType = attributeOption.getOptionInputType(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 01411523108cf..870d1dedefede 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -414,7 +414,15 @@ define([ }; $(function () { - var editForm = $('#edit_form'); + var editForm = $('#edit_form'), + swatchVisualPanel = $('#swatch-visual-options-panel'), + swatchTextPanel = $('#swatch-text-options-panel'), + activePanel, + formContent = $(), + optionTable; + + activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; + optionTable = activePanel.find('table'); $('#frontend_input').bind('change', function () { swatchProductAttributes.bindAttributeInputType(); @@ -430,16 +438,11 @@ define([ .collapsable() .collapse('hide'); - editForm.on('submit', function () { - var activePanel, - swatchValues = [], - swatchVisualPanel = $('#swatch-visual-options-panel'), - swatchTextPanel = $('#swatch-text-options-panel'); - - activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; + editForm.on('beforeSubmit', function () { + var swatchValues = []; - activePanel - .find('table input') + optionTable + .find('input') .each(function () { swatchValues.push(this.name + '=' + $(this).val()); }); @@ -452,11 +455,17 @@ define([ .val(JSON.stringify(swatchValues)) .prependTo(editForm); + formContent = optionTable.clone(true); + [swatchVisualPanel, swatchTextPanel].forEach(function (el) { $(el).find('table') .replaceWith($('<div>').text($.mage.__('Sending swatch values as package.'))); }); }); + + editForm.on('afterValidate.error', function () { + optionTable.replaceWith(formContent); + }); }); window.saveAttributeInNewSet = swatchProductAttributes.saveAttributeInNewSet; diff --git a/lib/web/mage/backend/validation.js b/lib/web/mage/backend/validation.js index d3ab7dd086a43..1043f45a7402e 100644 --- a/lib/web/mage/backend/validation.js +++ b/lib/web/mage/backend/validation.js @@ -171,6 +171,7 @@ this._submit(); } else { this._showErrors(response); + $(this.element[0]).trigger('afterValidate.error'); $('body').trigger('processStop'); } }, @@ -223,6 +224,7 @@ * @protected */ _onError: function () { + $(this.element[0]).trigger('afterValidate.error'); $('body').trigger('processStop'); if (this.options.errorUrl) { From 0ff4e4ead023aa878823bc6d28aaf74d7851b98d Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Fri, 7 Sep 2018 13:10:46 +0400 Subject: [PATCH 0058/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Remove test from CE --- .../Mftf/Section/AdminSalesConfigSection.xml | 10 ---- .../CheckingGiftOptionsActionGroup.xml | 8 +-- .../Test/Mftf/Data/GiftOptionsData.xml | 13 +--- .../Test/Mftf/Metadata/gift_options-meta.xml | 31 ---------- .../StoreFrontCheckingGiftOptionsTest.xml | 59 ------------------- .../Mftf/Section/MultishippingSection.xml} | 5 +- ...AdminShipmentAddressInformationSection.xml | 3 +- 7 files changed, 9 insertions(+), 120 deletions(-) delete mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml delete mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml rename app/code/Magento/{Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml => Multishipping/Test/Mftf/Section/MultishippingSection.xml} (51%) diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml index aefb7c5441c5b..95a9f75768c62 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml @@ -10,18 +10,8 @@ <element name="enableMAPUseSystemValue" type="checkbox" selector="#sales_msrp_enabled_inherit"/> <element name="enableMAPSelect" type="select" selector="#sales_msrp_enabled"/> <element name="giftOptions" type="select" selector="#sales_gift_options-head"/> - <element name="allowGiftWrappingOnOrderLevel" type="select" selector="#sales_gift_options_wrapping_allow_order"/> - <element name="levelNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='No']"/> - <element name="levelYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='Yes']"/> - <element name="allowGiftWrappingForOrderItems" type="select" selector="#sales_gift_options_wrapping_allow_items"/> - <element name="itemsNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='No']"/> - <element name="itemsYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='Yes']"/> <element name="allowGiftReceipt" type="select" selector="#sales_gift_options_allow_gift_receipt"/> - <element name="receiptNo" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='No']"/> - <element name="receiptYes" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='Yes']"/> <element name="allowPrintedCard" type="select" selector="#sales_gift_options_allow_printed_card"/> - <element name="printedCardNo" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='No']"/> - <element name="printedCardYes" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='Yes']"/> <element name="go" type="select" selector="//a[@id='sales_gift_options-head']/ancestor::div[@class='entry-edit-head admin__collapsible-block']"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml index 05dad757e287f..f81877006c7a6 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml @@ -7,11 +7,11 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <actionGroup name="CheckingGiftOptionsActionGroup"> - <click stepKey="clickOnCheckoutWithMultipleAddresses" selector="{{StoreFrontShoppingCartSection.checkoutWithMultipleAddresses}}"/> - <waitForPageLoad stepKey="waitForShipToMultipleAddresses"/> - <click stepKey="goToShippingInformation" selector="{{StoreFrontShoppingCartSection.goToShippingInformation}}"/> + <click stepKey="clickOnCheckoutWithMultipleAddresses" selector="{{MultishippingSection.checkoutWithMultipleAddresses}}"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <click stepKey="goToShippingInformation" selector="{{AdminShipmentAddressInformationSection.goToShippingInformation}}"/> <waitForPageLoad stepKey="waitForGiftOption"/> <click stepKey="thickAddGiftOptions" selector="{{GiftOptionsOnFrontSection.giftOptionCheckbox}}"/> <waitForPageLoad stepKey="waitForOptions"/> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml index b2bc71b5b7a7b..951bbd3b787b7 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml @@ -7,15 +7,7 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="ConfigAllowGiftWrappingForOrderItemsOnly" type="gift_options_config_state"> - <requiredEntity type="wrapping_allow_order">wrappingAllowOrder</requiredEntity> - <requiredEntity type="allow_gift_receipt">allowGiftReceipt</requiredEntity> - <requiredEntity type="allow_printed_card">allowPrintedCard</requiredEntity> - </entity> - <entity name="wrappingAllowOrder" type="wrapping_allow_order"> - <data key="value">0</data> - </entity> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <entity name="allowGiftReceipt" type="allow_gift_receipt"> <data key="value">0</data> </entity> @@ -28,9 +20,6 @@ <requiredEntity type="allow_gift_receipt">defaultAllowGiftReceipt</requiredEntity> <requiredEntity type="allow_printed_card">defaultAllowPrintedCard</requiredEntity> </entity> - <entity name="defaultWrappingAllowOrder" type="wrapping_allow_order"> - <data key="value">1</data> - </entity> <entity name="defaultAllowGiftReceipt" type="allow_gift_receipt"> <data key="value">1</data> </entity> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml deleted file mode 100644 index a32f5694f2470..0000000000000 --- a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> - <operation name="SalesGiftOptionsConfigState" dataType="gift_options_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="gift_options_config_state"> - <object key="gift_options" dataType="gift_options_config_state"> - <object key="fields" dataType="gift_options_config_state"> - <object key="wrapping_allow_order" dataType="wrapping_allow_order"> - <field key="value">string</field> - </object> - <object key="wrapping_allow_items" dataType="wrapping_allow_items"> - <field key="value">string</field> - </object> - <object key="allow_gift_receipt" dataType="allow_gift_receipt"> - <field key="value">string</field> - </object> - <object key="allow_printed_card" dataType="allow_printed_card"> - <field key="value">string</field> - </object> - </object> - </object> - </object> - </operation> -</operations> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml deleted file mode 100644 index 0bb5bf0e71fa8..0000000000000 --- a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="StoreFrontCheckingGiftOptionsTest"> - <annotations> - <features value="Gift"/> - <stories value="Checking Gift Options on front end order page"/> - <title value="Checking Gift Options on front end order page"/> - <description value="Admin should be able to control gift options"/> - <severity value="MAJOR"/> - <testCaseId value="MAGETWO-94209"/> - <group value="Gift"/> - </annotations> - <before> - <createData stepKey="category" entity="SimpleSubCategory"/> - <createData stepKey="product1" entity="SimpleProduct"> - <requiredEntity createDataKey="category"/> - </createData> - <createData stepKey="product2" entity="SimpleProduct"> - <requiredEntity createDataKey="category"/> - </createData> - <createData entity="Simple_US_Customer" stepKey="customer"/> - <createData entity="ConfigAllowGiftWrappingForOrderItemsOnly" stepKey="configAllowGiftWrappingForOrderItemsOnly"/> - - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> - <argument name="Customer" value="$$customer$$"/> - </actionGroup> - - </before> - - <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> - <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct1"> - <argument name="productName" value="$$product1.name$$"/> - </actionGroup> - <amOnPage url="$$product2.name$$.html" stepKey="goToProduct2"/> - <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct2"> - <argument name="productName" value="$$product2.name$$"/> - </actionGroup> - <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> - <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> - - <after> - <createData entity="DefaultConfigGiftOptions" stepKey="restoreDefaultConfigGiftOptions"/> - <deleteData stepKey="deleteCategory" createDataKey="category"/> - <deleteData stepKey="deleteProduct1" createDataKey="product1"/> - <deleteData stepKey="deleteProduct2" createDataKey="product2"/> - <deleteData stepKey="deleteCustomer" createDataKey="customer"/> - <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> - </after> - </test> -</tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml similarity index 51% rename from app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml rename to app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index 303c5e526423f..e7d57af1172c6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -7,9 +7,8 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="StoreFrontShoppingCartSection"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <section name="MultishippingSection"> <element name="checkoutWithMultipleAddresses" type="button" selector="//span[text()='Check Out with Multiple Addresses']"/> - <element name="goToShippingInformation" type="button" selector="//button[@title='Go to Shipping Information']"/> </section> </sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml index ea4dde8190bc7..10878310c262f 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml @@ -7,11 +7,12 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="AdminShipmentAddressInformationSection"> <element name="billingAddress" type="text" selector=".order-billing-address address"/> <element name="billingAddressEdit" type="button" selector=".order-billing-address .actions a"/> <element name="shippingAddress" type="text" selector=".order-shipping-address address"/> <element name="shippingAddressEdit" type="button" selector=".order-shipping-address .actions a"/> + <element name="goToShippingInformation" type="button" selector="//button[@title='Go to Shipping Information']"/> </section> </sections> From 76f7ab6fb6de62668da5cbff758ac5ecaff0c6d1 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Fri, 7 Sep 2018 13:24:50 +0300 Subject: [PATCH 0059/1415] MAGETWO-91495: 'Invalid data provided for linked products' error on 'Save & Duplicate' product action - Fix added --- app/code/Magento/Catalog/Model/Product/Copier.php | 3 ++- .../Model/Product/AnchorUrlRewriteGenerator.php | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index e94104ae473a0..d86118eeca67a 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -78,7 +78,8 @@ public function copy(\Magento\Catalog\Model\Product $product) $urlKey = preg_match('/(.*)-(\d+)$/', $urlKey, $matches) ? $matches[1] . '-' . ($matches[2] + 1) : $urlKey . '-1'; - $duplicate->setUrlKey($urlKey); + $duplicate->setUrlKey($urlKey) + ->setUrlPath(null); try { $duplicate->save(); $isDuplicateSaved = true; diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php index a7cc894c9a022..b3e8b0e2b0df5 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php @@ -62,6 +62,9 @@ public function generate($storeId, Product $product, ObjectRegistry $productCate if ($anchorCategoryIds) { foreach ($anchorCategoryIds as $anchorCategoryId) { $anchorCategory = $this->categoryRepository->get($anchorCategoryId); + if ($anchorCategory->getParentId() == \Magento\Catalog\Model\Category::TREE_ROOT_ID) { + continue; + } $urls[] = $this->urlRewriteFactory->create() ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE) ->setEntityId($product->getId()) From 10765ab93c5336dbab89c71f80a0fe14db9ca38a Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 7 Sep 2018 14:35:54 +0300 Subject: [PATCH 0060/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixes after discussion. Added configuration to enable/disable toolbar memorizing. --- .../Block/Product/ProductList/Toolbar.php | 19 ++++---- .../Product/ProductList/ToolbarMemorizer.php | 48 +++++++++++-------- .../Magento/Catalog/etc/adminhtml/system.xml | 6 +++ app/code/Magento/Catalog/etc/config.xml | 1 + 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 0e971dcb5b9f5..e3ed8ef94b74b 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -274,7 +274,7 @@ public function getCurrentOrder() $order = $defaultOrder; } - if ($order != $defaultOrder) { + if ($order != $defaultOrder && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } @@ -300,7 +300,7 @@ public function getCurrentDirection() $dir = $this->_direction; } - if ($dir != $this->_direction) { + if ($dir != $this->_direction && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } @@ -442,7 +442,7 @@ public function getCurrentMode() $mode = $defaultMode; } - if ($mode != $defaultMode) { + if ($mode != $defaultMode && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); } @@ -602,7 +602,7 @@ public function getLimit() $limit = $defaultLimit; } - if ($limit != $defaultLimit) { + if ($limit != $defaultLimit && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } @@ -711,15 +711,18 @@ public function getPagerHtml() public function getWidgetOptionsJson(array $customOptions = []) { $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); + $defaultDirection = $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION; + $isMemorizingAllowed = $this->toolbarMemorizer->isMemorizingAllowed(); $options = [ 'mode' => ToolbarModel::MODE_PARAM_NAME, 'direction' => ToolbarModel::DIRECTION_PARAM_NAME, 'order' => ToolbarModel::ORDER_PARAM_NAME, 'limit' => ToolbarModel::LIMIT_PARAM_NAME, - 'modeDefault' => $defaultMode, - 'directionDefault' => $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION, - 'orderDefault' => $this->getOrderField(), - 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), + 'modeDefault' => $isMemorizingAllowed ? false : $defaultMode, + 'directionDefault' => $isMemorizingAllowed ? false : $defaultDirection, + 'orderDefault' => $isMemorizingAllowed ? false : $this->getOrderField(), + 'limitDefault' => $isMemorizingAllowed ? false : + $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), ]; $options = array_replace_recursive($options, $customOptions); diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php index 1ff63a0fa3448..4e65a4f9853e7 100644 --- a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -3,9 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Catalog\Model\Product\ProductList; use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\App\Config\ScopeConfigInterface; /** * Class ToolbarMemorizer @@ -14,6 +18,11 @@ */ class ToolbarMemorizer { + /** + * XML PATH to enable/disable saving toolbar parameters to session + */ + const XML_PATH_CATALOG_REMEMBER_PAGINATION = 'catalog/frontend/remember_pagination'; + /** * @var CatalogSession */ @@ -25,9 +34,9 @@ class ToolbarMemorizer private $toolbarModel; /** - * @var bool + * @var ScopeConfigInterface */ - private $paramsMemorizeAllowed = true; + private $scopeConfig; /** * @var string|bool @@ -52,13 +61,16 @@ class ToolbarMemorizer /** * @param Toolbar $toolbarModel * @param CatalogSession $catalogSession + * @param ScopeConfigInterface $scopeConfig */ public function __construct( Toolbar $toolbarModel, - CatalogSession $catalogSession + CatalogSession $catalogSession, + ScopeConfigInterface $scopeConfig ) { $this->toolbarModel = $toolbarModel; $this->catalogSession = $catalogSession; + $this->scopeConfig = $scopeConfig; } /** @@ -118,27 +130,28 @@ public function getLimit() } /** - * Disable list state params memorizing + * Method to save all catalog parameters in catalog session * - * @return $this + * @return void */ - public function disableParamsMemorizing() + public function memorizeParams() { - $this->paramsMemorizeAllowed = false; - return $this; + if (!$this->catalogSession->getParamsMemorizeDisabled() && $this->isMemorizingAllowed()) { + $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) + ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) + ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) + ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + } } /** - * Method to save all catalog parameters in catalog session + * Check configuration for enabled/disabled toolbar memorizing * - * @return void + * @return bool */ - public function memorizeParams() + public function isMemorizingAllowed() { - $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) - ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) - ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) - ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + return $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); } /** @@ -150,10 +163,7 @@ public function memorizeParams() */ private function memorizeParam($param, $value) { - if ($value && $this->paramsMemorizeAllowed && - !$this->catalogSession->getParamsMemorizeDisabled() && - $this->catalogSession->getData($param) != $value - ) { + if ($value && $this->catalogSession->getData($param) != $value) { $this->catalogSession->setData($param, $value); } return $this; diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 71a799fd22427..be35ae2e5549d 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -92,6 +92,12 @@ <comment>Whether to show "All" option in the "Show X Per Page" dropdown</comment> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> + <field id="remember_pagination" translate="label comment" type="select" sortOrder="7" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Remember Category Pagination</label> + <comment>Note that SEO and performance experience may be negative by this feature enabled. + Also it will increase cache storage consumption.</comment> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + </field> </group> <group id="placeholder" translate="label" sortOrder="300" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Product Image Placeholders</label> diff --git a/app/code/Magento/Catalog/etc/config.xml b/app/code/Magento/Catalog/etc/config.xml index 1d92197e390a1..9ede3885f9a78 100644 --- a/app/code/Magento/Catalog/etc/config.xml +++ b/app/code/Magento/Catalog/etc/config.xml @@ -30,6 +30,7 @@ <flat_catalog_category>0</flat_catalog_category> <default_sort_by>position</default_sort_by> <parse_url_directives>1</parse_url_directives> + <remember_pagination>0</remember_pagination> </frontend> <product> <flat> From cd649d162681f3698cb0f989cb624f79ae9f4dfc Mon Sep 17 00:00:00 2001 From: Oleksandr_Hodzevych <Oleksandr_Hodzevych@epam.com> Date: Fri, 7 Sep 2018 15:10:50 +0300 Subject: [PATCH 0061/1415] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fixed widget operator less or more --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 1afe995f837ea..01c671f0b0678 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -32,11 +32,11 @@ class Builder '==' => ':field = ?', '!=' => ':field <> ?', '>=' => ':field >= ?', - '>e;' => ':field >= ?', + '>=' => ':field >= ?', '>' => ':field > ?', '>' => ':field > ?', '<=' => ':field <= ?', - '<e;' => ':field <= ?', + '<=' => ':field <= ?', '<' => ':field < ?', '<' => ':field < ?', '{}' => ':field IN (?)', From 502e415c948db0eaa72ddd1b3dbe57879e0d97f6 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 7 Sep 2018 17:37:49 +0300 Subject: [PATCH 0062/1415] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed issue with incorrect url path generation for children categories; --- .../CategoryUrlPathAutogeneratorObserver.php | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index eb54f0427c11a..5c7a8b16a666e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -8,6 +8,7 @@ use Magento\Catalog\Model\Category; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; use Magento\CatalogUrlRewrite\Service\V1\StoreViewService; +use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\Event\Observer; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; use Magento\Framework\Event\ObserverInterface; @@ -30,19 +31,27 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface */ protected $storeViewService; + /** + * @var CategoryRepositoryInterface + */ + private $categoryRepository; + /** * @param CategoryUrlPathGenerator $categoryUrlPathGenerator * @param ChildrenCategoriesProvider $childrenCategoriesProvider * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService + * @param CategoryRepositoryInterface $categoryRepository */ public function __construct( CategoryUrlPathGenerator $categoryUrlPathGenerator, ChildrenCategoriesProvider $childrenCategoriesProvider, - StoreViewService $storeViewService + StoreViewService $storeViewService, + CategoryRepositoryInterface $categoryRepository ) { $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; $this->childrenCategoriesProvider = $childrenCategoriesProvider; $this->storeViewService = $storeViewService; + $this->categoryRepository = $categoryRepository; } /** @@ -77,22 +86,22 @@ public function execute(\Magento\Framework\Event\Observer $observer) */ protected function updateUrlPathForChildren(Category $category) { - $children = $this->childrenCategoriesProvider->getChildren($category, true); - if ($this->isGlobalScope($category->getStoreId())) { - foreach ($children as $child) { + $childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); + foreach ($childrenIds as $childId) { foreach ($category->getStoreIds() as $storeId) { if ($this->storeViewService->doesEntityHaveOverriddenUrlPathForStore( $storeId, - $child->getId(), + $childId, Category::ENTITY )) { - $child->setStoreId($storeId); + $child = $this->categoryRepository->get($childId, $storeId); $this->updateUrlPathForCategory($child); } } } } else { + $children = $this->childrenCategoriesProvider->getChildren($category, true); foreach ($children as $child) { $child->setStoreId($category->getStoreId()); $this->updateUrlPathForCategory($child); From 7831ac34c037ead0204526ef6b5acdf4dedbb0a6 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Fri, 7 Sep 2018 18:38:12 +0400 Subject: [PATCH 0063/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Update automated test --- .../Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index ea07db7b3f951..253eb7a3be609 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AssociatedProductToConfigurableOutOfStockTest"> <annotations> <features value="CatalogInventory"/> From de672221506c6ec7ce506e6499ac9ab16d69acf3 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 7 Sep 2018 17:06:23 -0500 Subject: [PATCH 0064/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Adminhtml/Product/Attribute/Save.php | 36 +++++++++---- .../Adminhtml/Product/Attribute/Validate.php | 27 ++++++++-- .../Attribute/Option/OptionsDataProvider.php | 39 +++++++++++++++ .../Catalog/view/adminhtml/web/js/options.js | 50 ++++++++++--------- .../Product/Attribute/Plugin/Save.php | 9 ---- 5 files changed, 115 insertions(+), 46 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index 817de6828e48d..a7076ba8526fe 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -13,6 +13,7 @@ use Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Helper\Product; use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataProvider; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator; @@ -75,6 +76,11 @@ class Save extends Attribute */ private $presentation; + /** + * @var OptionsDataProvider|null + */ + private $optionsDataProvider; + /** * @param Context $context * @param FrontendInterface $attributeLabelCache @@ -88,6 +94,7 @@ class Save extends Attribute * @param Product $productHelper * @param LayoutFactory $layoutFactory * @param Presentation|null $presentation + * @param OptionsDataProvider|null $optionsDataProvider * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -102,7 +109,8 @@ public function __construct( FilterManager $filterManager, Product $productHelper, LayoutFactory $layoutFactory, - Presentation $presentation = null + Presentation $presentation = null, + OptionsDataProvider $optionsDataProvider = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->buildFactory = $buildFactory; @@ -113,6 +121,8 @@ public function __construct( $this->groupCollectionFactory = $groupCollectionFactory; $this->layoutFactory = $layoutFactory; $this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class); + $this->optionsDataProvider = $optionsDataProvider + ?: ObjectManager::getInstance()->get(OptionsDataProvider::class); } /** @@ -123,7 +133,21 @@ public function __construct( */ public function execute() { + try { + $optionData = $this->optionsDataProvider->getOptionsData($this->getRequest()); + } catch (\InvalidArgumentException $e) { + $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " + . "If the error persists, please try again later."); + $this->messageManager->addErrorMessage($message); + return $this->returnResult('catalog/*/edit', ['_current' => true], ['error' => true]); + } + $data = $this->getRequest()->getPostValue(); + $data = array_merge_recursive( + $data, + $optionData + ); + if ($data) { $this->preprocessOptionsData($data); $setId = $this->getRequest()->getParam('set'); @@ -326,15 +350,7 @@ public function execute() */ private function preprocessOptionsData(&$data) { - if (isset($data['serialized_options'])) { - $serializedOptions = json_decode($data['serialized_options'], JSON_OBJECT_AS_ARRAY); - foreach ($serializedOptions as $serializedOption) { - $option = []; - parse_str($serializedOption, $option); - $data = array_replace_recursive($data, $option); - } - } - unset($data['serialized_options']); + } /** diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index db452113ada06..35cc2a903bc96 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -7,6 +7,8 @@ namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataProvider; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute @@ -28,6 +30,11 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute */ private $multipleAttributeList; + /** + * @var OptionsDataProvider|null + */ + private $optionsDataProvider; + /** * Constructor * @@ -38,6 +45,7 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param array $multipleAttributeList + * @param OptionsDataProvider|null $optionsDataProvider */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -46,12 +54,15 @@ public function __construct( \Magento\Framework\View\Result\PageFactory $resultPageFactory, \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, - array $multipleAttributeList = [] + array $multipleAttributeList = [], + OptionsDataProvider $optionsDataProvider = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->multipleAttributeList = $multipleAttributeList; + $this->optionsDataProvider = $optionsDataProvider ?: ObjectManager::getInstance() + ->get(OptionsDataProvider::class); } /** @@ -63,6 +74,14 @@ public function execute() { $response = new DataObject(); $response->setError(false); + try { + $optionsData = $this->optionsDataProvider->getOptionsData($this->getRequest()); + } catch (\InvalidArgumentException $e) { + $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " + . "If the error persists, please try again later."); + $this->setMessageToResponse($response, [$message]); + $response->setError(true); + } $attributeCode = $this->getRequest()->getParam('attribute_code'); $frontendLabel = $this->getRequest()->getParam('frontend_label'); @@ -102,10 +121,10 @@ public function execute() } $multipleOption = $this->getRequest()->getParam("frontend_input"); - $multipleOption = null == $multipleOption ? 'select' : $multipleOption; + $multipleOption = (null === $multipleOption) ? 'select' : $multipleOption; - if (isset($this->multipleAttributeList[$multipleOption]) && !(null == ($multipleOption))) { - $options = $this->getRequest()->getParam($this->multipleAttributeList[$multipleOption]); + if (isset($this->multipleAttributeList[$multipleOption])) { + $options = $optionsData[$this->multipleAttributeList[$multipleOption]] ?? null; $this->checkUniqueOption( $response, $options diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php new file mode 100644 index 0000000000000..a2a1fcb7fb526 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\Product\Attribute\Option; + +use Magento\Framework\App\RequestInterface; + +class OptionsDataProvider +{ + /** + * @param RequestInterface $request + * @return array + * @throws \InvalidArgumentException + */ + public function getOptionsData(RequestInterface $request): array + { + $serializedOptions = $request->getParam('serialized_options'); + $optionsData = []; + + if ($serializedOptions) { + $encodedOptions = json_decode($serializedOptions, JSON_OBJECT_AS_ARRAY); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \InvalidArgumentException('Unable to unserialize options data.'); + } + + foreach ($encodedOptions as $encodedOption) { + $decodedOptionData = []; + parse_str($encodedOption, $decodedOptionData); + $optionsData = array_replace_recursive($optionsData, $decodedOptionData); + } + } + + return $optionsData; + } +} \ No newline at end of file diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index a4b3ca95e45da..233f554512f8c 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -146,8 +146,8 @@ define([ return optionDefaultInputType; } }, - formContent = jQuery(), - optionTable = optionPanel.find('table'); + optionsTableContent = jQuery(), + optionContainer = optionPanel.find('table tbody'); if ($('add_new_option_button')) { Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true)); @@ -183,33 +183,37 @@ define([ }); } editForm.on('beforeSubmit', function () { - optionPanel.find('input') - .each(function () { - if (this.disabled) { - return; - } + if (optionPanel.is(':visible')) { + optionContainer.find('input') + .each(function () { + if (this.disabled) { + return; + } - if (this.type === 'checkbox' || this.type === 'radio') { - if (this.checked) { + if (this.type === 'checkbox' || this.type === 'radio') { + if (this.checked) { + optionsValues.push(this.name + '=' + jQuery(this).val()); + } + } else { optionsValues.push(this.name + '=' + jQuery(this).val()); } - } else { - optionsValues.push(this.name + '=' + jQuery(this).val()); - } - }); - jQuery('<input>') - .attr({ - type: 'hidden', - name: 'serialized_options' - }) - .val(JSON.stringify(optionsValues)) - .prependTo(editForm); - formContent = optionTable.clone(true); - optionTable + }); + jQuery('<input>') + .attr({ + type: 'hidden', + name: 'serialized_options' + }) + .val(JSON.stringify(optionsValues)) + .prependTo(editForm); + } + optionsTableContent = optionContainer.clone(true); + optionContainer .replaceWith(jQuery('<div>').text(jQuery.mage.__('Sending attribute values as package.'))); }); editForm.on('afterValidate.error', function () { - optionTable.replaceWith(formContent); + if (optionPanel.is(':visible')) { + optionContainer.replaceWith(optionsTableContent); + } }); window.attributeOption = attributeOption; window.optionDefaultInputType = attributeOption.getOptionInputType(); diff --git a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php index 383c97a166d34..9ec65fb08045c 100644 --- a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php +++ b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php @@ -26,15 +26,6 @@ public function beforeDispatch(Attribute\Save $subject, RequestInterface $reques $data = $request->getPostValue(); if (isset($data['frontend_input'])) { - //Data is serialized to overcome issues caused by max_input_vars value if it's modification is unavailable. - //See subject controller code and comments for more info. - if (isset($data['serialized_swatch_values']) - && in_array($data['frontend_input'], ['swatch_visual', 'swatch_text']) - ) { - $data['serialized_options'] = $data['serialized_swatch_values']; - unset($data['serialized_swatch_values']); - } - switch ($data['frontend_input']) { case 'swatch_visual': $data[Swatch::SWATCH_INPUT_TYPE_KEY] = Swatch::SWATCH_INPUT_TYPE_VISUAL; From 8ec2c30e99f70a7ba78602f51476c38625200f1e Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Sun, 9 Sep 2018 19:34:52 -0500 Subject: [PATCH 0065/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../adminhtml/web/js/product-attributes.js | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 870d1dedefede..dd1fb4b0a8b54 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -417,12 +417,9 @@ define([ var editForm = $('#edit_form'), swatchVisualPanel = $('#swatch-visual-options-panel'), swatchTextPanel = $('#swatch-text-options-panel'), - activePanel, - formContent = $(), - optionTable; - - activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; - optionTable = activePanel.find('table'); + optionsTableContent = $(), + optionContainer = $(), + activePanel = $(); $('#frontend_input').bind('change', function () { swatchProductAttributes.bindAttributeInputType(); @@ -441,22 +438,26 @@ define([ editForm.on('beforeSubmit', function () { var swatchValues = []; - optionTable - .find('input') - .each(function () { - swatchValues.push(this.name + '=' + $(this).val()); - }); + activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; + optionContainer = activePanel.find('table tbody'); - $('<input>') - .attr({ - type: 'hidden', - name: 'serialized_swatch_values' - }) - .val(JSON.stringify(swatchValues)) - .prependTo(editForm); + if (activePanel.is(':visible')) { + optionContainer + .find('input') + .each(function () { + swatchValues.push(this.name + '=' + $(this).val()); + }); - formContent = optionTable.clone(true); + $('<input>') + .attr({ + type: 'hidden', + name: 'serialized_options' + }) + .val(JSON.stringify(swatchValues)) + .prependTo(editForm); + } + optionsTableContent = optionContainer.clone(true); [swatchVisualPanel, swatchTextPanel].forEach(function (el) { $(el).find('table') .replaceWith($('<div>').text($.mage.__('Sending swatch values as package.'))); @@ -464,7 +465,9 @@ define([ }); editForm.on('afterValidate.error', function () { - optionTable.replaceWith(formContent); + if (activePanel.is(':visible')) { + optionContainer.replaceWith(optionsTableContent); + } }); }); From 616eb6d5a9f0ac88730c8db38b40d151f64e94f4 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 10 Sep 2018 13:20:09 -0500 Subject: [PATCH 0066/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Adminhtml/Product/Attribute/Save.php | 31 +++++-------------- .../Adminhtml/Product/Attribute/Validate.php | 18 +++++------ ...taProvider.php => OptionsDataResolver.php} | 9 ++++-- .../Catalog/view/adminhtml/web/js/options.js | 14 ++++----- .../adminhtml/web/js/product-attributes.js | 15 ++++----- 5 files changed, 37 insertions(+), 50 deletions(-) rename app/code/Magento/Catalog/Model/Product/Attribute/Option/{OptionsDataProvider.php => OptionsDataResolver.php} (88%) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index a7076ba8526fe..825288b366410 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -13,7 +13,7 @@ use Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Helper\Product; use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataProvider; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator; @@ -77,9 +77,9 @@ class Save extends Attribute private $presentation; /** - * @var OptionsDataProvider|null + * @var OptionsDataResolver|null */ - private $optionsDataProvider; + private $optionsDataResolver; /** * @param Context $context @@ -94,7 +94,7 @@ class Save extends Attribute * @param Product $productHelper * @param LayoutFactory $layoutFactory * @param Presentation|null $presentation - * @param OptionsDataProvider|null $optionsDataProvider + * @param OptionsDataResolver|null $optionsDataResolver * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -110,7 +110,7 @@ public function __construct( Product $productHelper, LayoutFactory $layoutFactory, Presentation $presentation = null, - OptionsDataProvider $optionsDataProvider = null + OptionsDataResolver $optionsDataResolver = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->buildFactory = $buildFactory; @@ -121,8 +121,8 @@ public function __construct( $this->groupCollectionFactory = $groupCollectionFactory; $this->layoutFactory = $layoutFactory; $this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class); - $this->optionsDataProvider = $optionsDataProvider - ?: ObjectManager::getInstance()->get(OptionsDataProvider::class); + $this->optionsDataResolver = $optionsDataResolver + ?: ObjectManager::getInstance()->get(OptionsDataResolver::class); } /** @@ -134,7 +134,7 @@ public function __construct( public function execute() { try { - $optionData = $this->optionsDataProvider->getOptionsData($this->getRequest()); + $optionData = $this->optionsDataResolver->getOptionsData($this->getRequest()); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " . "If the error persists, please try again later."); @@ -149,7 +149,6 @@ public function execute() ); if ($data) { - $this->preprocessOptionsData($data); $setId = $this->getRequest()->getParam('set'); $attributeSet = null; @@ -339,20 +338,6 @@ public function execute() return $this->returnResult('catalog/*/', [], ['error' => true]); } - /** - * Extract options data from serialized options field and append to data array. - * - * This logic is required to overcome max_input_vars php limit - * that may vary and/or be inaccessible to change on different instances. - * - * @param array $data - * @return void - */ - private function preprocessOptionsData(&$data) - { - - } - /** * @param string $path * @param array $params diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 35cc2a903bc96..fa8103f703367 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -7,7 +7,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataProvider; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; @@ -31,9 +31,9 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute private $multipleAttributeList; /** - * @var OptionsDataProvider|null + * @var OptionsDataResolver|null */ - private $optionsDataProvider; + private $optionsDataResolver; /** * Constructor @@ -45,7 +45,7 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param array $multipleAttributeList - * @param OptionsDataProvider|null $optionsDataProvider + * @param OptionsDataResolver|null $optionsDataResolver */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -55,14 +55,14 @@ public function __construct( \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, array $multipleAttributeList = [], - OptionsDataProvider $optionsDataProvider = null + OptionsDataResolver $optionsDataResolver = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->multipleAttributeList = $multipleAttributeList; - $this->optionsDataProvider = $optionsDataProvider ?: ObjectManager::getInstance() - ->get(OptionsDataProvider::class); + $this->optionsDataResolver = $optionsDataResolver ?: ObjectManager::getInstance() + ->get(OptionsDataResolver::class); } /** @@ -75,9 +75,9 @@ public function execute() $response = new DataObject(); $response->setError(false); try { - $optionsData = $this->optionsDataProvider->getOptionsData($this->getRequest()); + $optionsData = $this->optionsDataResolver->getOptionsData($this->getRequest()); } catch (\InvalidArgumentException $e) { - $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " + $message = __("The attribute couldn't be validated due to an error. Verify your information and try again. " . "If the error persists, please try again later."); $this->setMessageToResponse($response, [$message]); $response->setError(true); diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php similarity index 88% rename from app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php rename to app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php index a2a1fcb7fb526..20e713be9a440 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataProvider.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php @@ -8,9 +8,14 @@ use Magento\Framework\App\RequestInterface; -class OptionsDataProvider +/** + * Attribute options data resolver. + */ +class OptionsDataResolver { /** + * Provides attribute options data from the request. + * * @param RequestInterface $request * @return array * @throws \InvalidArgumentException @@ -36,4 +41,4 @@ public function getOptionsData(RequestInterface $request): array return $optionsData; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 233f554512f8c..bb06d05371e09 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -20,7 +20,6 @@ define([ return function (config) { var optionPanel = jQuery('#manage-options-panel'), - optionsValues = [], editForm = jQuery('#edit_form'), attributeOption = { table: $('attribute-options-table'), @@ -146,8 +145,7 @@ define([ return optionDefaultInputType; } }, - optionsTableContent = jQuery(), - optionContainer = optionPanel.find('table tbody'); + tableBody = jQuery(); if ($('add_new_option_button')) { Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true)); @@ -183,6 +181,9 @@ define([ }); } editForm.on('beforeSubmit', function () { + var optionsValues = [], + optionContainer = optionPanel.find('table tbody'); + if (optionPanel.is(':visible')) { optionContainer.find('input') .each(function () { @@ -206,13 +207,12 @@ define([ .val(JSON.stringify(optionsValues)) .prependTo(editForm); } - optionsTableContent = optionContainer.clone(true); - optionContainer - .replaceWith(jQuery('<div>').text(jQuery.mage.__('Sending attribute values as package.'))); + tableBody = optionContainer.detach(); }); editForm.on('afterValidate.error', function () { if (optionPanel.is(':visible')) { - optionContainer.replaceWith(optionsTableContent); + optionPanel.find('table').append(tableBody); + jQuery('input[name="serialized_options"]').remove(); } }); window.attributeOption = attributeOption; diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index dd1fb4b0a8b54..49723f4190a92 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -417,8 +417,7 @@ define([ var editForm = $('#edit_form'), swatchVisualPanel = $('#swatch-visual-options-panel'), swatchTextPanel = $('#swatch-text-options-panel'), - optionsTableContent = $(), - optionContainer = $(), + tableBody = $(), activePanel = $(); $('#frontend_input').bind('change', function () { @@ -436,7 +435,8 @@ define([ .collapse('hide'); editForm.on('beforeSubmit', function () { - var swatchValues = []; + var swatchValues = [], + optionContainer; activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); @@ -457,16 +457,13 @@ define([ .prependTo(editForm); } - optionsTableContent = optionContainer.clone(true); - [swatchVisualPanel, swatchTextPanel].forEach(function (el) { - $(el).find('table') - .replaceWith($('<div>').text($.mage.__('Sending swatch values as package.'))); - }); + tableBody = optionContainer.detach(); }); editForm.on('afterValidate.error', function () { if (activePanel.is(':visible')) { - optionContainer.replaceWith(optionsTableContent); + activePanel.find('table').append(tableBody); + $('input[name="serialized_options"]').remove(); } }); }); From 13fa0d74eb5f5fa980d56cead6729c16177e02bc Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 11 Sep 2018 11:10:13 +0300 Subject: [PATCH 0067/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Add plugin to set toolbar parameters to context before controller dispatch --- .../Block/Product/ProductList/Toolbar.php | 8 +- .../Model/App/Action/ContextPlugin.php | 77 +++++++++++++++++++ app/code/Magento/Catalog/etc/frontend/di.xml | 4 + 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index e3ed8ef94b74b..073e3f8f6173e 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -274,7 +274,7 @@ public function getCurrentOrder() $order = $defaultOrder; } - if ($order != $defaultOrder && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } @@ -300,7 +300,7 @@ public function getCurrentDirection() $dir = $this->_direction; } - if ($dir != $this->_direction && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } @@ -442,7 +442,7 @@ public function getCurrentMode() $mode = $defaultMode; } - if ($mode != $defaultMode && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); } @@ -602,7 +602,7 @@ public function getLimit() $limit = $defaultLimit; } - if ($limit != $defaultLimit && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } diff --git a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php b/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php new file mode 100644 index 0000000000000..c5ed81540e29e --- /dev/null +++ b/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Catalog\Model\App\Action; + +use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; +use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\App\Http\Context as HttpContext; + +/** + * Before dispatch plugin for all frontend controllers to update http context. + */ +class ContextPlugin +{ + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + + /** + * @var CatalogSession + */ + private $catalogSession; + + /** + * @var HttpContext + */ + private $httpContext; + + /** + * @param ToolbarMemorizer $toolbarMemorizer + * @param CatalogSession $catalogSession + * @param HttpContext $httpContext + */ + public function __construct( + ToolbarMemorizer $toolbarMemorizer, + CatalogSession $catalogSession, + HttpContext $httpContext + ) { + $this->toolbarMemorizer = $toolbarMemorizer; + $this->catalogSession = $catalogSession; + $this->httpContext = $httpContext; + } + + /** + * Update http context with catalog sensitive information. + * + * @return void + */ + public function beforeDispatch() + { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { + $order = $this->catalogSession->getData(ToolbarModel::ORDER_PARAM_NAME); + if ($order) { + $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, false); + } + $direction = $this->catalogSession->getData(ToolbarModel::DIRECTION_PARAM_NAME); + if ($direction) { + $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $direction, false); + } + $mode = $this->catalogSession->getData(ToolbarModel::MODE_PARAM_NAME); + if ($mode) { + $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, false); + } + $limit = $this->catalogSession->getData(ToolbarModel::LIMIT_PARAM_NAME); + if ($limit) { + $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, false); + } + } + } +} diff --git a/app/code/Magento/Catalog/etc/frontend/di.xml b/app/code/Magento/Catalog/etc/frontend/di.xml index 55098037191e8..a1520b66e83dc 100644 --- a/app/code/Magento/Catalog/etc/frontend/di.xml +++ b/app/code/Magento/Catalog/etc/frontend/di.xml @@ -116,4 +116,8 @@ <plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/> <plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/> </type> + <type name="Magento\Framework\App\Action\AbstractAction"> + <plugin name="catalog_app_action_dispatch_controller_context_plugin" + type="Magento\Catalog\Model\App\Action\ContextPlugin" /> + </type> </config> From 5746734cc6345d6b265b3efc8d9c839778eb48e9 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 11 Sep 2018 13:53:04 +0300 Subject: [PATCH 0068/1415] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Fixed issue with incorrect totals sorting on cart page; --- .../view/frontend/layout/checkout_cart_index.xml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml index a5d0be503baad..9e86671500c50 100644 --- a/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml +++ b/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml @@ -13,14 +13,10 @@ <item name="components" xsi:type="array"> <item name="block-totals" xsi:type="array"> <item name="children" xsi:type="array"> - <item name="before_grandtotal" xsi:type="array"> - <item name="children" xsi:type="array"> - <item name="discount" xsi:type="array"> - <item name="component" xsi:type="string">Magento_SalesRule/js/view/cart/totals/discount</item> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string" translate="true">Discount</item> - </item> - </item> + <item name="discount" xsi:type="array"> + <item name="component" xsi:type="string">Magento_SalesRule/js/view/cart/totals/discount</item> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string" translate="true">Discount</item> </item> </item> </item> From e02ecd14e3874b033d83f560a582e46f85b7c458 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 11 Sep 2018 16:22:44 +0300 Subject: [PATCH 0069/1415] MAGETWO-91723: Text Attribute doesn't display all character on product page - Fixed an issue with small box for text svatch attrbute value; --- .../Magento/blank/Magento_Swatches/web/css/source/_module.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less index b5d604597148a..6dc25501c92db 100644 --- a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less @@ -124,7 +124,7 @@ float: left; height: 20px; margin: 0 @indent__s @indent__xs 0; - max-width: 90px; + max-width: 100%; min-width: 30px; overflow: hidden; padding: 1px 2px; From 897c616e51405900ed0dcce2b21d68d547c085c1 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 11 Sep 2018 16:10:50 -0500 Subject: [PATCH 0070/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Attribute/Option/OptionsDataResolver.php | 4 +- .../AdminProductAttributeActionGroup.xml | 5 +- .../AdminCreateProductAttributeSection.xml | 9 +++ .../Test/Mftf/Data/SwatchAttributeData.xml | 1 + ...ateVisualSwatchWithNonValidOptionsTest.xml | 74 +++++++++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php index 20e713be9a440..60b183db9410a 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Product\Attribute\Option; use Magento\Framework\App\RequestInterface; @@ -26,7 +28,7 @@ public function getOptionsData(RequestInterface $request): array $optionsData = []; if ($serializedOptions) { - $encodedOptions = json_decode($serializedOptions, JSON_OBJECT_AS_ARRAY); + $encodedOptions = json_decode($serializedOptions, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new \InvalidArgumentException('Unable to unserialize options data.'); diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index fd80838692065..23687484f1012 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -14,7 +14,10 @@ </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <click selector="{{AdminProductAttributeGridSection.AttributeCode(ProductAttribute.attribute_code)}}" stepKey="navigateToAttributeEditPage1" /> + <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" + userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/> + <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> + <click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/> <waitForPageLoad stepKey="waitForPageLoad2" /> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index b83676c2e1033..a497233afbd4e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -17,6 +17,7 @@ <element name="DefaultValue" type="input" selector="#default_value_text"/> <element name="Scope" type="select" selector="#is_global"/> <element name="Save" type="button" selector="#save" timeout="30"/> + <element name="DeleteAttribute" type="button" selector="#delete" timeout="30"/> <element name="SaveAndEdit" type="button" selector="#save_and_edit_button" timeout="30"/> <element name="TinyMCE4" type="button" selector="//span[text()='Default Value']/parent::label/following-sibling::div//div[@class='mce-branding-powered-by']"/> <element name="checkIfTabOpen" selector="//div[@id='advanced_fieldset-wrapper' and not(contains(@class,'opened'))]" type="button"/> @@ -63,4 +64,12 @@ <element name="SpecialCharacter" type="button" selector=".mce-i-charmap" /> <element name="TextArea" type="input" selector="#default_value_textarea" /> </section> + <section name="AdvancedAttributePropertiesSection"> + <element name="AdvancedAttributePropertiesSectionToggle" + type="button" selector="#advanced_fieldset-wrapper"/> + <element name="AttributeCode" type="text" selector="#attribute_code"/> + <element name="Scope" type="select" selector="#is_global"/> + <element name="AddToColumnOptions" type="select" selector="#is_used_in_grid"/> + <element name="UseInFilterOptions" type="select" selector="#is_filterable_in_grid"/> + </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml index 08e24cfeb38fe..d7ee6dabce7ed 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Data/SwatchAttributeData.xml @@ -11,5 +11,6 @@ <entity name="visualSwatchAttribute" type="SwatchAttribute"> <data key="default_label" unique="suffix">VisualSwatchAttr</data> <data key="input_type">Visual Swatch</data> + <data key="attribute_code" unique="suffix">visual_swatch_attr</data> </entity> </entities> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml new file mode 100644 index 0000000000000..00de4cdf937b5 --- /dev/null +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateVisualSwatchWithNonValidOptionsTest"> + <annotations> + <features value="Swatches"/> + <stories value="Create/configure swatches product attribute"/> + <title value="Admin should be able to create swatch product attribute"/> + <description value="Admin should be able to create swatch product attribute"/> + <severity value="BLOCKER"/> + <testCaseId value="MC-4140"/> + <group value="Swatches"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + </before> + <after> + <!-- Remove attribute --> + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="visualSwatchAttribute"/> + </actionGroup> + <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> + + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <amOnPage url="{{ProductAttributePage.url}}" stepKey="navigateToNewProductAttributePage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + + <!-- Set attribute properties --> + <fillField selector="{{AttributePropertiesSection.DefaultLabel}}" + userInput="{{visualSwatchAttribute.default_label}}" stepKey="fillDefaultLabel"/> + <selectOption selector="{{AttributePropertiesSection.InputType}}" + userInput="{{visualSwatchAttribute.input_type}}" stepKey="fillInputType"/> + + <!-- Set advanced attribute properties --> + <click selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" + stepKey="showAdvancedAttributePropertiesSection"/> + <waitForElementVisible selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + stepKey="waitForSlideOut"/> + <fillField selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + userInput="{{visualSwatchAttribute.attribute_code}}" + stepKey="fillAttributeCode"/> + + <!-- Add an empty swatch option --> + <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch1"/> + + <!-- Save the new product attribute --> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave1"/> + <waitForElementVisible selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="waitForError"/> + + <!-- Fill options data --> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> + <argument name="index" value="0"/> + </actionGroup> + <click selector="{{AdminManageSwatchSection.nthChooseColor('1')}}" stepKey="clickChooseColor1"/> + <actionGroup ref="setColorPickerByHex" stepKey="fillHex1"> + <argument name="nthColorPicker" value="1"/> + <argument name="hexColor" value="ff0000"/> + </actionGroup> + <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('0')}}" + userInput="red" stepKey="fillAdmin1"/> + + <!-- Save the new product attribute --> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave2"/> + <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" + stepKey="waitForSuccessMessage"/> + </test> +</tests> \ No newline at end of file From 758d65da91f7182ca7cea5bc05f424c34cba8227 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 11 Sep 2018 17:28:12 -0500 Subject: [PATCH 0071/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Controller/Adminhtml/Product/Attribute/Validate.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index fa8103f703367..9fcfe39f6dd9e 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -11,6 +11,9 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute { const DEFAULT_MESSAGE_KEY = 'message'; From dc878446ec83d88080c81ad71ef6fc986806f173 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 11 Sep 2018 19:41:28 +0400 Subject: [PATCH 0072/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Add change related to xsd --- .../GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml index 9856f009197c1..63243030682bf 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="GiftOptionsOnFrontSection"> <element name="giftOptionCheckbox" type="text" selector="//span[text()='Add Gift Options']"/> <element name="addGiftOptionsForIndividualItems" type="text" selector="//dt[@class='order-title individual']"/> From ca7932ba5e813967018a5052a763bbe65c9abd66 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <karen_mkhitaryan@epam.com> Date: Fri, 7 Sep 2018 12:10:46 +0300 Subject: [PATCH 0073/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Remove test from CE --- .../Mftf/Section/AdminShipmentAddressInformationSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml index 3268a6f288371..10878310c262f 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="AdminShipmentAddressInformationSection"> <element name="billingAddress" type="text" selector=".order-billing-address address"/> <element name="billingAddressEdit" type="button" selector=".order-billing-address .actions a"/> From ee4e0a11e8a398755d5586082f38c86a5d126462 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 12 Sep 2018 15:31:24 +0300 Subject: [PATCH 0074/1415] MAGETWO-92179: Fixed incorrect behavior of attribute sets --- .../catalog/product/attribute/set/main.phtml | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml index 54b945b48c104..670a943da0aad 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml @@ -188,6 +188,15 @@ for( j in config[i].children ) { if(config[i].children[j].id) { newNode = new Ext.tree.TreeNode(config[i].children[j]); + + if (typeof newNode.ui.onTextChange === 'function') { + newNode.ui.onTextChange = function (_3, _4, _5) { + if (this.rendered) { + this.textNode.innerText = _4; + } + } + } + } node.appendChild(newNode); newNode.addListener('click', editSet.unregister); } @@ -195,13 +204,20 @@ } } } - } - editSet = function() { - return { - register : function(node) { - editSet.currentNode = node; - }, + + editSet = function () { + return { + register: function (node) { + editSet.currentNode = node; + if (typeof node.ui.onTextChange === 'function') { + node.ui.onTextChange = function (_3, _4, _5) { + if (this.rendered) { + this.textNode.innerText = _4; + } + } + } + }, unregister : function() { editSet.currentNode = false; @@ -293,6 +309,14 @@ allowDrag : true }); + if (typeof newNode.ui.onTextChange === 'function') { + newNode.ui.onTextChange = function (_3, _4, _5) { + if (this.rendered) { + this.textNode.innerText = _4; + } + } + } + TreePanels.root.appendChild(newNode); newNode.addListener('beforemove', editSet.groupBeforeMove); newNode.addListener('beforeinsert', editSet.groupBeforeInsert); From 6d068c79b5bb8fcad3a4b18df2a394fb7beb84f6 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 11 Sep 2018 18:11:30 +0300 Subject: [PATCH 0075/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Post toolbar parameters when using toolbar saving. --- .../Block/Product/ProductList/Toolbar.php | 29 +++++++++---- .../frontend/web/js/product/list/toolbar.js | 41 ++++++++++++++++--- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 073e3f8f6173e..9f1514aab9d6f 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -8,6 +8,7 @@ use Magento\Catalog\Helper\Product\ProductList; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; +use Magento\Framework\App\ObjectManager; /** * Product list toolbar @@ -132,6 +133,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ private $httpContext; + /** + * @var \Magento\Framework\Data\Form\FormKey + */ + private $formKey; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Catalog\Model\Session $catalogSession @@ -142,6 +148,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper * @param ToolbarMemorizer|null $toolbarMemorizer * @param \Magento\Framework\App\Http\Context|null $httpContext + * @param \Magento\Framework\Data\Form\FormKey|null $formKey * @param array $data */ public function __construct( @@ -154,6 +161,7 @@ public function __construct( \Magento\Framework\Data\Helper\PostHelper $postDataHelper, ToolbarMemorizer $toolbarMemorizer = null, \Magento\Framework\App\Http\Context $httpContext = null, + \Magento\Framework\Data\Form\FormKey $formKey = null, array $data = [] ) { $this->_catalogSession = $catalogSession; @@ -162,12 +170,15 @@ public function __construct( $this->urlEncoder = $urlEncoder; $this->_productListHelper = $productListHelper; $this->_postDataHelper = $postDataHelper; - $this->toolbarMemorizer = $toolbarMemorizer ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + $this->toolbarMemorizer = $toolbarMemorizer ?: ObjectManager::getInstance()->get( ToolbarMemorizer::class ); - $this->httpContext = $httpContext ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + $this->httpContext = $httpContext ?: ObjectManager::getInstance()->get( \Magento\Framework\App\Http\Context::class ); + $this->formKey = $formKey ?: ObjectManager::getInstance()->get( + \Magento\Framework\Data\Form\FormKey::class + ); parent::__construct($context, $data); } @@ -711,19 +722,19 @@ public function getPagerHtml() public function getWidgetOptionsJson(array $customOptions = []) { $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); - $defaultDirection = $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION; - $isMemorizingAllowed = $this->toolbarMemorizer->isMemorizingAllowed(); $options = [ 'mode' => ToolbarModel::MODE_PARAM_NAME, 'direction' => ToolbarModel::DIRECTION_PARAM_NAME, 'order' => ToolbarModel::ORDER_PARAM_NAME, 'limit' => ToolbarModel::LIMIT_PARAM_NAME, - 'modeDefault' => $isMemorizingAllowed ? false : $defaultMode, - 'directionDefault' => $isMemorizingAllowed ? false : $defaultDirection, - 'orderDefault' => $isMemorizingAllowed ? false : $this->getOrderField(), - 'limitDefault' => $isMemorizingAllowed ? false : - $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), + 'modeDefault' => $defaultMode, + 'directionDefault' => $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION, + 'orderDefault' => $this->getOrderField(), + 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), + 'formKey' => $this->formKey->getFormKey(), + 'pageParam' => ToolbarModel::PAGE_PARM_NAME, + 'post' => $this->toolbarMemorizer->isMemorizingAllowed() ? true : false ]; $options = array_replace_recursive($options, $customOptions); return json_encode(['productListToolbarForm' => $options]); diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 88be03a04e71a..aee8933194ab1 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -27,7 +27,10 @@ define([ directionDefault: 'asc', orderDefault: 'position', limitDefault: '9', - url: '' + url: '', + formKey: '', + pageParam: 'p', + post: false }, /** @inheritdoc */ @@ -99,12 +102,38 @@ define([ } paramData[paramName] = paramValue; - if (paramValue == defaultValue) { //eslint-disable-line eqeqeq - delete paramData[paramName]; - } - paramData = $.param(paramData); + if (this.options.post) { + var form = document.createElement('form'); + + var params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; + for (var key in paramData) { + if (params.indexOf(key) !== -1) { + var input = document.createElement('input'); + input.name = key; + input.value = paramData[key]; + form.appendChild(input); + delete paramData[key]; + } + } + var formKey = document.createElement('input'); + formKey.name = 'form_key'; + formKey.value = this.options.formKey; + form.appendChild(formKey); + + paramData = $.param(paramData); + baseUrl = baseUrl + (paramData.length ? '?' + paramData : ''); - location.href = baseUrl + (paramData.length ? '?' + paramData : ''); + form.action = baseUrl; + form.method = 'POST'; + document.body.appendChild(form); + form.submit(); + } else { + if (paramValue == defaultValue) { //eslint-disable-line eqeqeq + delete paramData[paramName]; + } + paramData = $.param(paramData); + location.href = baseUrl + (paramData.length ? '?' + paramData : ''); + } } }); From b2b611107a9988f69ea95db1b09dbfbfa3770c12 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 12 Sep 2018 19:20:52 +0300 Subject: [PATCH 0076/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix tests. --- .../Block/Product/ProductList/Toolbar.php | 1 - .../Block/Product/ProductList/ToolbarTest.php | 25 ++++++++++++++----- .../frontend/web/js/product/list/toolbar.js | 1 - 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 9f1514aab9d6f..3e3f86cd7de01 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -733,7 +733,6 @@ public function getWidgetOptionsJson(array $customOptions = []) 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), 'formKey' => $this->formKey->getFormKey(), - 'pageParam' => ToolbarModel::PAGE_PARM_NAME, 'post' => $this->toolbarMemorizer->isMemorizingAllowed() ? true : false ]; $options = array_replace_recursive($options, $customOptions); diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php index ac963326dbfa1..8282ffa409f9c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php @@ -18,6 +18,11 @@ class ToolbarTest extends \PHPUnit\Framework\TestCase */ protected $model; + /** + * @var \Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer | \PHPUnit_Framework_MockObject_MockObject + */ + private $memorizer; + /** * @var \Magento\Framework\Url | \PHPUnit_Framework_MockObject_MockObject */ @@ -62,6 +67,13 @@ protected function setUp() 'getLimit', 'getCurrentPage' ]); + $this->memorizer = $this->createPartialMock(\Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, [ + 'getDirection', + 'getOrder', + 'getMode', + 'getLimit', + 'isMemorizingAllowed' + ]); $this->layout = $this->createPartialMock(\Magento\Framework\View\Layout::class, ['getChildName', 'getBlock']); $this->pagerBlock = $this->createPartialMock(\Magento\Theme\Block\Html\Pager::class, [ 'setUseContainer', @@ -116,6 +128,7 @@ protected function setUp() 'context' => $context, 'catalogConfig' => $this->catalogConfig, 'toolbarModel' => $this->model, + 'toolbarMemorizer' => $this->memorizer, 'urlEncoder' => $this->urlEncoder, 'productListHelper' => $this->productListHelper ] @@ -155,7 +168,7 @@ public function testGetPagerEncodedUrl() public function testGetCurrentOrder() { $order = 'price'; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getOrder') ->will($this->returnValue($order)); $this->catalogConfig->expects($this->once()) @@ -169,7 +182,7 @@ public function testGetCurrentDirection() { $direction = 'desc'; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getDirection') ->will($this->returnValue($direction)); @@ -183,7 +196,7 @@ public function testGetCurrentMode() $this->productListHelper->expects($this->once()) ->method('getAvailableViewMode') ->will($this->returnValue(['list' => 'List'])); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getMode') ->will($this->returnValue($mode)); @@ -232,11 +245,11 @@ public function testGetLimit() $mode = 'list'; $limit = 10; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getMode') ->will($this->returnValue($mode)); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getLimit') ->will($this->returnValue($limit)); $this->productListHelper->expects($this->once()) @@ -266,7 +279,7 @@ public function testGetPagerHtml() $this->productListHelper->expects($this->exactly(2)) ->method('getAvailableLimit') ->will($this->returnValue([10 => 10, 20 => 20])); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getLimit') ->will($this->returnValue($limit)); $this->pagerBlock->expects($this->once()) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index aee8933194ab1..7c47f5bd04d5a 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -29,7 +29,6 @@ define([ limitDefault: '9', url: '', formKey: '', - pageParam: 'p', post: false }, From 5a283e3ff98079a94249bd3430c945484d8859c1 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 12 Sep 2018 15:31:57 -0500 Subject: [PATCH 0077/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Product/Attribute/ValidateTest.php | 167 +++++++++++------- .../catalog/product/attribute/js.phtml | 5 +- .../Catalog/view/adminhtml/web/js/options.js | 7 +- ...ateVisualSwatchWithNonValidOptionsTest.xml | 14 +- .../adminhtml/web/js/product-attributes.js | 11 +- .../Adminhtml/Product/AttributeTest.php | 17 +- 6 files changed, 134 insertions(+), 87 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index 9c747393cc72a..60c79a044812a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Validate; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet; @@ -61,6 +62,11 @@ class ValidateTest extends AttributeTest */ protected $layoutMock; + /** + * @var OptionsDataResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $optionsDataResolverMock; + protected function setUp() { parent::setUp(); @@ -86,6 +92,8 @@ protected function setUp() ->getMock(); $this->layoutMock = $this->getMockBuilder(LayoutInterface::class) ->getMockForAbstractClass(); + $this->optionsDataResolverMock = $this->getMockBuilder(OptionsDataResolver::class) + ->getMock(); $this->contextMock->expects($this->any()) ->method('getObjectManager') @@ -100,13 +108,14 @@ protected function getModel() return $this->objectManager->getObject( Validate::class, [ - 'context' => $this->contextMock, - 'attributeLabelCache' => $this->attributeLabelCacheMock, - 'coreRegistry' => $this->coreRegistryMock, - 'resultPageFactory' => $this->resultPageFactoryMock, - 'resultJsonFactory' => $this->resultJsonFactoryMock, - 'layoutFactory' => $this->layoutFactoryMock, - 'multipleAttributeList' => ['select' => 'option'] + 'context' => $this->contextMock, + 'attributeLabelCache' => $this->attributeLabelCacheMock, + 'coreRegistry' => $this->coreRegistryMock, + 'resultPageFactory' => $this->resultPageFactoryMock, + 'resultJsonFactory' => $this->resultJsonFactoryMock, + 'layoutFactory' => $this->layoutFactoryMock, + 'multipleAttributeList' => ['select' => 'option'], + 'optionsDataResolver' => $this->optionsDataResolverMock, ] ); } @@ -160,17 +169,22 @@ public function testExecute() */ public function testUniqueValidation(array $options, $isError) { - $countFunctionCalls = ($isError) ? 6 : 5; + $countFunctionCalls = ($isError) ? 5 : 4; $this->requestMock->expects($this->exactly($countFunctionCalls)) ->method('getParam') ->willReturnMap([ ['frontend_label', null, null], ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], - ['option', null, $options], ['message_key', null, Validate::DEFAULT_MESSAGE_KEY] ]); + $this->optionsDataResolverMock + ->expects($this->once()) + ->method('getOptionsData') + ->with($this->requestMock) + ->willReturn($options); + $this->objectManagerMock->expects($this->once()) ->method('create') ->willReturn($this->attributeMock); @@ -203,67 +217,77 @@ public function provideUniqueData() return [ 'no values' => [ [ - 'delete' => [ - "option_0" => "", - "option_1" => "", - "option_2" => "", - ] + 'option' => [ + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "", + ], + ], ], false ], 'valid options' => [ [ - 'value' => [ - "option_0" => [1, 0], - "option_1" => [2, 0], - "option_2" => [3, 0], + 'option' => [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [2, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "", + ], ], - 'delete' => [ - "option_0" => "", - "option_1" => "", - "option_2" => "", - ] ], false ], 'duplicate options' => [ [ - 'value' => [ - "option_0" => [1, 0], - "option_1" => [1, 0], - "option_2" => [3, 0], + 'option' => [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [1, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "", + ], ], - 'delete' => [ - "option_0" => "", - "option_1" => "", - "option_2" => "", - ] ], true ], 'duplicate and deleted' => [ [ - 'value' => [ - "option_0" => [1, 0], - "option_1" => [1, 0], - "option_2" => [3, 0], + 'option' => [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [1, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "1", + "option_2" => "", + ], ], - 'delete' => [ - "option_0" => "", - "option_1" => "1", - "option_2" => "", - ] ], false ], 'empty and deleted' => [ [ - 'value' => [ - "option_0" => [1, 0], - "option_1" => [2, 0], - "option_2" => ["", ""], + 'option' => [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [2, 0], + "option_2" => ["", ""], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "1", + ], ], - 'delete' => [ - "option_0" => "", - "option_1" => "", - "option_2" => "1", - ] ], false ], ]; @@ -285,10 +309,15 @@ public function testEmptyOption(array $options, $result) ['frontend_input', 'select', 'multipleselect'], ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], - ['option', null, $options], ['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'], ]); + $this->optionsDataResolverMock + ->expects($this->once()) + ->method('getOptionsData') + ->with($this->requestMock) + ->willReturn($options); + $this->objectManagerMock->expects($this->once()) ->method('create') ->willReturn($this->attributeMock); @@ -320,8 +349,10 @@ public function provideEmptyOption() return [ 'empty admin scope options' => [ [ - 'value' => [ - "option_0" => [''], + 'option' => [ + 'value' => [ + "option_0" => [''], + ], ], ], (object) [ @@ -331,8 +362,10 @@ public function provideEmptyOption() ], 'not empty admin scope options' => [ [ - 'value' => [ - "option_0" => ['asdads'], + 'option' => [ + 'value' => [ + "option_0" => ['asdads'], + ], ], ], (object) [ @@ -341,11 +374,13 @@ public function provideEmptyOption() ], 'empty admin scope options and deleted' => [ [ - 'value' => [ - "option_0" => [''], - ], - 'delete' => [ - 'option_0' => '1', + 'option' => [ + 'value' => [ + "option_0" => [''], + ], + 'delete' => [ + 'option_0' => '1', + ], ], ], (object) [ @@ -354,11 +389,13 @@ public function provideEmptyOption() ], 'empty admin scope options and not deleted' => [ [ - 'value' => [ - "option_0" => [''], - ], - 'delete' => [ - 'option_0' => '0', + 'option' => [ + 'value' => [ + "option_0" => [''], + ], + 'delete' => [ + 'option_0' => '0', + ], ], ], (object) [ diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml index 8a5f1919f78be..eeacc90fba914 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml @@ -40,13 +40,16 @@ function getFrontTab() { function checkOptionsPanelVisibility(){ if($('manage-options-panel')){ - var panel = $('manage-options-panel').up('.fieldset'); + var panel = $('manage-options-panel').up('.fieldset'), + activePanelClass = 'selected-type-options'; if($('frontend_input') && ($('frontend_input').value=='select' || $('frontend_input').value=='multiselect')){ panel.show(); + panel.addClass(activePanelClass); } else { panel.hide(); + panel.removeClass(activePanelClass); } } } diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index bb06d05371e09..7c35993670444 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -145,7 +145,8 @@ define([ return optionDefaultInputType; } }, - tableBody = jQuery(); + tableBody = jQuery(), + activePanelClass = 'selected-type-options'; if ($('add_new_option_button')) { Event.observe('add_new_option_button', 'click', attributeOption.add.bind(attributeOption, {}, true)); @@ -184,7 +185,7 @@ define([ var optionsValues = [], optionContainer = optionPanel.find('table tbody'); - if (optionPanel.is(':visible')) { + if (optionPanel.hasClass(activePanelClass)) { optionContainer.find('input') .each(function () { if (this.disabled) { @@ -210,7 +211,7 @@ define([ tableBody = optionContainer.detach(); }); editForm.on('afterValidate.error', function () { - if (optionPanel.is(':visible')) { + if (optionPanel.hasClass(activePanelClass)) { optionPanel.find('table').append(tableBody); jQuery('input[name="serialized_options"]').remove(); } diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 00de4cdf937b5..92a33487615ea 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -47,14 +47,8 @@ userInput="{{visualSwatchAttribute.attribute_code}}" stepKey="fillAttributeCode"/> - <!-- Add an empty swatch option --> + <!-- Add new swatch option without label --> <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch1"/> - - <!-- Save the new product attribute --> - <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave1"/> - <waitForElementVisible selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="waitForError"/> - - <!-- Fill options data --> <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> <argument name="index" value="0"/> </actionGroup> @@ -63,6 +57,12 @@ <argument name="nthColorPicker" value="1"/> <argument name="hexColor" value="ff0000"/> </actionGroup> + + <!-- Save the new product attribute --> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave1"/> + <waitForElementVisible selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="waitForError"/> + + <!-- Fill options data --> <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('0')}}" userInput="red" stepKey="fillAdmin1"/> diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 49723f4190a92..9538e8729e48d 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -16,7 +16,8 @@ define([ 'use strict'; return function (optionConfig) { - var swatchProductAttributes = { + var activePanelClass = 'selected-type-options', + swatchProductAttributes = { frontendInput: $('#frontend_input'), isFilterable: $('#is_filterable'), isFilterableInSearch: $('#is_filterable_in_search'), @@ -338,6 +339,7 @@ define([ */ _showPanel: function (el) { el.closest('.fieldset').show(); + el.addClass(activePanelClass); this._render(el.attr('id')); }, @@ -347,6 +349,7 @@ define([ */ _hidePanel: function (el) { el.closest('.fieldset').hide(); + el.removeClass(activePanelClass); }, /** @@ -438,10 +441,10 @@ define([ var swatchValues = [], optionContainer; - activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; + activePanel = swatchTextPanel.hasClass(this.activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); - if (activePanel.is(':visible')) { + if (activePanel.hasClass(activePanelClass)) { optionContainer .find('input') .each(function () { @@ -461,7 +464,7 @@ define([ }); editForm.on('afterValidate.error', function () { - if (activePanel.is(':visible')) { + if (activePanel.hasClass(activePanelClass)) { activePanel.find('table').append(tableBody); $('input[name="serialized_options"]').remove(); } diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 969d9530ae542..1a0073b154ffa 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -48,12 +48,14 @@ private function getSwatchVisualDataSet(int $optionsCount) : array $optionsData []= "optionvisual[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; $optionsData []= "optionvisual[delete][option_{$i}]="; } - $optionsData []= "visual_swatch_validation="; - $optionsData []= "visual_swatch_validation_unique="; return [ 'attribute_data' => array_merge_recursive( [ - 'serialized_swatch_values' => json_encode($optionsData), + 'serialized_options' => json_encode($optionsData), + ], + [ + 'visual_swatch_validation' => '', + 'visual_swatch_validation_unique' => '', ], $this->getAttributePreset(), [ @@ -86,12 +88,14 @@ private function getSwatchTextDataSet(int $optionsCount) : array $optionsData []= "optiontext[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; $optionsData []= "optiontext[delete][option_{$i}]="; } - $optionsData []= "text_swatch_validation="; - $optionsData []= "text_swatch_validation_unique="; return [ 'attribute_data' => array_merge_recursive( [ - 'serialized_swatch_values' => json_encode($optionsData), + 'serialized_options' => json_encode($optionsData), + ], + [ + 'text_swatch_validation' => '', + 'text_swatch_validation_unique' => '', ], $this->getAttributePreset(), [ @@ -111,7 +115,6 @@ private function getSwatchTextDataSet(int $optionsCount) : array private function getAttributePreset() : array { return [ - 'serialized_options' => '[]', 'form_key' => 'XxtpPYjm2YPYUlAt', 'frontend_label' => [ 0 => 'asdasd', From 00cb15e4f59e6a71dd51b08b3553633eebfebeaf Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 14 Sep 2018 09:14:40 +0300 Subject: [PATCH 0078/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix bug when memorizing getting disabled after we have params in session already. --- .../Product/ProductList/ToolbarMemorizer.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php index 4e65a4f9853e7..9c1a781d594f7 100644 --- a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -58,6 +58,11 @@ class ToolbarMemorizer */ private $limit; + /** + * @var bool + */ + private $isMemorizingAllowed; + /** * @param Toolbar $toolbarModel * @param CatalogSession $catalogSession @@ -82,7 +87,7 @@ public function getOrder() { if ($this->order === null) { $this->order = $this->toolbarModel->getOrder() ?? - $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME) : null); } return $this->order; } @@ -96,7 +101,7 @@ public function getDirection() { if ($this->direction === null) { $this->direction = $this->toolbarModel->getDirection() ?? - $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME) : null); } return $this->direction; } @@ -110,7 +115,7 @@ public function getMode() { if ($this->mode === null) { $this->mode = $this->toolbarModel->getMode() ?? - $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME) : null); } return $this->mode; } @@ -124,7 +129,7 @@ public function getLimit() { if ($this->limit === null) { $this->limit = $this->toolbarModel->getLimit() ?? - $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME) : null); } return $this->limit; } @@ -151,7 +156,10 @@ public function memorizeParams() */ public function isMemorizingAllowed() { - return $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); + if ($this->isMemorizingAllowed === null) { + $this->isMemorizingAllowed = $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); + } + return $this->isMemorizingAllowed; } /** From 0400e32d120bc8dc5b94818f76209b789ac6623d Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 10:53:07 +0300 Subject: [PATCH 0079/1415] Added ProductImage reslover to images. --- .../Model/Resolver/Product/ProductImage.php | 97 +++++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 13 ++- 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php new file mode 100644 index 0000000000000..2e6133f1e32cd --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Returns product image. + */ +class ProductImage implements ResolverInterface +{ + /** + * @var CatalogImageHelperFactory + */ + private $catalogImageHelperFactory; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param ValueFactory $valueFactory + * @param CatalogImageHelperFactory $catalogImageHelperFactory, + * @param StoreManagerInterface $storeManager + */ + public function __construct( + ValueFactory $valueFactory, + CatalogImageHelperFactory $catalogImageHelperFactory, + StoreManagerInterface $storeManager + ) + { + $this->valueFactory = $valueFactory; + $this->catalogImageHelperFactory = $catalogImageHelperFactory; + $this->storeManager = $storeManager; + } + + /** + * Get product's image by type. + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): Value + { + if (!isset($value['model'])) { + $result = function () { + return null; + }; + return $this->valueFactory->create($result); + } + /** @var Product $product */ + $product = $value['model']; + $imageType = $field->getName(); + + $catalogImageHelper = $this->catalogImageHelperFactory->create(); + + $imageUrl = $catalogImageHelper->init( + $product, + 'product_' . $imageType, + ['type' => $imageType] + )->getUrl(); + + $imageData = [ + 'url' => $imageUrl, + 'path' => $product->getData($imageType) + ]; + + $result = function () use ($imageData) { + return $imageData; + }; + + return $this->valueFactory->create($result); + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 9235ec271a3c2..683dfb8de1f26 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -257,9 +257,9 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ meta_title: String @doc(description: "A string that is displayed in the title bar and tab of the browser and in search results lists") meta_keyword: String @doc(description: "A comma-separated list of keywords that are visible only to search engines") meta_description: String @doc(description: "A brief overview of the product for search results listings, maximum 255 characters") - image: String @doc(description: "The relative path to the main image on the product page") - small_image: String @doc(description: "The relative path to the small image, which is used on catalog pages") - thumbnail: String @doc(description: "The relative path to the product's thumbnail image") + image: ProductImage @doc(description: "The relative path to the main image on the product page") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") + small_image: ProductImage @doc(description: "The relative path to the small image, which is used on catalog pages") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") + thumbnail: ProductImage @doc(description: "The relative path to the product's thumbnail image") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") new_from_date: String @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") new_to_date: String @doc(description: "The end date for new product listings") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached") @@ -352,6 +352,11 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the image_size_y: Int @doc(description: "The maximum height of an image") } +type ProductImage @doc(description: "Product image information. Contains image relative path and URL") { + url: String + path: String +} + interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { title: String @doc(description: "The display name for this option") required: Boolean @doc(description: "Indicates whether the option is required") @@ -548,6 +553,6 @@ type SortField { } type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { - default: String @doc(description: "Default value of sort fields") + default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } From 277c81fe005884724cfe1298f4f7cdeda3d5901a Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 11:23:03 +0300 Subject: [PATCH 0080/1415] Updates --- .../Model/Resolver/Product/ProductImage.php | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 2e6133f1e32cd..811bf08fc1c18 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -10,14 +10,13 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Store\Model\StoreManagerInterface; /** - * Returns product image. + * Return product image paths by image type. */ class ProductImage implements ResolverInterface { @@ -26,28 +25,20 @@ class ProductImage implements ResolverInterface */ private $catalogImageHelperFactory; - /** - * @var ValueFactory - */ - private $valueFactory; - /** * @var StoreManagerInterface */ private $storeManager; /** - * @param ValueFactory $valueFactory * @param CatalogImageHelperFactory $catalogImageHelperFactory, * @param StoreManagerInterface $storeManager */ public function __construct( - ValueFactory $valueFactory, CatalogImageHelperFactory $catalogImageHelperFactory, StoreManagerInterface $storeManager ) { - $this->valueFactory = $valueFactory; $this->catalogImageHelperFactory = $catalogImageHelperFactory; $this->storeManager = $storeManager; } @@ -63,13 +54,9 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): Value - { + ) { if (!isset($value['model'])) { - $result = function () { - return null; - }; - return $this->valueFactory->create($result); + throw new GraphQlInputException(__('"model" value should be specified')); } /** @var Product $product */ $product = $value['model']; @@ -88,10 +75,6 @@ public function resolve( 'path' => $product->getData($imageType) ]; - $result = function () use ($imageData) { - return $imageData; - }; - - return $this->valueFactory->create($result); + return $imageData; } -} \ No newline at end of file +} From 4b05e07445639c73f72d62d734934500c9866c92 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Mon, 10 Sep 2018 17:36:02 +0300 Subject: [PATCH 0081/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Add automated test --- .../ActionGroup/AdminOrderActionGroup.xml | 12 ++- .../Section/AdminOrderFormItemsSection.xml | 4 + .../Section/AdminOrderFormPaymentSection.xml | 1 + ...vailabilityCreditMemoWithNoPaymentTest.xml | 94 +++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index c82623632d782..b904b025e4e4d 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -222,6 +222,16 @@ <waitForElementVisible selector="{{AdminOrderFormPaymentSection.flatRateOption}}" stepKey="waitForShippingOptions"/> <selectOption selector="{{AdminOrderFormPaymentSection.flatRateOption}}" userInput="flatrate_flatrate" stepKey="checkFlatRate"/> </actionGroup> + + <!--Select free shipping method--> + <actionGroup name="orderSelectFreeShipping"> + <click selector="{{AdminOrderFormPaymentSection.header}}" stepKey="unfocus"/> + <waitForPageLoad stepKey="waitForJavascriptToFinish"/> + <click selector="{{AdminOrderFormPaymentSection.getShippingMethods}}" stepKey="clickShippingMethods"/> + <waitForElementVisible selector="{{AdminOrderFormPaymentSection.freeShippingOption}}" stepKey="waitForShippingOptions"/> + <selectOption selector="{{AdminOrderFormPaymentSection.freeShippingOption}}" userInput="freeshipping_freeshipping" stepKey="checkFreeShipping"/> + </actionGroup> + <!--Check that customer information is correct in order--> <actionGroup name="verifyBasicOrderInformation"> <arguments> @@ -268,4 +278,4 @@ <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> </actionGroup> -</actionGroups> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsSection.xml index 7a920166a8caa..0d98c1ec1a712 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsSection.xml @@ -27,6 +27,10 @@ <element name="rowCheck" type="checkbox" selector="#sales_order_create_search_grid_table > tbody tr:nth-of-type({{row}}) td.col-select [type=checkbox]" parameterized="true"/> <element name="rowQty" type="input" selector="#sales_order_create_search_grid_table > tbody tr:nth-of-type({{row}}) td.col-qty [name='qty']" parameterized="true"/> <element name="addSelected" type="button" selector="#order-search .admin__page-section-title .actions button.action-add" timeout="30"/> + <element name="customPriceCheckbox" type="checkbox" selector="//*[@class='custom-price-block']/input"/> + <element name="customPriceField" type="input" selector="//*[@class='custom-price-block']/following-sibling::input"/> + <element name="updateItemsAndQuantities" type="button" selector="//span[contains(text(),'Update Items and Quantities')]"/> + <element name="creditMemo" type="input" selector="#order_creditmemo"/> <element name="configure" type="button" selector=".product-configure-block button.action-default.scalable" timeout="30"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index e4d329bc85057..4350ffeb03373 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -13,5 +13,6 @@ <element name="getShippingMethods" type="text" selector="#order-shipping_method a.action-default" timeout="30"/> <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> <element name="shippingError" type="text" selector="#order[has_shipping]-error"/> + <element name="freeShippingOption" type="radio" selector="#s_method_freeshipping_freeshipping" timeout="30"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml new file mode 100644 index 0000000000000..dd34777d3658c --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminAvailabilityCreditMemoWithNoPaymentTest"> + <annotations> + <features value="Sales"/> + <stories value="MAGETWO-91547: Unable to create Credit memo for order with no payment required"/> + <title value="Checking availability of 'Credit memo' button for order with no payment required"/> + <description value="*Credit Memo* button should be displayed"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94470"/> + <group value="sales"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Enable *Free Shipping* --> + <createData entity="FreeShippingMethodsSettingConfig" stepKey="freeShippingMethodsSettingConfig"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <!-- Disable *Free Shipping* --> + <createData entity="DefaultShippingMethodsConfig" stepKey="defaultShippingMethodsConfig"/> + <createData entity="DisableFreeShippingConfig" stepKey="disableFreeShippingConfig"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + + <!-- Flush Magento Cache --> + <magentoCLI stepKey="flushCache" command="cache:flush"/> + + <!--Proceed to Admin panel > SALES > Orders. Created order should be in Processing status--> + <amOnPage url="{{AdminOrderCreatePage.url}}" stepKey="navigateToSalesOrderPage"/> + <waitForPageLoad stepKey="waitForSalesOrderPageLoaded"/> + + <click selector="{{AdminOrderFormActionSection.CreateNewCustomer}}" stepKey="clickCreateCustomer"/> + <waitForElementVisible stepKey="waitForNewOrderPageOpened" selector="{{NewOrderSection.submitOrder}}"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Create New Order" stepKey="seeNewOrderPageTitle"/> + + <!--Check if order can be submitted without the required fields including email address--> + <scrollToTopOfPage stepKey="scrollToTopOfOrderFormPage" after="seeNewOrderPageTitle"/> + <actionGroup ref="addSimpleProductToOrder" stepKey="addFirstProductToOrder" after="scrollToTopOfOrderFormPage"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + + <!--Click *Custom Price* link, enter 0 and click *Update Items and Quantities* button--> + <click selector="{{AdminOrderFormItemsSection.customPriceCheckbox}}" stepKey="clickCustomPriceCheckbox"/> + <waitForElementVisible stepKey="waitForPriceFieldAppears" selector="{{AdminOrderFormItemsSection.customPriceField}}"/> + <fillField selector="{{AdminOrderFormItemsSection.customPriceField}}" userInput="0" stepKey="fillCustomPriceField"/> + <click selector="{{AdminOrderFormItemsSection.updateItemsAndQuantities}}" stepKey="clickUpdateItemsAndQuantitiesButton"/> + + <!--Fill customer group and customer email--> + <selectOption selector="{{AdminOrderFormAccountSection.group}}" userInput="{{GeneralCustomerGroup.code}}" stepKey="selectCustomerGroup" after="clickUpdateItemsAndQuantitiesButton"/> + <fillField selector="{{AdminOrderFormAccountSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail" after="selectCustomerGroup"/> + + <!--Fill customer address information--> + <actionGroup ref="fillOrderCustomerInformation" stepKey="fillCustomerAddress" after="fillCustomerEmail"> + <argument name="customer" value="Simple_US_Customer"/> + <argument name="address" value="US_Address_TX"/> + </actionGroup> + + <!-- Select Free shipping --> + <actionGroup ref="orderSelectFreeShipping" stepKey="selectFreeShippingOption" after="fillCustomerAddress"/> + + <!--Click *Submit Order* button--> + <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="selectFreeShippingOption"/> + + <!--Click *Invoice* button--> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> + <waitForPageLoad stepKey="waitForInvoicePageOpened"/> + + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <waitForPageLoad stepKey="waitForInvoiceSaved"/> + <see userInput="The invoice has been created." stepKey="seeCorrectMessage"/> + + <!--Verify that *Credit Memo* button is displayed--> + <seeElement selector="{{AdminOrderFormItemsSection.creditMemo}}" stepKey="seeCreditMemo"/> + <click selector="{{AdminOrderFormItemsSection.creditMemo}}" stepKey="clickCreditMemoItem"/> + <waitForPageLoad stepKey="waitForCreditMemoPageLoaded"/> + <see stepKey="seeNewMemoPage" userInput="New Memo"/> + <seeInCurrentUrl url="{{AdminCreditMemoNewPage.url}}" stepKey="seeUrlOnPage"/> + </test> +</tests> From 1acda9bc30580ad73f8ce239a34fb8eea7c25ae5 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Fri, 14 Sep 2018 13:45:51 +0300 Subject: [PATCH 0082/1415] magento/bulk-api-ce#14: The user passed for async api should reference WebAPI user - applied backward compatibility policy to modified constructors --- .../AsynchronousOperations/Model/BulkManagement.php | 8 +++++--- .../Magento/AsynchronousOperations/Model/MassSchedule.php | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php index 1d7d15f84163f..faf01921e5737 100644 --- a/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php +++ b/app/code/Magento/AsynchronousOperations/Model/BulkManagement.php @@ -5,6 +5,7 @@ */ namespace Magento\AsynchronousOperations\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterfaceFactory; @@ -71,6 +72,7 @@ class BulkManagement implements \Magento\Framework\Bulk\BulkManagementInterface * @param MetadataPool $metadataPool * @param ResourceConnection $resourceConnection * @param \Psr\Log\LoggerInterface $logger + * @param UserContextInterface $userContext */ public function __construct( EntityManager $entityManager, @@ -79,8 +81,8 @@ public function __construct( BulkPublisherInterface $publisher, MetadataPool $metadataPool, ResourceConnection $resourceConnection, - UserContextInterface $userContext, - \Psr\Log\LoggerInterface $logger + \Psr\Log\LoggerInterface $logger, + UserContextInterface $userContext = null ) { $this->entityManager = $entityManager; $this->bulkSummaryFactory= $bulkSummaryFactory; @@ -88,8 +90,8 @@ public function __construct( $this->metadataPool = $metadataPool; $this->resourceConnection = $resourceConnection; $this->publisher = $publisher; - $this->userContext = $userContext; $this->logger = $logger; + $this->userContext = $userContext ?: ObjectManager::getInstance()->get(UserContextInterface::class); } /** diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index 5f792d1729ca4..28a360adc5101 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -8,6 +8,7 @@ namespace Magento\AsynchronousOperations\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject\IdentityGeneratorInterface; use Magento\Framework\Exception\LocalizedException; use Magento\AsynchronousOperations\Api\Data\ItemStatusInterfaceFactory; @@ -69,6 +70,7 @@ class MassSchedule * @param BulkManagementInterface $bulkManagement * @param LoggerInterface $logger * @param OperationRepository $operationRepository + * @param UserContextInterface $userContext */ public function __construct( IdentityGeneratorInterface $identityService, @@ -77,7 +79,7 @@ public function __construct( BulkManagementInterface $bulkManagement, LoggerInterface $logger, OperationRepository $operationRepository, - UserContextInterface $userContext + UserContextInterface $userContext = null ) { $this->identityService = $identityService; $this->itemStatusInterfaceFactory = $itemStatusInterfaceFactory; @@ -85,7 +87,7 @@ public function __construct( $this->bulkManagement = $bulkManagement; $this->logger = $logger; $this->operationRepository = $operationRepository; - $this->userContext = $userContext; + $this->userContext = $userContext ?: ObjectManager::getInstance()->get(UserContextInterface::class); } /** From 819b1178eca59bb530b6cca9fd7a1a7cbde28f4f Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 14:44:34 +0300 Subject: [PATCH 0083/1415] Update code style. --- .../Model/Resolver/Product/ProductImage.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 811bf08fc1c18..3cf961c0f4225 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -31,14 +31,13 @@ class ProductImage implements ResolverInterface private $storeManager; /** - * @param CatalogImageHelperFactory $catalogImageHelperFactory, - * @param StoreManagerInterface $storeManager + * @param CatalogImageHelperFactory $catalogImageHelperFactory + * @param StoreManagerInterface $storeManager */ public function __construct( CatalogImageHelperFactory $catalogImageHelperFactory, StoreManagerInterface $storeManager - ) - { + ) { $this->catalogImageHelperFactory = $catalogImageHelperFactory; $this->storeManager = $storeManager; } @@ -46,7 +45,7 @@ public function __construct( /** * Get product's image by type. * - * {@inheritdoc} + * @inheritdoc */ public function resolve( Field $field, @@ -62,6 +61,7 @@ public function resolve( $product = $value['model']; $imageType = $field->getName(); + /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ $catalogImageHelper = $this->catalogImageHelperFactory->create(); $imageUrl = $catalogImageHelper->init( From 3dc490d11dd502ee21f71100fad73e43f3a5f4fe Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 14 Sep 2018 15:18:33 +0300 Subject: [PATCH 0084/1415] MAGETWO-91532: Copy tier price for copied products - Fix merge conflict --- .../Product/Attribute/Backend/TierPrice/UpdateHandler.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php index a112da79d16fa..b4d6dc2c19e51 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php @@ -92,7 +92,12 @@ public function execute($entity, $arguments = []) $productId = (int) $entity->getData($identifierField); // prepare original data to compare - $origPrices = $entity->getOrigData($attribute->getName()); + $origPrices = []; + $originalId = $entity->getOrigData($identifierField); + if (empty($originalId) || $entity->getData($identifierField) == $originalId) { + $origPrices = $entity->getOrigData($attribute->getName()); + } + $old = $this->prepareOriginalDataToCompare($origPrices, $isGlobal); // prepare data for save $new = $this->prepareNewDataForSave($priceRows, $isGlobal); From 5dbdd4830626d3d944ed1f23e1bfb6fe3a896aea Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 14 Sep 2018 16:45:37 +0300 Subject: [PATCH 0085/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- .../Magento/Sales/Controller/AbstractController/Reorder.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index dd4d73930cc8f..0ba092b57ca2a 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Controller\AbstractController; use Magento\Framework\App\Action; +use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Registry; abstract class Reorder extends Action\Action @@ -40,9 +41,14 @@ public function __construct( * Action for reorder * * @return \Magento\Framework\Controller\ResultInterface + * @throws NotFoundException */ public function execute() { + if (!$this->getRequest()->isPost()) { + throw new NotFoundException(__('Page not Found')); + } + $result = $this->orderLoader->load($this->_request); if ($result instanceof \Magento\Framework\Controller\ResultInterface) { return $result; From 3caa51f14d8f4f84735c87a9da4b7edc27e1c27a Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 14 Sep 2018 16:58:51 +0300 Subject: [PATCH 0086/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- .../Magento/Sales/Controller/AbstractController/Reorder.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index 0ba092b57ca2a..cbc0c2cd007a9 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -4,12 +4,18 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Sales\Controller\AbstractController; use Magento\Framework\App\Action; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Registry; +/** + * Class Reorder + * + * @package Magento\Sales\Controller\AbstractController + */ abstract class Reorder extends Action\Action { /** From aafc793f5d22ac7d087a1e04919f95f7378a2e46 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 13 Sep 2018 17:21:01 -0500 Subject: [PATCH 0087/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Adminhtml/Product/Attribute/Save.php | 17 ++++--- .../Adminhtml/Product/Attribute/Validate.php | 17 ++++--- .../Attribute/Option/OptionsDataResolver.php | 46 ----------------- .../Option/OptionsDataSerializer.php | 50 +++++++++++++++++++ .../adminhtml/web/js/product-attributes.js | 2 +- 5 files changed, 69 insertions(+), 63 deletions(-) delete mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php create mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index 825288b366410..0c6b2cb52e1a3 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -13,7 +13,7 @@ use Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Helper\Product; use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator; @@ -77,9 +77,9 @@ class Save extends Attribute private $presentation; /** - * @var OptionsDataResolver|null + * @var OptionsDataSerializer|null */ - private $optionsDataResolver; + private $optionsDataSerializer; /** * @param Context $context @@ -94,7 +94,7 @@ class Save extends Attribute * @param Product $productHelper * @param LayoutFactory $layoutFactory * @param Presentation|null $presentation - * @param OptionsDataResolver|null $optionsDataResolver + * @param OptionsDataSerializer|null $optionsDataSerializer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -110,7 +110,7 @@ public function __construct( Product $productHelper, LayoutFactory $layoutFactory, Presentation $presentation = null, - OptionsDataResolver $optionsDataResolver = null + OptionsDataSerializer $optionsDataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->buildFactory = $buildFactory; @@ -121,8 +121,8 @@ public function __construct( $this->groupCollectionFactory = $groupCollectionFactory; $this->layoutFactory = $layoutFactory; $this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class); - $this->optionsDataResolver = $optionsDataResolver - ?: ObjectManager::getInstance()->get(OptionsDataResolver::class); + $this->optionsDataSerializer = $optionsDataSerializer + ?: ObjectManager::getInstance()->get(OptionsDataSerializer::class); } /** @@ -134,7 +134,8 @@ public function __construct( public function execute() { try { - $optionData = $this->optionsDataResolver->getOptionsData($this->getRequest()); + $optionData = $this->optionsDataSerializer + ->unserialize($this->getRequest()->getParam('serialized_options')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " . "If the error persists, please try again later."); diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 9fcfe39f6dd9e..ca2ba9d231a33 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -7,7 +7,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; @@ -34,9 +34,9 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute private $multipleAttributeList; /** - * @var OptionsDataResolver|null + * @var OptionsDataSerializer|null */ - private $optionsDataResolver; + private $optionsDataSerializer; /** * Constructor @@ -48,7 +48,7 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param array $multipleAttributeList - * @param OptionsDataResolver|null $optionsDataResolver + * @param OptionsDataSerializer|null $optionsDataSerializer */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -58,14 +58,14 @@ public function __construct( \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, array $multipleAttributeList = [], - OptionsDataResolver $optionsDataResolver = null + OptionsDataSerializer $optionsDataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->multipleAttributeList = $multipleAttributeList; - $this->optionsDataResolver = $optionsDataResolver ?: ObjectManager::getInstance() - ->get(OptionsDataResolver::class); + $this->optionsDataSerializer = $optionsDataSerializer ?: ObjectManager::getInstance() + ->get(OptionsDataSerializer::class); } /** @@ -78,7 +78,8 @@ public function execute() $response = new DataObject(); $response->setError(false); try { - $optionsData = $this->optionsDataResolver->getOptionsData($this->getRequest()); + $optionsData = $this->optionsDataSerializer + ->unserialize($this->getRequest()->getParam('serialized_options')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be validated due to an error. Verify your information and try again. " . "If the error persists, please try again later."); diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php deleted file mode 100644 index 60b183db9410a..0000000000000 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataResolver.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\Catalog\Model\Product\Attribute\Option; - -use Magento\Framework\App\RequestInterface; - -/** - * Attribute options data resolver. - */ -class OptionsDataResolver -{ - /** - * Provides attribute options data from the request. - * - * @param RequestInterface $request - * @return array - * @throws \InvalidArgumentException - */ - public function getOptionsData(RequestInterface $request): array - { - $serializedOptions = $request->getParam('serialized_options'); - $optionsData = []; - - if ($serializedOptions) { - $encodedOptions = json_decode($serializedOptions, true); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new \InvalidArgumentException('Unable to unserialize options data.'); - } - - foreach ($encodedOptions as $encodedOption) { - $decodedOptionData = []; - parse_str($encodedOption, $decodedOptionData); - $optionsData = array_replace_recursive($optionsData, $decodedOptionData); - } - } - - return $optionsData; - } -} diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php new file mode 100644 index 0000000000000..8fe02a9123b18 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Catalog\Model\Product\Attribute\Option; + +use Magento\Framework\Serialize\SerializerInterface; + +/** + * Attribute options data serializer. + */ +class OptionsDataSerializer +{ + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @param SerializerInterface $serializer + */ + public function __construct(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } + + /** + * Provides attribute options data from the serialized data. + * + * @param string $serializedOptions + * @return array + */ + public function unserialize(string $serializedOptions): array + { + $optionsData = []; + $encodedOptions = $this->serializer->unserialize($serializedOptions); + + foreach ($encodedOptions as $encodedOption) { + $decodedOptionData = []; + parse_str($encodedOption, $decodedOptionData); + $optionsData = array_replace_recursive($optionsData, $decodedOptionData); + } + + return $optionsData; + } +} diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 9538e8729e48d..d0eacc94e2c32 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -441,7 +441,7 @@ define([ var swatchValues = [], optionContainer; - activePanel = swatchTextPanel.hasClass(this.activePanelClass) ? swatchTextPanel : swatchVisualPanel; + activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); if (activePanel.hasClass(activePanelClass)) { From efceb14099aee0a388c20c4a9696e6e6b67ee8ee Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 14 Sep 2018 09:37:21 -0500 Subject: [PATCH 0088/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Adminhtml/Product/Attribute/SaveTest.php | 130 ++++++++++++++++++ .../Product/Attribute/ValidateTest.php | 84 +++++++++-- .../Adminhtml/Product/AttributeTest.php | 19 ++- 3 files changed, 217 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php index f493cbc88f18e..b9b1aeb9157db 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php @@ -5,7 +5,9 @@ */ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute; +use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Save; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\Product\AttributeSet\Build; @@ -13,11 +15,14 @@ use Magento\Eav\Api\Data\AttributeSetInterface; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\ValidatorFactory; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory; +use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Filter\FilterManager; use Magento\Catalog\Helper\Product as ProductHelper; +use Magento\Framework\View\Element\Messages; use Magento\Framework\View\LayoutFactory; use Magento\Backend\Model\View\Result\Redirect as ResultRedirect; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator as InputTypeValidator; +use Magento\Framework\View\LayoutInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -79,6 +84,16 @@ class SaveTest extends AttributeTest */ protected $inputTypeValidatorMock; + /** + * @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject + */ + private $optionsDataSerializerMock; + + /** + * @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productAttributeMock; + protected function setUp() { parent::setUp(); @@ -108,6 +123,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->redirectMock = $this->getMockBuilder(ResultRedirect::class) + ->setMethods(['setData', 'setPath']) ->disableOriginalConstructor() ->getMock(); $this->attributeSetMock = $this->getMockBuilder(AttributeSetInterface::class) @@ -119,6 +135,12 @@ protected function setUp() $this->inputTypeValidatorMock = $this->getMockBuilder(InputTypeValidator::class) ->disableOriginalConstructor() ->getMock(); + $this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class) + ->setMethods(['getId', 'get']) + ->getMockForAbstractClass(); $this->buildFactoryMock->expects($this->any()) ->method('create') @@ -126,6 +148,9 @@ protected function setUp() $this->validatorFactoryMock->expects($this->any()) ->method('create') ->willReturn($this->inputTypeValidatorMock); + $this->attributeFactoryMock + ->method('create') + ->willReturn($this->productAttributeMock); } /** @@ -145,11 +170,23 @@ protected function getModel() 'validatorFactory' => $this->validatorFactoryMock, 'groupCollectionFactory' => $this->groupCollectionFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, + 'optionsDataSerializer' => $this->optionsDataSerializerMock, ]); } public function testExecuteWithEmptyData() { + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap([ + ['isAjax', null, null], + ['serialized_options', null, ''], + ]); + $this->optionsDataSerializerMock + ->expects($this->once()) + ->method('unserialize') + ->with('') + ->willReturn([]); $this->requestMock->expects($this->once()) ->method('getPostValue') ->willReturn([]); @@ -170,6 +207,23 @@ public function testExecute() 'frontend_input' => 'test_frontend_input', ]; + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap([ + ['isAjax', null, null], + ['serialized_options', null, ''], + ]); + $this->optionsDataSerializerMock + ->expects($this->once()) + ->method('unserialize') + ->with('') + ->willReturn([]); + $this->productAttributeMock + ->method('getId') + ->willReturn(1); + $this->productAttributeMock + ->method('getAttributeCode') + ->willReturn('test_code'); $this->requestMock->expects($this->once()) ->method('getPostValue') ->willReturn($data); @@ -203,4 +257,80 @@ public function testExecute() $this->assertInstanceOf(ResultRedirect::class, $this->getModel()->execute()); } + + /** + * @throws \Magento\Framework\Exception\NotFoundException + */ + public function testExecuteWithOptionsDataError() + { + $serializedOptions = '{"key":"value"}'; + $message = "The attribute couldn't be saved due to an error. Verify your information and try again. " + . "If the error persists, please try again later."; + + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap([ + ['isAjax', null, true], + ['serialized_options', null, $serializedOptions], + ]); + $this->optionsDataSerializerMock + ->expects($this->once()) + ->method('unserialize') + ->with($serializedOptions) + ->willThrowException(new \InvalidArgumentException('Some exception')); + $this->messageManager + ->expects($this->once()) + ->method('addErrorMessage') + ->with($message); + $this->addReturnResultConditions('catalog/*/edit', ['_current' => true], ['error' => true]); + + $this->getModel()->execute(); + } + + /** + * @param string $path + * @param array $params + * @param array $response + * @return mixed + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + private function addReturnResultConditions(string $path = '', array $params = [], array $response = []) + { + $layoutMock = $this->getMockBuilder(LayoutInterface::class) + ->setMethods(['initMessages', 'getMessagesBlock']) + ->getMockForAbstractClass(); + $this->layoutFactoryMock + ->expects($this->once()) + ->method('create') + ->with() + ->willReturn($layoutMock); + $layoutMock + ->method('initMessages') + ->with(); + $messageBlockMock = $this->getMockBuilder(Messages::class) + ->disableOriginalConstructor() + ->getMock(); + $layoutMock + ->expects($this->once()) + ->method('getMessagesBlock') + ->willReturn($messageBlockMock); + $messageBlockMock + ->expects($this->once()) + ->method('getGroupedHtml') + ->willReturn('message1'); + $this->resultFactoryMock + ->expects($this->once()) + ->method('create') + ->with(ResultFactory::TYPE_JSON) + ->willReturn($this->redirectMock); + $response = array_merge($response, [ + 'messages' => ['message1'], + 'params' => $params, + ]); + $this->redirectMock + ->expects($this->once()) + ->method('setData') + ->with($response) + ->willReturnSelf(); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index 60c79a044812a..e9fc8bf3362b3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -6,7 +6,7 @@ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Validate; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataResolver; +use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet; @@ -63,9 +63,9 @@ class ValidateTest extends AttributeTest protected $layoutMock; /** - * @var OptionsDataResolver|\PHPUnit_Framework_MockObject_MockObject + * @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject */ - private $optionsDataResolverMock; + private $optionsDataSerializerMock; protected function setUp() { @@ -92,7 +92,8 @@ protected function setUp() ->getMock(); $this->layoutMock = $this->getMockBuilder(LayoutInterface::class) ->getMockForAbstractClass(); - $this->optionsDataResolverMock = $this->getMockBuilder(OptionsDataResolver::class) + $this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class) + ->disableOriginalConstructor() ->getMock(); $this->contextMock->expects($this->any()) @@ -115,19 +116,21 @@ protected function getModel() 'resultJsonFactory' => $this->resultJsonFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, 'multipleAttributeList' => ['select' => 'option'], - 'optionsDataResolver' => $this->optionsDataResolverMock, + 'optionsDataSerializer' => $this->optionsDataSerializerMock, ] ); } public function testExecute() { + $serializedOptions = '{"key":"value"}'; $this->requestMock->expects($this->any()) ->method('getParam') ->willReturnMap([ ['frontend_label', null, 'test_frontend_label'], ['attribute_code', null, 'test_attribute_code'], ['new_attribute_set_name', null, 'test_attribute_set_name'], + ['serialized_options', null, $serializedOptions], ]); $this->objectManagerMock->expects($this->exactly(2)) ->method('create') @@ -169,20 +172,22 @@ public function testExecute() */ public function testUniqueValidation(array $options, $isError) { - $countFunctionCalls = ($isError) ? 5 : 4; + $serializedOptions = '{"key":"value"}'; + $countFunctionCalls = ($isError) ? 6 : 5; $this->requestMock->expects($this->exactly($countFunctionCalls)) ->method('getParam') ->willReturnMap([ ['frontend_label', null, null], ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], - ['message_key', null, Validate::DEFAULT_MESSAGE_KEY] + ['message_key', null, Validate::DEFAULT_MESSAGE_KEY], + ['serialized_options', null, $serializedOptions], ]); - $this->optionsDataResolverMock + $this->optionsDataSerializerMock ->expects($this->once()) - ->method('getOptionsData') - ->with($this->requestMock) + ->method('unserialize') + ->with($serializedOptions) ->willReturn($options); $this->objectManagerMock->expects($this->once()) @@ -302,6 +307,7 @@ public function provideUniqueData() */ public function testEmptyOption(array $options, $result) { + $serializedOptions = '{"key":"value"}'; $this->requestMock->expects($this->any()) ->method('getParam') ->willReturnMap([ @@ -310,12 +316,13 @@ public function testEmptyOption(array $options, $result) ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], ['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'], + ['serialized_options', null, $serializedOptions], ]); - $this->optionsDataResolverMock + $this->optionsDataSerializerMock ->expects($this->once()) - ->method('getOptionsData') - ->with($this->requestMock) + ->method('unserialize') + ->with($serializedOptions) ->willReturn($options); $this->objectManagerMock->expects($this->once()) @@ -405,4 +412,55 @@ public function provideEmptyOption() ], ]; } + + /** + * @throws \Magento\Framework\Exception\NotFoundException + */ + public function testExecuteWithOptionsDataError() + { + $serializedOptions = '{"key":"value"}'; + $message = "The attribute couldn't be validated due to an error. Verify your information and try again. " + . "If the error persists, please try again later."; + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap([ + ['frontend_label', null, 'test_frontend_label'], + ['attribute_code', null, 'test_attribute_code'], + ['new_attribute_set_name', null, 'test_attribute_set_name'], + ['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'], + ['serialized_options', null, $serializedOptions], + ]); + + $this->optionsDataSerializerMock + ->expects($this->once()) + ->method('unserialize') + ->with($serializedOptions) + ->willThrowException(new \InvalidArgumentException('Some exception')); + + $this->objectManagerMock + ->method('create') + ->willReturnMap([ + [\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, [], $this->attributeMock], + [\Magento\Eav\Model\Entity\Attribute\Set::class, [], $this->attributeSetMock] + ]); + + $this->attributeMock + ->method('loadByCode') + ->willReturnSelf(); + $this->attributeSetMock + ->method('setEntityTypeId') + ->willReturnSelf(); + $this->resultJsonFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->resultJson); + $this->resultJson->expects($this->once()) + ->method('setJsonData') + ->with(json_encode([ + 'error' => true, + 'message' => $message + ])) + ->willReturnSelf(); + + $this->getModel()->execute(); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/AttributeTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/AttributeTest.php index b85b03852b621..2a75773754fca 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/AttributeTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/AttributeTest.php @@ -9,8 +9,10 @@ use Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Framework\App\RequestInterface; use Magento\Framework\Cache\FrontendInterface; +use Magento\Framework\Message\ManagerInterface; +use Magento\Framework\ObjectManager\ObjectManager; use Magento\Framework\Registry; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Framework\View\Result\PageFactory; use Magento\Framework\Controller\ResultFactory; @@ -20,7 +22,7 @@ class AttributeTest extends \PHPUnit\Framework\TestCase { /** - * @var ObjectManager + * @var ObjectManagerHelper */ protected $objectManager; @@ -54,9 +56,14 @@ class AttributeTest extends \PHPUnit\Framework\TestCase */ protected $resultFactoryMock; + /** + * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $messageManager; + protected function setUp() { - $this->objectManager = new ObjectManager($this); + $this->objectManager = new ObjectManagerHelper($this); $this->contextMock = $this->getMockBuilder(Context::class) ->disableOriginalConstructor() ->getMock(); @@ -74,6 +81,9 @@ protected function setUp() $this->resultFactoryMock = $this->getMockBuilder(ResultFactory::class) ->disableOriginalConstructor() ->getMock(); + $this->messageManager = $this->getMockBuilder(ManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); $this->contextMock->expects($this->any()) ->method('getRequest') @@ -81,6 +91,9 @@ protected function setUp() $this->contextMock->expects($this->any()) ->method('getResultFactory') ->willReturn($this->resultFactoryMock); + $this->contextMock + ->method('getMessageManager') + ->willReturn($this->messageManager); } /** From 727ca8cb1a9ebc9d750c3409a0c6acb44a835482 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 14 Sep 2018 11:07:11 -0500 Subject: [PATCH 0089/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Controller/Adminhtml/Product/Attribute/Save.php | 13 ++++++++++--- .../Adminhtml/Product/Attribute/Validate.php | 9 ++++++++- .../Adminhtml/Product/Attribute/Plugin/Save.php | 2 ++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index 0c6b2cb52e1a3..e32d84b393aeb 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -32,6 +32,8 @@ use Magento\Framework\View\Result\PageFactory; /** + * Product attribute save controller. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends Attribute @@ -126,10 +128,13 @@ public function __construct( } /** + * @inheritdoc + * * @return Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @throws \Zend_Validate_Exception */ public function execute() { @@ -158,7 +163,7 @@ public function execute() $name = trim($name); try { - /** @var $attributeSet Set */ + /** @var Set $attributeSet */ $attributeSet = $this->buildFactory->create() ->setEntityTypeId($this->_entityTypeId) ->setSkeletonId($setId) @@ -180,7 +185,7 @@ public function execute() $attributeId = $this->getRequest()->getParam('attribute_id'); - /** @var $model ProductAttributeInterface */ + /** @var ProductAttributeInterface $model */ $model = $this->attributeFactory->create(); if ($attributeId) { $model->load($attributeId); @@ -212,7 +217,7 @@ public function execute() //validate frontend_input if (isset($data['frontend_input'])) { - /** @var $inputType Validator */ + /** @var Validator $inputType */ $inputType = $this->validatorFactory->create(); if (!$inputType->isValid($data['frontend_input'])) { foreach ($inputType->getMessages() as $message) { @@ -340,6 +345,8 @@ public function execute() } /** + * Provides an initialized Result object. + * * @param string $path * @param array $params * @param array $response diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index ca2ba9d231a33..34dcf6639f943 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -12,6 +12,8 @@ use Magento\Framework\DataObject; /** + * Product attribute validate controller. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute @@ -69,6 +71,8 @@ public function __construct( } /** + * @inheritdoc + * * @return \Magento\Framework\Controller\ResultInterface * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) @@ -146,7 +150,8 @@ public function execute() } /** - * Throws Exception if not unique values into options + * Throws Exception if not unique values into options. + * * @param array $optionsValues * @param array $deletedOptions * @return bool @@ -180,6 +185,8 @@ private function setMessageToResponse($response, $messages) } /** + * Performs checking the uniqueness of the attribute options. + * * @param DataObject $response * @param array|null $options * @return $this diff --git a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php index 9ec65fb08045c..72d27152d639a 100644 --- a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php +++ b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php @@ -16,6 +16,8 @@ class Save { /** + * Performs the conversion of the frontend input value. + * * @param Attribute\Save $subject * @param RequestInterface $request * @return array From 6dfd297fb804990486fd0d5b699cd8f9ddd20e71 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 14 Sep 2018 11:42:44 -0500 Subject: [PATCH 0090/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Catalog/Controller/Adminhtml/Product/AttributeTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 4261873cc8e6e..ae8005db95a29 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -376,7 +376,8 @@ protected function _getAttributeData() 'used_in_product_listing' => '1', 'used_for_sort_by' => '0', 'apply_to' => ['simple'], - 'frontend_label' => [\Magento\Store\Model\Store::DEFAULT_STORE_ID => 'string to translate'] + 'frontend_label' => [\Magento\Store\Model\Store::DEFAULT_STORE_ID => 'string to translate'], + 'serialized_options' => '[]', ]; } } From 05665bbedcc25b9ac1d47083aee4ec647c2794fd Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 14 Sep 2018 14:27:33 -0500 Subject: [PATCH 0091/1415] MAGETWO-90540: MFTF Test failure - Advanced Reporting configuration permission --- .../Test/Mftf/Section/AdminConfigSection.xml | 2 +- .../Test/Mftf/Test/AdminConfigurationPermissionTest.xml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) rename app/code/Magento/{Config => Analytics}/Test/Mftf/Section/AdminConfigSection.xml (93%) diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml similarity index 93% rename from app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml rename to app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml index dbede5491e011..9ec2c62a3c27a 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminConfigSection"> - <element name="advancedReportingMenuItem" type="text" selector="//a[contains(concat(' ',normalize-space(@class),' '),'item-nav')]/span[text()='Advanced Reporting']"/> + <element name="advancedReportingMenuItem" type="text" selector="//*[@id='system_config_tabs']/div[1]//span[text()='Advanced Reporting']"/> <element name="advancedReportingService" type="select" selector="#analytics_general_enabled"/> <element name="advancedReportingServiceLabel" type="text" selector="#row_analytics_general_enabled>td.label>label>span"/> <element name="advancedReportingServiceStatus" type="text" selector="#row_analytics_general_enabled>td.value>p>span"/> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml index d8aed1250d82a..5414e9c2a5c18 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-82648"/> <group value="analytics"/> - <skip> - <issueId value="MAGETWO-90659"/> - </skip> </annotations> <before> <createData stepKey="noReportUserRole" entity="adminNoReportRole"/> From a3097e3394ed4015cbf47ac2abfb005d5702467d Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 14 Sep 2018 14:28:51 -0500 Subject: [PATCH 0092/1415] MAGETWO-90540: MFTF Test failure - Advanced Reporting configuration permission --- .../Test/Mftf/Section/AdminConfigSection.xml | 1 - .../Config/Test/Mftf/Section/AdminConfigSection.xml | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml diff --git a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml index 9ec2c62a3c27a..f8554a4ea115b 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml @@ -18,6 +18,5 @@ <element name="advancedReportingSeconds" type="select" selector="#row_analytics_general_collection_time>td:nth-child(2)>select:nth-child(4)"/> <element name="advancedReportingBlankIndustryError" type="text" selector=".message-error>div"/> <element name="advancedReportingSuccessMessage" type="text" selector=".message-success>div"/> - <element name="saveButton" type="button" selector="#save"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml new file mode 100644 index 0000000000000..f4698b6865779 --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminConfigSection"> + <element name="saveButton" type="button" selector="#save"/> + </section> +</sections> \ No newline at end of file From c0a2ad10307296693911312c29f397182ab7f762 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Sat, 15 Sep 2018 14:33:58 +0300 Subject: [PATCH 0093/1415] Fix bool scope config and update throws and update use clases --- .../Model/Recommendations/DataProvider.php | 4 +- .../CatalogInventory/Model/Configuration.php | 31 ++--- app/code/Magento/Checkout/Helper/Data.php | 12 +- app/code/Magento/Customer/Helper/Address.php | 106 ++++++++++-------- .../Customer/Model/AccountConfirmation.php | 2 +- .../Ui/Component/DataProvider/Document.php | 24 ++-- app/code/Magento/Directory/Helper/Data.php | 38 ++++--- app/code/Magento/Downloadable/Helper/Data.php | 16 +-- .../Model/DataProvider/Suggestions.php | 14 ++- .../Model/GiftMessageConfigProvider.php | 27 +++-- .../Magento/GoogleOptimizer/Helper/Data.php | 2 +- app/code/Magento/Msrp/Model/Config.php | 2 +- .../NewRelicReporting/Model/Config.php | 4 +- .../Magento/Reports/Model/ReportStatus.php | 4 +- .../Model/ResourceModel/Catalog/Product.php | 47 ++++---- .../Magento/Store/Model/BaseUrlChecker.php | 12 +- .../Store/Model/HeaderProvider/Hsts.php | 2 +- .../Model/HeaderProvider/UpgradeInsecure.php | 2 +- app/code/Magento/Store/Model/StoreManager.php | 4 +- .../Magento/Wishlist/Model/Rss/Wishlist.php | 16 +-- .../Magento/Framework/Session/SidResolver.php | 12 +- .../Magento/Framework/View/Asset/Config.php | 9 +- .../Framework/View/Asset/Minification.php | 2 +- 23 files changed, 218 insertions(+), 174 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php index 546983bb5e5a8..77df85e52003c 100644 --- a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php +++ b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php @@ -73,7 +73,7 @@ public function __construct( */ public function isResultsCountEnabled() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::CONFIG_RESULTS_COUNT_ENABLED, ScopeInterface::SCOPE_STORE ); @@ -130,7 +130,7 @@ private function getSearchRecommendations(\Magento\Search\Model\QueryInterface $ */ private function isSearchRecommendationsEnabled() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::CONFIG_IS_ENABLED, ScopeInterface::SCOPE_STORE ); diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php index 2f0415b40dc01..b0f8aebf1da26 100644 --- a/app/code/Magento/CatalogInventory/Model/Configuration.php +++ b/app/code/Magento/CatalogInventory/Model/Configuration.php @@ -9,6 +9,7 @@ use Magento\CatalogInventory\Helper\Minsaleqty as MinsaleqtyHelper; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Catalog\Model\ProductTypes\ConfigInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; /** @@ -201,7 +202,7 @@ public function canSubtractQty($store = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_CAN_SUBTRACT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -214,7 +215,7 @@ public function getMinQty($store = null) { return (float)$this->scopeConfig->getValue( self::XML_PATH_MIN_QTY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -237,7 +238,7 @@ public function getMaxSaleQty($store = null) { return (float)$this->scopeConfig->getValue( self::XML_PATH_MAX_SALE_QTY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -250,7 +251,7 @@ public function getNotifyStockQty($store = null) { return (float) $this->scopeConfig->getValue( self::XML_PATH_NOTIFY_STOCK_QTY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -264,9 +265,9 @@ public function getNotifyStockQty($store = null) */ public function getEnableQtyIncrements($store = null) { - return (bool) $this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_ENABLE_QTY_INCREMENTS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -279,7 +280,7 @@ public function getQtyIncrements($store = null) { return (float)$this->scopeConfig->getValue( self::XML_PATH_QTY_INCREMENTS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -294,7 +295,7 @@ public function getBackorders($store = null) { return (int) $this->scopeConfig->getValue( self::XML_PATH_BACKORDERS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -309,7 +310,7 @@ public function getManageStock($store = null) { return (int) $this->scopeConfig->isSetFlag( self::XML_PATH_MANAGE_STOCK, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -325,7 +326,7 @@ public function getCanBackInStock($store = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_CAN_BACK_IN_STOCK, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -340,7 +341,7 @@ public function isShowOutOfStock($store = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_SHOW_OUT_OF_STOCK, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -355,7 +356,7 @@ public function isAutoReturnEnabled($store = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_ITEM_AUTO_RETURN, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -371,7 +372,7 @@ public function isDisplayProductStockStatus($store = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_DISPLAY_PRODUCT_STOCK_STATUS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -385,7 +386,7 @@ public function getDefaultConfigValue($field, $store = null) { return $this->scopeConfig->getValue( self::XML_PATH_ITEM . $field, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -398,7 +399,7 @@ public function getStockThresholdQty($store = null) { return $this->scopeConfig->getValue( self::XML_PATH_STOCK_THRESHOLD_QTY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } diff --git a/app/code/Magento/Checkout/Helper/Data.php b/app/code/Magento/Checkout/Helper/Data.php index 0f2326d37c1ad..5a920ee2f5d8a 100644 --- a/app/code/Magento/Checkout/Helper/Data.php +++ b/app/code/Magento/Checkout/Helper/Data.php @@ -145,9 +145,9 @@ public function convertPrice($price, $format = true) */ public function canOnepageCheckout() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( 'checkout/options/onepage_checkout_enabled', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } @@ -217,7 +217,7 @@ public function sendPaymentFailedEmail( \Magento\Quote\Model\Quote $checkout, string $message, string $checkoutType = 'onepage' - ): \Magento\Checkout\Helper\Data { + ): Data { $this->paymentFailures->handle((int)$checkout->getId(), $message, $checkoutType); return $this; @@ -232,7 +232,7 @@ protected function _getEmails($configPath, $storeId) { $data = $this->scopeConfig->getValue( $configPath, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $storeId ); if (!empty($data)) { @@ -256,7 +256,7 @@ public function isAllowedGuestCheckout(\Magento\Quote\Model\Quote $quote, $store } $guestCheckout = $this->scopeConfig->isSetFlag( self::XML_PATH_GUEST_CHECKOUT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); @@ -295,7 +295,7 @@ public function isCustomerMustBeLogged() { return $this->scopeConfig->isSetFlag( self::XML_PATH_CUSTOMER_MUST_BE_LOGGED, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php index c74c62dc6d98c..8e867c891d932 100644 --- a/app/code/Magento/Customer/Helper/Address.php +++ b/app/code/Magento/Customer/Helper/Address.php @@ -10,6 +10,8 @@ use Magento\Customer\Api\Data\AttributeMetadataInterface; use Magento\Directory\Model\Country\Format; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Element\BlockInterface; +use Magento\Store\Model\ScopeInterface; /** * Customer address helper @@ -148,8 +150,8 @@ public function getCreateUrl() } /** - * @param string $renderer - * @return \Magento\Framework\View\Element\BlockInterface + * @param BlockInterface|string $renderer + * @return BlockInterface */ public function getRenderer($renderer) { @@ -160,13 +162,15 @@ public function getRenderer($renderer) } } - /** - * Return customer address config value by key and store - * - * @param string $key - * @param \Magento\Store\Model\Store|int|string $store - * @return string|null - */ + /** + * Return customer address config value by key and store + * + * @param string $key + * @param \Magento\Store\Model\Store|int|string $store + * + * @return string|null + * @throws NoSuchEntityException + */ public function getConfig($key, $store = null) { $store = $this->_storeManager->getStore($store); @@ -174,19 +178,22 @@ public function getConfig($key, $store = null) if (!isset($this->_config[$websiteId])) { $this->_config[$websiteId] = $this->scopeConfig->getValue( 'customer/address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } return isset($this->_config[$websiteId][$key]) ? (string)$this->_config[$websiteId][$key] : null; } - /** - * Return Number of Lines in a Street Address for store - * - * @param \Magento\Store\Model\Store|int|string $store - * @return int - */ + /** + * Return Number of Lines in a Street Address for store + * + * @param \Magento\Store\Model\Store|int|string $store + * + * @return int + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getStreetLines($store = null) { $websiteId = $this->_storeManager->getStore($store)->getWebsiteId(); @@ -228,25 +235,29 @@ public function getFormatTypeRenderer($code) return $formatType->getRenderer(); } - /** - * Determine if specified address config value can be shown - * - * @param string $key - * @return bool - */ + /** + * Determine if specified address config value can be shown + * + * @param string $key + * + * @return bool + * @throws NoSuchEntityException + */ public function canShowConfig($key) { return (bool)$this->getConfig($key); } - /** - * Get string with frontend validation classes for attribute - * - * @param string $attributeCode - * @return string - * - * @SuppressWarnings(PHPMD.NPathComplexity) - */ + /** + * Get string with frontend validation classes for attribute + * + * @param string $attributeCode + * + * @return string + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getAttributeValidationClass($attributeCode) { $class = ''; @@ -313,9 +324,9 @@ public function convertStreetLines($origStreets, $toCount) */ public function isVatValidationEnabled($store = null) { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_VAT_VALIDATION_ENABLED, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -327,9 +338,9 @@ public function isVatValidationEnabled($store = null) */ public function isDisableAutoGroupAssignDefaultValue() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_VIV_DISABLE_AUTO_ASSIGN_DEFAULT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } @@ -341,9 +352,9 @@ public function isDisableAutoGroupAssignDefaultValue() */ public function hasValidateOnEachTransaction($store = null) { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_VIV_ON_EACH_TRANSACTION, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -358,7 +369,7 @@ public function getTaxCalculationAddressType($store = null) { return (string)$this->scopeConfig->getValue( self::XML_PATH_VIV_TAX_CALCULATION_ADDRESS_TYPE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $store ); } @@ -370,19 +381,22 @@ public function getTaxCalculationAddressType($store = null) */ public function isVatAttributeVisible() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_VAT_FRONTEND_VISIBILITY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } - /** - * Retrieve attribute visibility - * - * @param string $code - * @return bool - * @since 100.2.0 - */ + /** + * Retrieve attribute visibility + * + * @param string $code + * + * @return bool + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + * @since 100.2.0 + */ public function isAttributeVisible($code) { $attributeMetadata = $this->_addressMetadataService->getAttributeMetadata($code); diff --git a/app/code/Magento/Customer/Model/AccountConfirmation.php b/app/code/Magento/Customer/Model/AccountConfirmation.php index 7d01ff0efc411..3c473dec78400 100644 --- a/app/code/Magento/Customer/Model/AccountConfirmation.php +++ b/app/code/Magento/Customer/Model/AccountConfirmation.php @@ -56,7 +56,7 @@ public function isConfirmationRequired($websiteId, $customerId, $customerEmail): return false; } - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_IS_CONFIRM, ScopeInterface::SCOPE_WEBSITES, $websiteId diff --git a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php index a9a5c5b17744e..89a3c2e855f6f 100644 --- a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php +++ b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php @@ -117,11 +117,12 @@ public function getCustomAttribute($attributeCode) return parent::getCustomAttribute($attributeCode); } - /** - * Update customer gender value - * Method set gender label instead of id value - * @return void - */ + /** + * Update customer gender value + * Method set gender label instead of id value + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ private function setGenderValue() { $value = $this->getData(self::$genderAttributeCode); @@ -140,11 +141,12 @@ private function setGenderValue() } } - /** - * Update customer group value - * Method set group code instead id value - * @return void - */ + /** + * Update customer group value + * Method set group code instead id value + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ private function setCustomerGroupValue() { $value = $this->getData(self::$groupAttributeCode); @@ -178,7 +180,7 @@ private function setConfirmationValue() { $value = $this->getData(self::$confirmationAttributeCode); $websiteId = $this->getData(self::$websiteIdAttributeCode) ?: $this->getData(self::$websiteAttributeCode); - $isConfirmationRequired = (bool)$this->scopeConfig->getValue( + $isConfirmationRequired = $this->scopeConfig->isSetFlag( AccountManagement::XML_PATH_IS_CONFIRM, ScopeInterface::SCOPE_WEBSITES, $websiteId diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php index 99e1d1ad5394e..3f1e272345ed8 100644 --- a/app/code/Magento/Directory/Helper/Data.php +++ b/app/code/Magento/Directory/Helper/Data.php @@ -6,6 +6,7 @@ namespace Magento\Directory\Helper; +use Magento\Directory\Model\Currency; use Magento\Store\Model\ScopeInterface; /** @@ -165,11 +166,12 @@ public function getCountryCollection($store = null) return $this->_countryCollection; } - /** - * Retrieve regions data json - * - * @return string - */ + /** + * Retrieve regions data json + * + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ public function getRegionJson() { \Magento\Framework\Profiler::start('TEST: ' . __METHOD__, ['group' => 'TEST', 'method' => __METHOD__]); @@ -191,15 +193,17 @@ public function getRegionJson() return $this->_regionJson; } - /** - * Convert currency - * - * @param float $amount - * @param string $from - * @param string $to - * @return float - * @SuppressWarnings(PHPMD.ShortVariable) - */ + /** + * Convert currency + * + * @param float $amount + * @param string $from + * @param string $to + * + * @return float + * @SuppressWarnings(PHPMD.ShortVariable) + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ public function currencyConvert($amount, $from, $to = null) { if (empty($this->_currencyCache[$from])) { @@ -251,7 +255,7 @@ public function isZipCodeOptional($countryCode) * Returns the list of countries, for which region is required * * @param boolean $asJson - * @return array + * @return array|string */ public function getCountriesWithStatesRequired($asJson = false) { @@ -275,7 +279,7 @@ public function getCountriesWithStatesRequired($asJson = false) */ public function isShowNonRequiredState() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_DISPLAY_ALL_STATES, ScopeInterface::SCOPE_STORE ); @@ -303,7 +307,7 @@ public function isRegionRequired($countryId) */ public function getBaseCurrencyCode() { - return $this->scopeConfig->getValue(\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE, 'default'); + return $this->scopeConfig->getValue( Currency::XML_PATH_CURRENCY_BASE, 'default'); } /** diff --git a/app/code/Magento/Downloadable/Helper/Data.php b/app/code/Magento/Downloadable/Helper/Data.php index 96aa5bdfeffd7..e9b2a5ce44c01 100644 --- a/app/code/Magento/Downloadable/Helper/Data.php +++ b/app/code/Magento/Downloadable/Helper/Data.php @@ -5,7 +5,9 @@ */ namespace Magento\Downloadable\Helper; +use Magento\Downloadable\Model\Link; use Magento\Downloadable\Model\Link\Purchased\Item; +use Magento\Store\Model\ScopeInterface; /** * Downloadable helper @@ -17,7 +19,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * Check is link shareable or not * - * @param \Magento\Downloadable\Model\Link|Item $link + * @param Link|Item $link * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ @@ -25,14 +27,14 @@ public function getIsShareable($link) { $shareable = false; switch ($link->getIsShareable()) { - case \Magento\Downloadable\Model\Link::LINK_SHAREABLE_YES: - case \Magento\Downloadable\Model\Link::LINK_SHAREABLE_NO: + case Link::LINK_SHAREABLE_YES: + case Link::LINK_SHAREABLE_NO: $shareable = (bool)$link->getIsShareable(); break; - case \Magento\Downloadable\Model\Link::LINK_SHAREABLE_CONFIG: - $shareable = (bool)$this->scopeConfig->isSetFlag( - \Magento\Downloadable\Model\Link::XML_PATH_CONFIG_IS_SHAREABLE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + case Link::LINK_SHAREABLE_CONFIG: + $shareable = $this->scopeConfig->isSetFlag( + Link::XML_PATH_CONFIG_IS_SHAREABLE, + ScopeInterface::SCOPE_STORE ); } return $shareable; diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index 8ebd45596d399..0ab1b626b074f 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -122,16 +122,18 @@ public function getItems(QueryInterface $query, $limit = null, $additionalFilter */ public function isResultsCountEnabled() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::CONFIG_SUGGESTION_COUNT_RESULTS_ENABLED, ScopeInterface::SCOPE_STORE ); } - /** - * @param QueryInterface $query - * @return array - */ + /** + * @param QueryInterface $query + * + * @return array + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ private function getSuggestions(QueryInterface $query) { $suggestions = []; @@ -204,7 +206,7 @@ private function getSearchSuggestionsCount() */ private function isSuggestionsAllowed() { - $isSearchSuggestionsEnabled = (bool)$this->scopeConfig->getValue( + $isSearchSuggestionsEnabled = $this->scopeConfig->isSetFlag( self::CONFIG_SUGGESTION_ENABLED, ScopeInterface::SCOPE_STORE ); diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index c7f145eaddbb4..3001fa411655c 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -13,6 +13,7 @@ use Magento\Framework\Locale\FormatInterface as LocaleFormat; use Magento\Framework\Data\Form\FormKey; use Magento\Catalog\Model\Product\Attribute\Source\Boolean; +use Magento\Store\Model\ScopeInterface; /** * Configuration provider for GiftMessage rendering on "Checkout cart" page. @@ -41,7 +42,12 @@ class GiftMessageConfigProvider implements ConfigProviderInterface */ protected $checkoutSession; - /** + /** + * @var HttpContext + */ + protected $httpContext; + + /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; @@ -93,13 +99,13 @@ public function getConfig() { $configuration = []; $configuration['giftMessage'] = []; - $orderLevelGiftMessageConfiguration = (bool)$this->scopeConfiguration->getValue( + $orderLevelGiftMessageConfiguration = $this->scopeConfiguration->isSetFlag( GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); - $itemLevelGiftMessageConfiguration = (bool)$this->scopeConfiguration->getValue( + $itemLevelGiftMessageConfiguration = $this->scopeConfiguration->isSetFlag( GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); if ($orderLevelGiftMessageConfiguration) { $orderMessages = $this->getOrderLevelGiftMessages(); @@ -164,11 +170,12 @@ protected function getOrderLevelGiftMessages() return $this->cartRepository->get($cartId); } - /** - * Load already specified item level gift messages and related configuration. - * - * @return \Magento\GiftMessage\Api\Data\MessageInterface[]|null - */ + /** + * Load already specified item level gift messages and related configuration. + * + * @return \Magento\GiftMessage\Api\Data\MessageInterface[]|null + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ protected function getItemLevelGiftMessages() { $itemLevelConfig = []; diff --git a/app/code/Magento/GoogleOptimizer/Helper/Data.php b/app/code/Magento/GoogleOptimizer/Helper/Data.php index 5b0291eb1435d..4929e474949b3 100644 --- a/app/code/Magento/GoogleOptimizer/Helper/Data.php +++ b/app/code/Magento/GoogleOptimizer/Helper/Data.php @@ -51,7 +51,7 @@ public function __construct( */ public function isGoogleExperimentEnabled($store = null) { - return (bool)$this->scopeConfig->isSetFlag(self::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE, $store); + return $this->scopeConfig->isSetFlag(self::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE, $store); } /** diff --git a/app/code/Magento/Msrp/Model/Config.php b/app/code/Magento/Msrp/Model/Config.php index 2ee9f41870a5a..7a990e82cbdf7 100644 --- a/app/code/Magento/Msrp/Model/Config.php +++ b/app/code/Magento/Msrp/Model/Config.php @@ -74,7 +74,7 @@ public function setStoreId($store) */ public function isEnabled() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_MSRP_ENABLED, ScopeInterface::SCOPE_STORE, $this->storeId diff --git a/app/code/Magento/NewRelicReporting/Model/Config.php b/app/code/Magento/NewRelicReporting/Model/Config.php index 32e1078c01c9d..7c0273334d7ce 100644 --- a/app/code/Magento/NewRelicReporting/Model/Config.php +++ b/app/code/Magento/NewRelicReporting/Model/Config.php @@ -88,7 +88,7 @@ public function __construct( */ public function isNewRelicEnabled() { - return (bool)$this->scopeConfig->getValue('newrelicreporting/general/enable'); + return $this->scopeConfig->getValue('newrelicreporting/general/enable'); } /** @@ -168,7 +168,7 @@ public function getNewRelicAppName() */ public function isCronEnabled() { - return (bool)$this->scopeConfig->getValue('newrelicreporting/cron/enable_cron'); + return $this->scopeConfig->getValue('newrelicreporting/cron/enable_cron'); } /** diff --git a/app/code/Magento/Reports/Model/ReportStatus.php b/app/code/Magento/Reports/Model/ReportStatus.php index ec0c32d9af1ec..112b9e9ccc45d 100644 --- a/app/code/Magento/Reports/Model/ReportStatus.php +++ b/app/code/Magento/Reports/Model/ReportStatus.php @@ -37,8 +37,8 @@ public function __construct(ScopeConfigInterface $scopeConfig) */ public function isReportEnabled(string $reportEventType): bool { - return (bool)$this->scopeConfig->getValue('reports/options/enabled') - && (bool)$this->scopeConfig->getValue($this->getConfigPathByEventType($reportEventType)); + return $this->scopeConfig->isSetFlag('reports/options/enabled') + && $this->scopeConfig->isSetFlag($this->getConfigPathByEventType($reportEventType)); } /** diff --git a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php index 11a59cfa59f17..621206d9bbbb3 100644 --- a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php +++ b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php @@ -256,12 +256,14 @@ protected function _joinAttribute($storeId, $attributeCode, $column = null) } } - /** - * Get attribute data by attribute code - * - * @param string $attributeCode - * @return array - */ + /** + * Get attribute data by attribute code + * + * @param string $attributeCode + * + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ protected function _getAttribute($attributeCode) { if (!isset($this->_attributesCache[$attributeCode])) { @@ -279,12 +281,15 @@ protected function _getAttribute($attributeCode) return $this->_attributesCache[$attributeCode]; } - /** - * Get category collection array - * - * @param null|string|bool|int|Store $storeId - * @return array|bool - */ + /** + * Get category collection array + * + * @param null|string|bool|int|Store $storeId + * + * @return array|bool + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ public function getCollection($storeId) { $products = []; @@ -343,13 +348,15 @@ public function getCollection($storeId) return $products; } - /** - * Prepare product - * - * @param array $productRow - * @param int $storeId - * @return \Magento\Framework\DataObject - */ + /** + * Prepare product + * + * @param array $productRow + * @param int $storeId + * + * @return \Magento\Framework\DataObject + * @throws \Magento\Framework\Exception\LocalizedException + */ protected function _prepareProduct(array $productRow, $storeId) { $product = new \Magento\Framework\DataObject(); @@ -482,7 +489,7 @@ private function getProductImageUrl($image) */ private function isCategoryProductURLsConfig($storeId) { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( HelperProduct::XML_PATH_PRODUCT_URL_USE_CATEGORY, ScopeInterface::SCOPE_STORE, $storeId diff --git a/app/code/Magento/Store/Model/BaseUrlChecker.php b/app/code/Magento/Store/Model/BaseUrlChecker.php index b65a76e8806f1..6e3defac9a1cd 100644 --- a/app/code/Magento/Store/Model/BaseUrlChecker.php +++ b/app/code/Magento/Store/Model/BaseUrlChecker.php @@ -5,6 +5,8 @@ */ namespace Magento\Store\Model; +use Magento\Store\Model\ScopeInterface; + /** * Verifies that the requested URL matches to base URL of store. */ @@ -47,9 +49,9 @@ public function execute($uri, $request) */ public function isEnabled() { - return (bool) $this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( 'web/url/redirect_to_base', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } @@ -62,13 +64,13 @@ public function isFrontendSecure() { $baseUrl = $this->scopeConfig->getValue( 'web/unsecure/base_url', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); $baseUrlParts = explode('://', $baseUrl); $baseUrlProtocol = array_shift($baseUrlParts); - $isSecure = (bool) $this->scopeConfig->getValue( + $isSecure = $this->scopeConfig->isSetFlag( 'web/secure/use_in_frontend', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); return $isSecure && $baseUrlProtocol == 'https'; diff --git a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php index 623fbed57e6c6..63afa7ad1fc84 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php +++ b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php @@ -45,7 +45,7 @@ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $ */ public function canApply() { - return (bool)$this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_FRONTEND) + return $this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_FRONTEND) && $this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML) && $this->scopeConfig->isSetFlag(Store::XML_PATH_ENABLE_HSTS); } diff --git a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php index a0bd015c15061..5dbe65141f184 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php +++ b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php @@ -45,7 +45,7 @@ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $ */ public function canApply() { - return (bool)$this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_FRONTEND) + return $this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_FRONTEND) && $this->scopeConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML) && $this->scopeConfig->isSetFlag(Store::XML_PATH_ENABLE_UPGRADE_INSECURE); } diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 445824baadfe0..0f2d0c90bd51a 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -291,9 +291,9 @@ function ($item) { */ protected function isSingleStoreModeEnabled() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( self::XML_PATH_SINGLE_STORE_MODE_ENABLED, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } diff --git a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php index 75df3027ad9a9..233b7a804d94d 100644 --- a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php +++ b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php @@ -7,6 +7,7 @@ namespace Magento\Wishlist\Model\Rss; use Magento\Framework\App\Rss\DataProviderInterface; +use Magento\Store\Model\ScopeInterface; /** * Wishlist RSS model @@ -114,17 +115,18 @@ public function __construct( */ public function isAllowed() { - return (bool)$this->scopeConfig->getValue( + return $this->scopeConfig->isSetFlag( 'rss/wishlist/active', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } - /** - * Get RSS feed items - * - * @return array - */ + /** + * Get RSS feed items + * + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getRssData() { $wishlist = $this->getWishlist(); diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index feb4877028dae..90ee7541a5d6a 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -85,10 +85,12 @@ public function __construct( $this->appState = $appState ?: \Magento\Framework\App\ObjectManager::getInstance()->get(State::class); } - /** - * @param SessionManagerInterface $session - * @return string|null - */ + /** + * @param SessionManagerInterface $session + * + * @return string|null + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getSid(SessionManagerInterface $session) { if ($this->appState->getAreaCode() !== \Magento\Framework\App\Area::AREA_FRONTEND) { @@ -169,7 +171,7 @@ public function getUseSessionInUrl() if ($this->_useSessionInUrl === null) { //Using config value by default, can be overridden by using the //setter. - $this->_useSessionInUrl = (bool)$this->scopeConfig->getValue( + $this->_useSessionInUrl = $this->scopeConfig->getValue( self::XML_PATH_USE_FRONTEND_SID, $this->_scopeType ); diff --git a/lib/internal/Magento/Framework/View/Asset/Config.php b/lib/internal/Magento/Framework/View/Asset/Config.php index 2a3d0d3dad467..6a0548b3395a0 100644 --- a/lib/internal/Magento/Framework/View/Asset/Config.php +++ b/lib/internal/Magento/Framework/View/Asset/Config.php @@ -8,7 +8,6 @@ use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\App\State; /** * View asset configuration interface @@ -55,7 +54,7 @@ public function __construct(ScopeConfigInterface $scopeConfig) */ public function isMergeCssFiles() { - return (bool)$this->scopeConfig->isSetFlag( + return $this->scopeConfig->isSetFlag( self::XML_PATH_MERGE_CSS_FILES, ScopeInterface::SCOPE_STORE ); @@ -68,7 +67,7 @@ public function isMergeCssFiles() */ public function isBundlingJsFiles() { - return (bool)$this->scopeConfig->isSetFlag( + return $this->scopeConfig->isSetFlag( self::XML_PATH_JS_BUNDLING, ScopeInterface::SCOPE_STORE ); @@ -81,7 +80,7 @@ public function isBundlingJsFiles() */ public function isMergeJsFiles() { - return (bool)$this->scopeConfig->isSetFlag( + return $this->scopeConfig->isSetFlag( self::XML_PATH_MERGE_JS_FILES, ScopeInterface::SCOPE_STORE ); @@ -94,7 +93,7 @@ public function isMergeJsFiles() */ public function isMinifyHtml() { - return (bool)$this->scopeConfig->isSetFlag( + return $this->scopeConfig->isSetFlag( self::XML_PATH_MINIFICATION_HTML, ScopeInterface::SCOPE_STORE ); diff --git a/lib/internal/Magento/Framework/View/Asset/Minification.php b/lib/internal/Magento/Framework/View/Asset/Minification.php index 596add349dbfa..ceee78469f090 100644 --- a/lib/internal/Magento/Framework/View/Asset/Minification.php +++ b/lib/internal/Magento/Framework/View/Asset/Minification.php @@ -64,7 +64,7 @@ public function isEnabled($contentType) if (!isset($this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType])) { $this->configCache[self::XML_PATH_MINIFICATION_ENABLED][$contentType] = $this->appState->getMode() != State::MODE_DEVELOPER && - (bool)$this->scopeConfig->isSetFlag( + $this->scopeConfig->isSetFlag( sprintf(self::XML_PATH_MINIFICATION_ENABLED, $contentType), $this->scope ); From 6c168dd9ced1f3eb141b01dc8091319b474811a6 Mon Sep 17 00:00:00 2001 From: Bartosz Kubicki <bartosz.kubicki@lizardmedia.pl> Date: Tue, 11 Sep 2018 19:38:22 +0200 Subject: [PATCH 0094/1415] Adding trimming sku value function to sku backend model. Adding trimming sku value function to sku backend model. Adding frontend validation for sku field. --- .../Model/Product/Attribute/Backend/Sku.php | 14 ++++++++++++++ .../DataProvider/Product/Form/Modifier/General.php | 3 ++- app/code/Magento/Ui/i18n/en_US.csv | 1 + .../Ui/view/base/web/js/lib/validation/rules.js | 6 ++++++ lib/web/i18n/en_US.csv | 1 + lib/web/mage/validation.js | 6 ++++++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php index a652d0ef90213..2ea3b9aaf10a8 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php @@ -97,6 +97,7 @@ protected function _generateUniqueSku($object) public function beforeSave($object) { $this->_generateUniqueSku($object); + $this->trimValue($object); return parent::beforeSave($object); } @@ -127,4 +128,17 @@ protected function _getLastSimilarAttributeValueIncrement($attribute, $object) $data = $connection->fetchOne($select, $bind); return abs((int)str_replace($value, '', $data)); } + + /** + * @param Product $object + * @return void + */ + private function trimValue($object) + { + $attrCode = $this->getAttribute()->getAttributeCode(); + $value = $object->getData($attrCode); + if ($value) { + $object->setData($attrCode, trim($value)); + } + } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index 98de8ea347671..e0b0d066c1c1d 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -361,7 +361,8 @@ protected function customizeNameListeners(array $meta) $skuPath . static::META_CONFIG_PATH, $meta, [ - 'autoImportIfEmpty' => true + 'autoImportIfEmpty' => true, + 'validation' => ['no-marginal-whitespace' => true] ] ); diff --git a/app/code/Magento/Ui/i18n/en_US.csv b/app/code/Magento/Ui/i18n/en_US.csv index 106526f66e708..2731d4be182a4 100644 --- a/app/code/Magento/Ui/i18n/en_US.csv +++ b/app/code/Magento/Ui/i18n/en_US.csv @@ -58,6 +58,7 @@ Keyword,Keyword "Letters, numbers, spaces or underscores only please","Letters, numbers, spaces or underscores only please" "Letters only please","Letters only please" "No white space please","No white space please" +"No marginal white space please","No marginal white space please" "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx","Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx" "A positive or negative non-decimal number please","A positive or negative non-decimal number please" "The specified vehicle identification number (VIN) is invalid.","The specified vehicle identification number (VIN) is invalid." diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index 1103f3e54a4cf..ced16e01b2bc4 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -116,6 +116,12 @@ define([ }, $.mage.__('No white space please') ], + 'no-marginal-whitespace': [ + function (value) { + return !/^\s+|\s+$/i.test(value); + }, + $.mage.__('No marginal white space please') + ], 'zip-range': [ function (value) { return /^90[2-5]-\d{2}-\d{4}$/.test(value); diff --git a/lib/web/i18n/en_US.csv b/lib/web/i18n/en_US.csv index 5c63a191420a4..bca42473e2f0b 100644 --- a/lib/web/i18n/en_US.csv +++ b/lib/web/i18n/en_US.csv @@ -27,6 +27,7 @@ Submit,Submit "Letters, numbers, spaces or underscores only please","Letters, numbers, spaces or underscores only please" "Letters only please","Letters only please" "No white space please","No white space please" +"No marginal white space please","No marginal white space please" "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx","Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx" "A positive or negative non-decimal number please","A positive or negative non-decimal number please" "The specified vehicle identification number (VIN) is invalid.","The specified vehicle identification number (VIN) is invalid." diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index d08819ebe94aa..dcfe9c41d311f 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -253,6 +253,12 @@ }, $.mage.__('No white space please') ], + 'no-marginal-whitespace': [ + function (value, element) { + return this.optional(element) || !/^\s+|\s+$/i.test(value); + }, + $.mage.__('No marginal white space please') + ], 'zip-range': [ function (value, element) { return this.optional(element) || /^90[2-5]-\d{2}-\d{4}$/.test(value); From ae42612217947d75aa09b300a34e23487b8954c3 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 13:58:19 -0300 Subject: [PATCH 0095/1415] Fix date format for different locales --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 3c2f20fcc186f..242c551c984f9 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -309,11 +309,23 @@ public function formatDateTime( */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { + $formatter = new \IntlDateFormatter( + $this->_localeResolver->getLocale(), + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + null + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { - $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone())); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); + $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); } } else { if ($date->getTimezone()->getName() !== $this->getConfigTimezone()) { From 7b728b19841eedc9c53bd6e65dd58c521e2ed56d Mon Sep 17 00:00:00 2001 From: Leandro Rosa <dev.leandrorosa@gmail.com> Date: Sun, 16 Sep 2018 14:30:56 -0300 Subject: [PATCH 0096/1415] Add checkout_cart_product_add_before event #17830 --- app/code/Magento/Checkout/Model/Cart.php | 4 ++++ .../Checkout/Test/Unit/Model/CartTest.php | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index be5692a894865..33f4fc9000c21 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -370,6 +370,10 @@ public function addProduct($productInfo, $requestInfo = null) if ($productId) { try { + $this->_eventManager->dispatch( + 'checkout_cart_product_add_before', + ['info' => $requestInfo, 'product' => $product] + ); $result = $this->getQuote()->addProduct($product, $request); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->_checkoutSession->setUseNotice(false); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php index 40de71e28c05e..88bc57b2c279a 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php @@ -315,6 +315,12 @@ public function testAddProduct($productInfo, $requestInfo) $this->productRepository->expects($this->any()) ->method('getById') ->will($this->returnValue($product)); + + $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => $requestInfo, 'product' => $product] + ); + $this->quoteMock->expects($this->once()) ->method('addProduct') ->will($this->returnValue(1)); @@ -322,7 +328,7 @@ public function testAddProduct($productInfo, $requestInfo) ->method('getQuote') ->will($this->returnValue($this->quoteMock)); - $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + $this->eventManagerMock->expects($this->at(1))->method('dispatch')->with( 'checkout_cart_product_add_after', ['quote_item' => 1, 'product' => $product] ); @@ -360,6 +366,12 @@ public function testAddProductException() $this->productRepository->expects($this->any()) ->method('getById') ->will($this->returnValue($product)); + + $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => 4, 'product' => $product] + ); + $this->quoteMock->expects($this->once()) ->method('addProduct') ->will($this->returnValue('error')); @@ -396,6 +408,11 @@ public function testAddProductExceptionBadParams() ->method('getById') ->will($this->returnValue($product)); + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => 'bad', 'product' => $product] + ); + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( 'checkout_cart_product_add_after', ['quote_item' => 1, 'product' => $product] From c4fa85bb59e9006f12fa79854da78af4e3fd601e Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 14:49:06 -0300 Subject: [PATCH 0097/1415] Move formatter into string conversion block --- app/code/Magento/Newsletter/Model/Queue.php | 3 ++- .../Framework/Stdlib/DateTime/Timezone.php | 22 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index efb68fd4243d1..83c80e1e5afce 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,7 +196,8 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); + $startAt = $this->timezone->convertConfigTimeToUtc($startAt, null); + $this->setQueueStartAt($startAt); } return $this; } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 242c551c984f9..54e6e9e1d3caf 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -309,21 +309,21 @@ public function formatDateTime( */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { - $formatter = new \IntlDateFormatter( - $this->_localeResolver->getLocale(), - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - null - ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { + $formatter = new \IntlDateFormatter( + $this->_localeResolver->getLocale(), + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + $format + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); } From 6bda779e40699ae1e4b16920374cfd398dea28a8 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 15:21:20 -0300 Subject: [PATCH 0098/1415] Convert internationalized date into DateTime object --- app/code/Magento/Newsletter/Model/Queue.php | 2 +- .../Framework/Stdlib/DateTime/Timezone.php | 20 ++++++++++++++++++- .../Stdlib/DateTime/TimezoneInterface.php | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 83c80e1e5afce..67f8cadbfaed4 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,7 +196,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $startAt = $this->timezone->convertConfigTimeToUtc($startAt, null); + $startAt = $this->timezone->convertConfigTimeToUtcWithPattern($startAt, 'Y-m-d H:i:s', null); $this->setQueueStartAt($startAt); } return $this; diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 54e6e9e1d3caf..a083b7c6fa986 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -306,8 +306,25 @@ public function formatDateTime( * @param string $format * @throws LocalizedException * @return string + * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') + { + return $this->convertConfigTimeToUtcWithPattern($date, $format); + } + + /** + * Convert date from config timezone to Utc. + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date + * @param string $format + * @param string $pattern + * @throws LocalizedException + * @return string + * @deprecated + */ + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-M-dd HH:mm:ss') { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { @@ -319,7 +336,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') \IntlDateFormatter::MEDIUM, $this->getConfigTimezone(), null, - $format + $pattern ); $unixTime = $formatter->parse($date); $dateTime = new DateTime($this); @@ -343,6 +360,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') return $date->format($format); } + /** * Retrieve date with time * diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index a8b3fb1a81ffe..5a4b15d6cca0c 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -143,6 +143,15 @@ public function formatDateTime( * @param string $format * @return string * @since 100.1.0 + * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); + + /** + * @param $date + * @param string $format + * @param string $pattern + * @return mixed + */ + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From a4f80a9d93c455328a08718b1c7319fde0dfc32f Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 15:50:33 -0300 Subject: [PATCH 0099/1415] Force pattern if locale not found --- .../Framework/Stdlib/DateTime/Timezone.php | 8 +++-- .../Test/Unit/DateTime/TimezoneTest.php | 29 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index a083b7c6fa986..59b299d176bd1 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -324,14 +324,18 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') * @return string * @deprecated */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-M-dd HH:mm:ss') + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = null) { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { + $locale = $this->_localeResolver->getLocale(); + if ($locale === null) { + $pattern = 'Y-M-dd HH:mm:ss'; + } $formatter = new \IntlDateFormatter( - $this->_localeResolver->getLocale(), + $locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::MEDIUM, $this->getConfigTimezone(), diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index d57525590b9e8..ea761db902674 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -124,11 +124,15 @@ public function dateIncludeTimeDataProvider() * @param string $expectedResult * @dataProvider getConvertConfigTimeToUtcFixtures */ - public function testConvertConfigTimeToUtc($date, $configuredTimezone, $expectedResult) + public function testConvertConfigTimeToUtc($date, $configuredTimezone, $configuredLocale, $expectedResult) { + $this->localeResolver + ->method('getLocale') + ->willReturn($configuredLocale); + $this->scopeConfigWillReturnConfiguredTimezone($configuredTimezone); - $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtc($date)); + $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtcWithPattern($date)); } /** @@ -141,16 +145,37 @@ public function getConvertConfigTimeToUtcFixtures() 'string' => [ '2016-10-10 10:00:00', 'UTC', + null, '2016-10-10 10:00:00' ], + 'string-en_US' => [ + 'Sep 29, 2018, 6:07:38 PM', + 'UTC', + 'en_US', + '2018-09-29 18:07:38' + ], + 'string-pt_BR' => [ + '29 de set de 2018 18:07:38', + 'UTC', + 'pt_BR', + '2018-09-29 18:07:38' + ], + 'string-tr_TR' => [ + '29 Eyl 2018 18:07:38', + 'UTC', + 'tr_TR', + '2018-09-29 18:07:38' + ], 'datetime' => [ new \DateTime('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', + null, '2016-10-10 10:00:00' ], 'datetimeimmutable' => [ new \DateTimeImmutable('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', + null, '2016-10-10 10:00:00' ] ]; From a44eb5dd5fd2a95f79b617a480b9221704495887 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Sun, 16 Sep 2018 17:14:58 -0300 Subject: [PATCH 0100/1415] #17744 Adding logic to get default billing address --- .../web/js/model/checkout-data-resolver.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 73f4df567903c..6586f647e2404 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -219,15 +219,26 @@ define([ */ applyBillingAddress: function () { var shippingAddress; + var isBillingAddressInitialized; if (quote.billingAddress()) { selectBillingAddress(quote.billingAddress()); return; } - shippingAddress = quote.shippingAddress(); + shippingAddress = quote.billingAddress(); + if(quote.isVirtual()) { + isBillingAddressInitialized = addressList.some(function (addrs) { + if (addrs.isDefaultBilling()) { + selectBillingAddress(addrs); + return true; + } + return false; + }); + } - if (shippingAddress && + if (!isBillingAddressInitialized && + shippingAddress && shippingAddress.canUseForBilling() && (shippingAddress.isDefaultShipping() || !quote.isVirtual()) ) { From 8aedb958f43bf714c934b677c90d4b74b9d1922b Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sun, 16 Sep 2018 20:24:39 +0000 Subject: [PATCH 0101/1415] GraphQl-44: prototype of format strategy Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- ...ibute.php => ProductTextareaAttribute.php} | 25 ++++++---- .../FormatFactory.php | 43 +++++++++++++++++ .../FormatInterface.php | 23 +++++++++ .../Product/ProductTextareaAttribute/Html.php | 47 +++++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 41 +++++++++------- 5 files changed, 152 insertions(+), 27 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductHtmlAttribute.php => ProductTextareaAttribute.php} (67%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php similarity index 67% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php index 18d15088e6656..f04609f91c86d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php @@ -8,38 +8,40 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Catalog\Helper\Output as OutputHelper; /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductHtmlAttribute implements ResolverInterface +class ProductTextareaAttribute implements ResolverInterface { + const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** * @var ValueFactory */ private $valueFactory; /** - * @var OutputHelper + * @var FormatFactory */ - private $outputHelper; + private $formatFactory; /** * @param ValueFactory $valueFactory - * @param OutputHelper $outputHelper + * @param FormatFactory $formatFactory */ public function __construct( ValueFactory $valueFactory, - OutputHelper $outputHelper + FormatFactory $formatFactory ) { $this->valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; + $this->formatFactory = $formatFactory; } /** @@ -62,9 +64,12 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - $result = function () use ($renderedValue) { - return $renderedValue; + $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; + $format = $this->formatFactory->create($formatIdentifier); + $attribute = ['content' => $format->getContent($product, $fieldName)]; + + $result = function () use ($attribute) { + return $attribute; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php new file mode 100644 index 0000000000000..2aab2d5816083 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Framework\ObjectManagerInterface; + +class FormatFactory +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * @param string $formatIdentifier + * @param array $data + * @return FormatInterface + */ + public function create(string $formatIdentifier, $data = []) : FormatInterface + { + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->create($formatClassName, $data); + if (false == $formatInstance instanceof FormatInterface) { + throw new \InvalidArgumentException( + $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' + ); + } + return $formatInstance; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php new file mode 100644 index 0000000000000..fae685b75c060 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Catalog\Model\Product as ModelProduct; + +interface FormatInterface +{ + /** + * @param ModelProduct $product + * @param string $fieldName + * @return string + */ + public function getContent( + ModelProduct $product, + string $fieldName + ): string; +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php new file mode 100644 index 0000000000000..8201c40427dc9 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Catalog\Helper\Output as OutputHelper; +use Magento\Catalog\Model\Product as ModelProduct; + +class Html implements FormatInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param ValueFactory $valueFactory + * @param OutputHelper $outputHelper + */ + public function __construct( + ValueFactory $valueFactory, + OutputHelper $outputHelper + ) { + $this->valueFactory = $valueFactory; + $this->outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function getContent( + ModelProduct $product, + string $fieldName + ): string { + return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f63c1a96762c2..82bc262ecf3c3 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") - ): CategoryTree + id: Int @doc(description: "Id of the category") +): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: String @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") - short_description: String @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") + description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") -{ -} + { + } type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") @@ -551,3 +551,10 @@ type SortFields @doc(description: "SortFields contains a default value for sort default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } + +type ProductTextareaAttribute { + content ( + format: String! @doc(description: "The format of content") +): String + @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") +} From cde04fc296154d8ade7c390b3eb3def76dcc4c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sun, 16 Sep 2018 20:38:50 +0000 Subject: [PATCH 0102/1415] GraphQl-45: pretified schema Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../CatalogGraphQl/etc/schema.graphqls | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 82bc262ecf3c3..a9c4a1b4bd8ae 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") -): CategoryTree + id: Int @doc(description: "Id of the category") + ): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") - { - } +{ +} type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") From d83c61c9d84bf96d925915de881c210d066b2292 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Sun, 16 Sep 2018 19:38:15 -0500 Subject: [PATCH 0103/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- ...ateVisualSwatchWithNonValidOptionsTest.xml | 2 +- dev/tests/acceptance/.gitignore | 1 + .../Handler/CatalogProductAttribute/Curl.php | 61 +++++++++++++++++++ .../Handler/SwatchProductAttribute/Curl.php | 4 +- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 92a33487615ea..1e9ce849db1be 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -17,7 +17,7 @@ <group value="Swatches"/> </annotations> <before> - <actionGroup ref="LoginActionGroup" stepKey="login"/> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> </before> <after> <!-- Remove attribute --> diff --git a/dev/tests/acceptance/.gitignore b/dev/tests/acceptance/.gitignore index e3ef78df82b9f..87ce9d4ff35d1 100755 --- a/dev/tests/acceptance/.gitignore +++ b/dev/tests/acceptance/.gitignore @@ -7,4 +7,5 @@ tests/functional.suite.yml tests/functional/Magento/FunctionalTest/_generated vendor/* mftf.log +/.credentials.example /utils/ \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index d78095f05fe45..57d775cdeb736 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -134,11 +134,72 @@ public function persist(FixtureInterface $fixture = null) } /** + * Additional data handling. + * * @param array $data * @return array */ protected function changeStructureOfTheData(array $data) { + $serializedOptions = $this->getSerializeOptions($data, ['option']); + if ($serializedOptions) { + $data['serialized_options'] = $serializedOptions; + unset($data['option']); + } + return $data; } + + /** + * Provides serialized product attribute options. + * + * @param array $data + * @param array $optionKeys + * @return array + */ + protected function getSerializeOptions(array $data, array $optionKeys): string + { + $options = []; + foreach ($optionKeys as $optionKey) { + if (!empty($data[$optionKey])) { + $options = array_merge( + $options, + $this->getEncodedOptions([$optionKey => $data[$optionKey]]) + ); + } + } + + return json_encode($options); + } + + /** + * Provides encoded attribute values. + * + * @param array $data + * @return array + */ + private function getEncodedOptions(array $data): array + { + $optionsData = []; + $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($data)); + foreach ($iterator as $value) { + $depth = $iterator->getDepth(); + $option = ''; + + $level = 0; + $option .= $iterator->getSubIterator($level)->key(); + $level++; + + while ($level <= $depth) { + $option .= '[' . $iterator->getSubIterator($level)->key() . ']'; + $level++; + } + + $option .= '=' . $value; + + $optionsData[] = $option; + } + + return $optionsData; + } } diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php index 083fa246c96ef..5e4a5cc45fe69 100644 --- a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php @@ -38,12 +38,14 @@ public function __construct(DataInterface $configuration, EventManagerInterface */ protected function changeStructureOfTheData(array $data) { - $data = parent::changeStructureOfTheData($data); $data['optiontext'] = $data['option']; $data['swatchtext'] = [ 'value' => $data['option']['value'] ]; + $data['serialized_options'] = $this->getSerializeOptions($data, ['optiontext', 'swatchtext']); unset($data['option']); + $data = parent::changeStructureOfTheData($data); + return $data; } } From f1614cda41d4ec53109f421ccb9a81e3804c2391 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 13 Sep 2018 15:42:50 +0300 Subject: [PATCH 0104/1415] MAGETWO-91553: Admin user with role scope set to custom is unable to view abandoned carts report - Fix added --- .../Model/ResourceModel/Quote/Collection.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php index 671acc9701012..251326415a514 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php @@ -5,6 +5,8 @@ */ namespace Magento\Reports\Model\ResourceModel\Quote; +use Magento\Store\Model\Store; + /** * @api * @since 100.0.2 @@ -48,6 +50,24 @@ public function __construct( $this->customerResource = $customerResource; } + /** + * Filter collections by stores. + * + * @param array $storeIds + * @param bool $withAdmin + * @return $this + */ + public function addStoreFilter(array $storeIds, $withAdmin = true) + { + if ($withAdmin) { + $storeIds[] = Store::DEFAULT_STORE_ID; + } + + $this->addFieldToFilter('store_id', ['in' => $storeIds]); + + return $this; + } + /** * Prepare for abandoned report * From b1227fc73a76c8dfe7c0af3241b4eeb19e7eb18b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 17 Sep 2018 15:18:36 +0200 Subject: [PATCH 0105/1415] Changed query depth limiter behavior --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/QueryComplexityLimiterTest.php | 6 +++++- .../GraphQl/Query/QueryComplexityLimiter.php | 14 ++++---------- .../Framework/GraphQl/Query/QueryProcessor.php | 6 ++++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 529280b7cbb6e..b1d24ce6c4a55 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,7 +99,7 @@ </type> <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> - <argument name="queryDepth" xsi:type="number">10</argument> + <argument name="queryDepth" xsi:type="number">15</argument> <argument name="queryComplexity" xsi:type="number">50</argument> </arguments> </type> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index c5f645a94472a..4616c450786ed 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -9,6 +9,10 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Tests query complexity limiter and depth limiter. + * Actual for production mode only + */ class QueryComplexityLimiterTest extends GraphQlAbstract { /** @@ -159,7 +163,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 10 but got 20/'); + self::expectExceptionMessageRegExp('/Max query depth should be 15 but got 20/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index a144ef8967f17..15e0edb2400ec 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -36,23 +36,17 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 10, + int $queryDepth = 15, int $queryComplexity = 50 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; } - /** - * @param bool $developerMode - */ - public function execute(bool $developerMode = false): void + public function execute(): void { DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); - - if (!$developerMode) { - DocumentValidator::addRule(new DisableIntrospection()); - DocumentValidator::addRule(new QueryDepth($this->queryDepth)); - } + DocumentValidator::addRule(new DisableIntrospection()); + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 57ff56b665a1e..98e6c840ba682 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,8 +55,10 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $developerMode = !$this->exceptionFormatter->shouldShowDetail(); - $this->queryComplexityLimiter->execute($developerMode); + var_dump($this->exceptionFormatter->shouldShowDetail()); + if (!$this->exceptionFormatter->shouldShowDetail()) { + $this->queryComplexityLimiter->execute(); + } $rootValue = null; return \GraphQL\GraphQL::executeQuery( From 1a64b7d2396ef7aea3bc59bffbade0727c352c29 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Mon, 17 Sep 2018 16:19:53 +0300 Subject: [PATCH 0106/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- app/code/Magento/Sales/Controller/AbstractController/Reorder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index cbc0c2cd007a9..a96892978c7fb 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ From 57fe7c19716fbc248fb7679063f2c4cd6281b7e6 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Mon, 17 Sep 2018 17:24:41 +0400 Subject: [PATCH 0107/1415] MAGETWO-91704: Can't cancel/change payment method after chosen Store Credit - Add locator for automated test --- .../Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index e4d329bc85057..8aaf626edab33 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -9,9 +9,10 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderFormPaymentSection"> + <element name="useCustomerBalance" type="checkbox" selector="#p_method_use_customerbalance"/> <element name="header" type="text" selector="#order-methods span.title"/> <element name="getShippingMethods" type="text" selector="#order-shipping_method a.action-default" timeout="30"/> <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> <element name="shippingError" type="text" selector="#order[has_shipping]-error"/> </section> -</sections> \ No newline at end of file +</sections> From 0890139741aa73a06f81223e0793c0994e171f4d Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 11:05:54 -0300 Subject: [PATCH 0108/1415] #17744 Reorganizing code --- .../view/frontend/web/js/model/checkout-data-resolver.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6586f647e2404..7a1ba9513ec42 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -226,7 +226,7 @@ define([ return; } - shippingAddress = quote.billingAddress(); + if(quote.isVirtual()) { isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { @@ -237,6 +237,7 @@ define([ }); } + shippingAddress = quote.shippingAddress(); if (!isBillingAddressInitialized && shippingAddress && shippingAddress.canUseForBilling() && From 46427da4fbf0a2590dec1cad296e1aec12108be3 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Mon, 17 Sep 2018 18:08:59 +0400 Subject: [PATCH 0109/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Update automated test to add logout action --- .../Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index 253eb7a3be609..ecc415585eb16 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -81,6 +81,7 @@ <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="StorefrontSignOutActionGroup"/> </after> <!-- Login as a customer --> From ee0b4526d0afd75342279ec631b2703e09745f2b Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 17 Sep 2018 11:50:49 -0500 Subject: [PATCH 0110/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fix functional tests --- app/code/Magento/Sales/Model/Order.php | 865 +++++++++++++++++-------- 1 file changed, 590 insertions(+), 275 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 89557be349953..47979591a5843 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -570,6 +570,7 @@ public function canCancel() /** * Getter whether the payment can be voided + * * @return bool */ public function canVoidPayment() @@ -886,7 +887,7 @@ protected function _placePayment() } /** - * {@inheritdoc} + * @inheritdoc */ public function getPayment() { @@ -1013,8 +1014,9 @@ public function addStatusToHistory($status, $comment = '', $isCustomerNotified = } /** - * Add a comment to order - * Different or default status may be specified + * Add a comment to order. + * + * Different or default status may be specified. * * @param string $comment * @param bool|string $status @@ -1028,8 +1030,9 @@ public function addStatusHistoryComment($comment, $status = false) } /** - * Add a comment to order status history - * Different or default status may be specified + * Add a comment to order status history. + * + * Different or default status may be specified. * * @param string $comment * @param bool|string $status @@ -1094,6 +1097,8 @@ public function place() } /** + * Hold + * * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ @@ -1239,6 +1244,8 @@ public function getShippingMethod($asObject = false) /*********************** ADDRESSES ***************************/ /** + * Get addresses collection + * * @return Collection */ public function getAddressesCollection() @@ -1253,6 +1260,8 @@ public function getAddressesCollection() } /** + * Get address by id + * * @param mixed $addressId * @return false */ @@ -1267,6 +1276,8 @@ public function getAddressById($addressId) } /** + * Add address + * * @param \Magento\Sales\Model\Order\Address $address * @return $this */ @@ -1281,6 +1292,8 @@ public function addAddress(\Magento\Sales\Model\Order\Address $address) } /** + * Get items collection + * * @param array $filterByTypes * @param bool $nonChildrenOnly * @return ImportCollection @@ -1353,6 +1366,8 @@ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false) } /** + * Get all items + * * @return \Magento\Sales\Model\Order\Item[] */ public function getAllItems() @@ -1367,6 +1382,8 @@ public function getAllItems() } /** + * Get all visible items + * * @return array */ public function getAllVisibleItems() @@ -1398,6 +1415,8 @@ public function getItemById($itemId) } /** + * Get item by quote item id + * * @param mixed $quoteItemId * @return \Magento\Framework\DataObject|null */ @@ -1412,6 +1431,8 @@ public function getItemByQuoteItemId($quoteItemId) } /** + * Add item + * * @param \Magento\Sales\Model\Order\Item $item * @return $this */ @@ -1427,6 +1448,8 @@ public function addItem(\Magento\Sales\Model\Order\Item $item) /*********************** PAYMENTS ***************************/ /** + * Get payments collection + * * @return PaymentCollection */ public function getPaymentsCollection() @@ -1441,6 +1464,8 @@ public function getPaymentsCollection() } /** + * Get all payments + * * @return array */ public function getAllPayments() @@ -1455,6 +1480,8 @@ public function getAllPayments() } /** + * Get payment by id + * * @param mixed $paymentId * @return Payment|false */ @@ -1469,7 +1496,9 @@ public function getPaymentById($paymentId) } /** - * {@inheritdoc} + * Set payment + * + * @return \Magento\Sales\Api\Data\OrderPaymentInterface|null */ public function setPayment(\Magento\Sales\Api\Data\OrderPaymentInterface $payment = null) { @@ -1536,6 +1565,8 @@ public function getVisibleStatusHistory() } /** + * GetStatus history by id + * * @param mixed $statusId * @return string|false */ @@ -1550,7 +1581,8 @@ public function getStatusHistoryById($statusId) } /** - * Set the order status history object and the order object to each other + * Set the order status history object and the order object to each other. + * * Adds the object to the status history collection, which is automatically saved when the order is saved. * See the entity_id attribute backend model. * Or the history record can be saved standalone after this. @@ -1570,6 +1602,8 @@ public function addStatusHistory(\Magento\Sales\Model\Order\Status\History $hist } /** + * Get real real_order_id + * * @return string */ public function getRealOrderId() @@ -1608,6 +1642,8 @@ public function formatPrice($price, $addBrackets = false) } /** + * Format price precision + * * @param float $price * @param int $precision * @param bool $addBrackets @@ -1643,6 +1679,8 @@ public function getBaseCurrency() } /** + * Format BasePrice + * * @param float $price * @return string */ @@ -1652,6 +1690,8 @@ public function formatBasePrice($price) } /** + * Format BasePrice Precision + * * @param float $price * @param int $precision * @return string @@ -1662,6 +1702,8 @@ public function formatBasePricePrecision($price, $precision) } /** + * Is currency different + * * @return bool */ public function isCurrencyDifferent() @@ -1694,6 +1736,8 @@ public function getBaseTotalDue() } /** + * Get data + * * @param string $key * @param null|string|int $index * @return mixed @@ -1861,8 +1905,8 @@ public function addRelatedObject(\Magento\Framework\Model\AbstractModel $object) /** * Get formatted order created date in store timezone * - * @param string $format date format type (short|medium|long|full) - * @return string + * @param string $format date format type (short|medium|long|full) + * @return string */ public function getCreatedAtFormatted($format) { @@ -1876,6 +1920,8 @@ public function getCreatedAtFormatted($format) } /** + * Get email customer note + * * @return string */ public function getEmailCustomerNote() @@ -1887,6 +1933,8 @@ public function getEmailCustomerNote() } /** + * Get store group name + * * @return string */ public function getStoreGroupName() @@ -1899,8 +1947,7 @@ public function getStoreGroupName() } /** - * Resets all data in object - * so after another load it will be complete new object + * Reset all data in object so after another load it will be complete new object. * * @return $this */ @@ -1924,6 +1971,8 @@ public function reset() } /** + * Get IsNotVirtual + * * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ @@ -1954,7 +2003,7 @@ public function isCanceled() } /** - * Returns increment id + * Return increment id * * @codeCoverageIgnore * @@ -1966,6 +2015,8 @@ public function getIncrementId() } /** + * Get Items + * * @return \Magento\Sales\Api\Data\OrderItemInterface[] */ public function getItems() @@ -1980,7 +2031,9 @@ public function getItems() } /** - * {@inheritdoc} + * Set Items + * + * @return $this * @codeCoverageIgnore */ public function setItems($items) @@ -1989,6 +2042,8 @@ public function setItems($items) } /** + * Get addresses + * * @return \Magento\Sales\Api\Data\OrderAddressInterface[] */ public function getAddresses() @@ -2003,6 +2058,8 @@ public function getAddresses() } /** + * Get status History + * * @return \Magento\Sales\Api\Data\OrderStatusHistoryInterface[]|null */ public function getStatusHistories() @@ -2017,7 +2074,7 @@ public function getStatusHistories() } /** - * {@inheritdoc} + * Get ExtensionAttributes * * @return \Magento\Sales\Api\Data\OrderExtensionInterface|null */ @@ -2027,7 +2084,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * Set ExtensionAttributes * * @param \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes * @return $this @@ -2040,7 +2097,7 @@ public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderExtensionInt //@codeCoverageIgnoreStart /** - * Returns adjustment_negative + * Return adjustment_negative * * @return float|null */ @@ -2050,7 +2107,7 @@ public function getAdjustmentNegative() } /** - * Returns adjustment_positive + * Return adjustment_positive * * @return float|null */ @@ -2060,7 +2117,7 @@ public function getAdjustmentPositive() } /** - * Returns applied_rule_ids + * Return applied_rule_ids * * @return string|null */ @@ -2070,7 +2127,7 @@ public function getAppliedRuleIds() } /** - * Returns base_adjustment_negative + * Return base_adjustment_negative * * @return float|null */ @@ -2080,7 +2137,7 @@ public function getBaseAdjustmentNegative() } /** - * Returns base_adjustment_positive + * Return base_adjustment_positive * * @return float|null */ @@ -2090,7 +2147,7 @@ public function getBaseAdjustmentPositive() } /** - * Returns base_currency_code + * Return base_currency_code * * @return string|null */ @@ -2100,7 +2157,7 @@ public function getBaseCurrencyCode() } /** - * Returns base_discount_amount + * Return base_discount_amount * * @return float|null */ @@ -2110,7 +2167,7 @@ public function getBaseDiscountAmount() } /** - * Returns base_discount_canceled + * Return base_discount_canceled * * @return float|null */ @@ -2120,7 +2177,7 @@ public function getBaseDiscountCanceled() } /** - * Returns base_discount_invoiced + * Return base_discount_invoiced * * @return float|null */ @@ -2130,7 +2187,7 @@ public function getBaseDiscountInvoiced() } /** - * Returns base_discount_refunded + * Return base_discount_refunded * * @return float|null */ @@ -2140,7 +2197,7 @@ public function getBaseDiscountRefunded() } /** - * Returns base_grand_total + * Return base_grand_total * * @return float */ @@ -2150,7 +2207,7 @@ public function getBaseGrandTotal() } /** - * Returns base_discount_tax_compensation_amount + * Return base_discount_tax_compensation_amount * * @return float|null */ @@ -2160,7 +2217,7 @@ public function getBaseDiscountTaxCompensationAmount() } /** - * Returns base_discount_tax_compensation_invoiced + * Return base_discount_tax_compensation_invoiced * * @return float|null */ @@ -2170,7 +2227,7 @@ public function getBaseDiscountTaxCompensationInvoiced() } /** - * Returns base_discount_tax_compensation_refunded + * Return base_discount_tax_compensation_refunded * * @return float|null */ @@ -2180,7 +2237,7 @@ public function getBaseDiscountTaxCompensationRefunded() } /** - * Returns base_shipping_amount + * Return base_shipping_amount * * @return float|null */ @@ -2190,7 +2247,7 @@ public function getBaseShippingAmount() } /** - * Returns base_shipping_canceled + * Return base_shipping_canceled * * @return float|null */ @@ -2200,7 +2257,7 @@ public function getBaseShippingCanceled() } /** - * Returns base_shipping_discount_amount + * Return base_shipping_discount_amount * * @return float|null */ @@ -2210,7 +2267,7 @@ public function getBaseShippingDiscountAmount() } /** - * Returns base_shipping_discount_tax_compensation_amnt + * Return base_shipping_discount_tax_compensation_amnt * * @return float|null */ @@ -2220,7 +2277,7 @@ public function getBaseShippingDiscountTaxCompensationAmnt() } /** - * Returns base_shipping_incl_tax + * Return base_shipping_incl_tax * * @return float|null */ @@ -2230,8 +2287,8 @@ public function getBaseShippingInclTax() } /** - * Returns base_shipping_invoiced - * + * Return base_shipping_invoiced + * @return float|null */ public function getBaseShippingInvoiced() @@ -2240,7 +2297,7 @@ public function getBaseShippingInvoiced() } /** - * Returns base_shipping_refunded + * Return base_shipping_refunded * * @return float|null */ @@ -2250,7 +2307,7 @@ public function getBaseShippingRefunded() } /** - * Returns base_shipping_tax_amount + * Return base_shipping_tax_amount * * @return float|null */ @@ -2260,7 +2317,7 @@ public function getBaseShippingTaxAmount() } /** - * Returns base_shipping_tax_refunded + * Return base_shipping_tax_refunded * * @return float|null */ @@ -2270,7 +2327,7 @@ public function getBaseShippingTaxRefunded() } /** - * Returns base_subtotal + * Return base_subtotal * * @return float|null */ @@ -2280,7 +2337,7 @@ public function getBaseSubtotal() } /** - * Returns base_subtotal_canceled + * Return base_subtotal_canceled * * @return float|null */ @@ -2290,7 +2347,7 @@ public function getBaseSubtotalCanceled() } /** - * Returns base_subtotal_incl_tax + * Return base_subtotal_incl_tax * * @return float|null */ @@ -2300,7 +2357,7 @@ public function getBaseSubtotalInclTax() } /** - * Returns base_subtotal_invoiced + * Return base_subtotal_invoiced * * @return float|null */ @@ -2310,7 +2367,7 @@ public function getBaseSubtotalInvoiced() } /** - * Returns base_subtotal_refunded + * Return base_subtotal_refunded * * @return float|null */ @@ -2320,7 +2377,7 @@ public function getBaseSubtotalRefunded() } /** - * Returns base_tax_amount + * Return base_tax_amount * * @return float|null */ @@ -2330,7 +2387,7 @@ public function getBaseTaxAmount() } /** - * Returns base_tax_canceled + * Return base_tax_canceled * * @return float|null */ @@ -2340,7 +2397,7 @@ public function getBaseTaxCanceled() } /** - * Returns base_tax_invoiced + * Return base_tax_invoiced * * @return float|null */ @@ -2350,7 +2407,7 @@ public function getBaseTaxInvoiced() } /** - * Returns base_tax_refunded + * Return base_tax_refunded * * @return float|null */ @@ -2360,7 +2417,7 @@ public function getBaseTaxRefunded() } /** - * Returns base_total_canceled + * Return base_total_canceled * * @return float|null */ @@ -2370,7 +2427,7 @@ public function getBaseTotalCanceled() } /** - * Returns base_total_invoiced + * Return base_total_invoiced * * @return float|null */ @@ -2380,7 +2437,7 @@ public function getBaseTotalInvoiced() } /** - * Returns base_total_invoiced_cost + * Return base_total_invoiced_cost * * @return float|null */ @@ -2390,7 +2447,7 @@ public function getBaseTotalInvoicedCost() } /** - * Returns base_total_offline_refunded + * Return base_total_offline_refunded * * @return float|null */ @@ -2400,7 +2457,7 @@ public function getBaseTotalOfflineRefunded() } /** - * Returns base_total_online_refunded + * Return base_total_online_refunded * * @return float|null */ @@ -2410,7 +2467,7 @@ public function getBaseTotalOnlineRefunded() } /** - * Returns base_total_paid + * Return base_total_paid * * @return float|null */ @@ -2420,7 +2477,7 @@ public function getBaseTotalPaid() } /** - * Returns base_total_qty_ordered + * Return base_total_qty_ordered * * @return float|null */ @@ -2430,7 +2487,7 @@ public function getBaseTotalQtyOrdered() } /** - * Returns base_total_refunded + * Return base_total_refunded * * @return float|null */ @@ -2440,7 +2497,7 @@ public function getBaseTotalRefunded() } /** - * Returns base_to_global_rate + * Return base_to_global_rate * * @return float|null */ @@ -2450,7 +2507,7 @@ public function getBaseToGlobalRate() } /** - * Returns base_to_order_rate + * Return base_to_order_rate * * @return float|null */ @@ -2460,7 +2517,7 @@ public function getBaseToOrderRate() } /** - * Returns billing_address_id + * Return billing_address_id * * @return int|null */ @@ -2470,7 +2527,7 @@ public function getBillingAddressId() } /** - * Returns can_ship_partially + * Return can_ship_partially * * @return int|null */ @@ -2480,7 +2537,7 @@ public function getCanShipPartially() } /** - * Returns can_ship_partially_item + * Return can_ship_partially_item * * @return int|null */ @@ -2490,7 +2547,7 @@ public function getCanShipPartiallyItem() } /** - * Returns coupon_code + * Return coupon_code * * @return string|null */ @@ -2500,7 +2557,7 @@ public function getCouponCode() } /** - * Returns created_at + * Return created_at * * @return string|null */ @@ -2510,7 +2567,7 @@ public function getCreatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCreatedAt($createdAt) { @@ -2518,7 +2575,7 @@ public function setCreatedAt($createdAt) } /** - * Returns customer_dob + * Return customer_dob * * @return string|null */ @@ -2528,7 +2585,7 @@ public function getCustomerDob() } /** - * Returns customer_email + * Return customer_email * * @return string */ @@ -2538,7 +2595,7 @@ public function getCustomerEmail() } /** - * Returns customer_firstname + * Return customer_firstname * * @return string|null */ @@ -2548,7 +2605,7 @@ public function getCustomerFirstname() } /** - * Returns customer_gender + * Return customer_gender * * @return int|null */ @@ -2558,7 +2615,7 @@ public function getCustomerGender() } /** - * Returns customer_group_id + * Return customer_group_id * * @return int|null */ @@ -2568,7 +2625,7 @@ public function getCustomerGroupId() } /** - * Returns customer_id + * Return customer_id * * @return int|null */ @@ -2578,7 +2635,7 @@ public function getCustomerId() } /** - * Returns customer_is_guest + * Return customer_is_guest * * @return int|null */ @@ -2588,7 +2645,7 @@ public function getCustomerIsGuest() } /** - * Returns customer_lastname + * Return customer_lastname * * @return string|null */ @@ -2598,7 +2655,7 @@ public function getCustomerLastname() } /** - * Returns customer_middlename + * Return customer_middlename * * @return string|null */ @@ -2608,7 +2665,7 @@ public function getCustomerMiddlename() } /** - * Returns customer_note + * Return customer_note * * @return string|null */ @@ -2618,7 +2675,7 @@ public function getCustomerNote() } /** - * Returns customer_note_notify + * Return customer_note_notify * * @return int|null */ @@ -2628,7 +2685,7 @@ public function getCustomerNoteNotify() } /** - * Returns customer_prefix + * Return customer_prefix * * @return string|null */ @@ -2638,7 +2695,7 @@ public function getCustomerPrefix() } /** - * Returns customer_suffix + * Return customer_suffix * * @return string|null */ @@ -2648,7 +2705,7 @@ public function getCustomerSuffix() } /** - * Returns customer_taxvat + * Return customer_taxvat * * @return string|null */ @@ -2658,7 +2715,7 @@ public function getCustomerTaxvat() } /** - * Returns discount_amount + * Return discount_amount * * @return float|null */ @@ -2668,7 +2725,7 @@ public function getDiscountAmount() } /** - * Returns discount_canceled + * Return discount_canceled * * @return float|null */ @@ -2678,7 +2735,7 @@ public function getDiscountCanceled() } /** - * Returns discount_description + * Return discount_description * * @return string|null */ @@ -2688,7 +2745,7 @@ public function getDiscountDescription() } /** - * Returns discount_invoiced + * Return discount_invoiced * * @return float|null */ @@ -2698,7 +2755,7 @@ public function getDiscountInvoiced() } /** - * Returns discount_refunded + * Return discount_refunded * * @return float|null */ @@ -2708,7 +2765,7 @@ public function getDiscountRefunded() } /** - * Returns edit_increment + * Return edit_increment * * @return int|null */ @@ -2718,7 +2775,7 @@ public function getEditIncrement() } /** - * Returns email_sent + * Return email_sent * * @return int|null */ @@ -2728,7 +2785,7 @@ public function getEmailSent() } /** - * Returns ext_customer_id + * Return ext_customer_id * * @return string|null */ @@ -2738,7 +2795,7 @@ public function getExtCustomerId() } /** - * Returns ext_order_id + * Return ext_order_id * * @return string|null */ @@ -2748,7 +2805,7 @@ public function getExtOrderId() } /** - * Returns forced_shipment_with_invoice + * Return forced_shipment_with_invoice * * @return int|null */ @@ -2758,7 +2815,7 @@ public function getForcedShipmentWithInvoice() } /** - * Returns global_currency_code + * Return global_currency_code * * @return string|null */ @@ -2768,7 +2825,7 @@ public function getGlobalCurrencyCode() } /** - * Returns grand_total + * Return grand_total * * @return float */ @@ -2778,7 +2835,7 @@ public function getGrandTotal() } /** - * Returns discount_tax_compensation_amount + * Return discount_tax_compensation_amount * * @return float|null */ @@ -2788,7 +2845,7 @@ public function getDiscountTaxCompensationAmount() } /** - * Returns discount_tax_compensation_invoiced + * Return discount_tax_compensation_invoiced * * @return float|null */ @@ -2798,7 +2855,7 @@ public function getDiscountTaxCompensationInvoiced() } /** - * Returns discount_tax_compensation_refunded + * Return discount_tax_compensation_refunded * * @return float|null */ @@ -2808,7 +2865,7 @@ public function getDiscountTaxCompensationRefunded() } /** - * Returns hold_before_state + * Return hold_before_state * * @return string|null */ @@ -2818,7 +2875,7 @@ public function getHoldBeforeState() } /** - * Returns hold_before_status + * Return hold_before_status * * @return string|null */ @@ -2828,7 +2885,7 @@ public function getHoldBeforeStatus() } /** - * Returns is_virtual + * Return is_virtual * * @return int|null */ @@ -2838,7 +2895,7 @@ public function getIsVirtual() } /** - * Returns order_currency_code + * Return order_currency_code * * @return string|null */ @@ -2848,7 +2905,7 @@ public function getOrderCurrencyCode() } /** - * Returns original_increment_id + * Return original_increment_id * * @return string|null */ @@ -2858,7 +2915,7 @@ public function getOriginalIncrementId() } /** - * Returns payment_authorization_amount + * Return payment_authorization_amount * * @return float|null */ @@ -2868,7 +2925,7 @@ public function getPaymentAuthorizationAmount() } /** - * Returns payment_auth_expiration + * Return payment_auth_expiration * * @return int|null */ @@ -2878,7 +2935,7 @@ public function getPaymentAuthExpiration() } /** - * Returns protect_code + * Return protect_code * * @return string|null */ @@ -2888,7 +2945,7 @@ public function getProtectCode() } /** - * Returns quote_address_id + * Return quote_address_id * * @return int|null */ @@ -2898,7 +2955,7 @@ public function getQuoteAddressId() } /** - * Returns quote_id + * Return quote_id * * @return int|null */ @@ -2908,7 +2965,7 @@ public function getQuoteId() } /** - * Returns relation_child_id + * Return relation_child_id * * @return string|null */ @@ -2918,7 +2975,7 @@ public function getRelationChildId() } /** - * Returns relation_child_real_id + * Return relation_child_real_id * * @return string|null */ @@ -2928,7 +2985,7 @@ public function getRelationChildRealId() } /** - * Returns relation_parent_id + * Return relation_parent_id * * @return string|null */ @@ -2938,7 +2995,7 @@ public function getRelationParentId() } /** - * Returns relation_parent_real_id + * Return relation_parent_real_id * * @return string|null */ @@ -2948,7 +3005,7 @@ public function getRelationParentRealId() } /** - * Returns remote_ip + * Return remote_ip * * @return string|null */ @@ -2958,7 +3015,7 @@ public function getRemoteIp() } /** - * Returns shipping_amount + * Return shipping_amount * * @return float|null */ @@ -2968,7 +3025,7 @@ public function getShippingAmount() } /** - * Returns shipping_canceled + * Return shipping_canceled * * @return float|null */ @@ -2978,7 +3035,7 @@ public function getShippingCanceled() } /** - * Returns shipping_description + * Return shipping_description * * @return string|null */ @@ -2988,7 +3045,7 @@ public function getShippingDescription() } /** - * Returns shipping_discount_amount + * Return shipping_discount_amount * * @return float|null */ @@ -2998,7 +3055,7 @@ public function getShippingDiscountAmount() } /** - * Returns shipping_discount_tax_compensation_amount + * Return shipping_discount_tax_compensation_amount * * @return float|null */ @@ -3008,7 +3065,7 @@ public function getShippingDiscountTaxCompensationAmount() } /** - * Returns shipping_incl_tax + * Return shipping_incl_tax * * @return float|null */ @@ -3018,7 +3075,7 @@ public function getShippingInclTax() } /** - * Returns shipping_invoiced + * Return shipping_invoiced * * @return float|null */ @@ -3028,7 +3085,7 @@ public function getShippingInvoiced() } /** - * Returns shipping_refunded + * Return shipping_refunded * * @return float|null */ @@ -3038,7 +3095,7 @@ public function getShippingRefunded() } /** - * Returns shipping_tax_amount + * Return shipping_tax_amount * * @return float|null */ @@ -3048,7 +3105,7 @@ public function getShippingTaxAmount() } /** - * Returns shipping_tax_refunded + * Return shipping_tax_refunded * * @return float|null */ @@ -3058,7 +3115,7 @@ public function getShippingTaxRefunded() } /** - * Returns state + * Return state * * @return string|null */ @@ -3068,7 +3125,7 @@ public function getState() } /** - * Returns status + * Return status * * @return string|null */ @@ -3078,7 +3135,7 @@ public function getStatus() } /** - * Returns store_currency_code + * Return store_currency_code * * @return string|null */ @@ -3088,7 +3145,7 @@ public function getStoreCurrencyCode() } /** - * Returns store_id + * Return store_id * * @return int|null */ @@ -3098,7 +3155,7 @@ public function getStoreId() } /** - * Returns store_name + * Return store_name * * @return string|null */ @@ -3108,7 +3165,7 @@ public function getStoreName() } /** - * Returns store_to_base_rate + * Return store_to_base_rate * * @return float|null */ @@ -3118,7 +3175,7 @@ public function getStoreToBaseRate() } /** - * Returns store_to_order_rate + * Return store_to_order_rate * * @return float|null */ @@ -3128,7 +3185,7 @@ public function getStoreToOrderRate() } /** - * Returns subtotal + * Return subtotal * * @return float|null */ @@ -3138,7 +3195,7 @@ public function getSubtotal() } /** - * Returns subtotal_canceled + * Return subtotal_canceled * * @return float|null */ @@ -3148,7 +3205,7 @@ public function getSubtotalCanceled() } /** - * Returns subtotal_incl_tax + * Return subtotal_incl_tax * * @return float|null */ @@ -3158,7 +3215,7 @@ public function getSubtotalInclTax() } /** - * Returns subtotal_invoiced + * Return subtotal_invoiced * * @return float|null */ @@ -3168,7 +3225,7 @@ public function getSubtotalInvoiced() } /** - * Returns subtotal_refunded + * Return subtotal_refunded * * @return float|null */ @@ -3178,7 +3235,7 @@ public function getSubtotalRefunded() } /** - * Returns tax_amount + * Return tax_amount * * @return float|null */ @@ -3188,7 +3245,7 @@ public function getTaxAmount() } /** - * Returns tax_canceled + * Return tax_canceled * * @return float|null */ @@ -3198,7 +3255,7 @@ public function getTaxCanceled() } /** - * Returns tax_invoiced + * Return tax_invoiced * * @return float|null */ @@ -3208,7 +3265,7 @@ public function getTaxInvoiced() } /** - * Returns tax_refunded + * Return tax_refunded * * @return float|null */ @@ -3218,7 +3275,7 @@ public function getTaxRefunded() } /** - * Returns total_canceled + * Return total_canceled * * @return float|null */ @@ -3228,7 +3285,7 @@ public function getTotalCanceled() } /** - * Returns total_invoiced + * Return total_invoiced * * @return float|null */ @@ -3238,7 +3295,7 @@ public function getTotalInvoiced() } /** - * Returns total_item_count + * Return total_item_count * * @return int|null */ @@ -3248,7 +3305,7 @@ public function getTotalItemCount() } /** - * Returns total_offline_refunded + * Return total_offline_refunded * * @return float|null */ @@ -3258,7 +3315,7 @@ public function getTotalOfflineRefunded() } /** - * Returns total_online_refunded + * Return total_online_refunded * * @return float|null */ @@ -3268,7 +3325,7 @@ public function getTotalOnlineRefunded() } /** - * Returns total_paid + * Return total_paid * * @return float|null */ @@ -3278,7 +3335,7 @@ public function getTotalPaid() } /** - * Returns total_qty_ordered + * Return total_qty_ordered * * @return float|null */ @@ -3288,7 +3345,7 @@ public function getTotalQtyOrdered() } /** - * Returns total_refunded + * Return total_refunded * * @return float|null */ @@ -3298,7 +3355,7 @@ public function getTotalRefunded() } /** - * Returns updated_at + * Return updated_at * * @return string|null */ @@ -3308,7 +3365,7 @@ public function getUpdatedAt() } /** - * Returns weight + * Return weight * * @return float|null */ @@ -3318,7 +3375,7 @@ public function getWeight() } /** - * Returns x_forwarded_for + * Return x_forwarded_for * * @return string|null */ @@ -3328,7 +3385,9 @@ public function getXForwardedFor() } /** - * {@inheritdoc} + * Set StatusHistories + * + * @return $this */ public function setStatusHistories(array $statusHistories = null) { @@ -3336,7 +3395,9 @@ public function setStatusHistories(array $statusHistories = null) } /** - * {@inheritdoc} + * Set Status + * + * @return $this */ public function setStatus($status) { @@ -3344,7 +3405,9 @@ public function setStatus($status) } /** - * {@inheritdoc} + * Set CouponCode + * + * @return $this */ public function setCouponCode($code) { @@ -3352,7 +3415,9 @@ public function setCouponCode($code) } /** - * {@inheritdoc} + * Set ProtectCode + * + * @return $this */ public function setProtectCode($code) { @@ -3360,7 +3425,9 @@ public function setProtectCode($code) } /** - * {@inheritdoc} + * Set ShippingDescription + * + * @return $this */ public function setShippingDescription($description) { @@ -3368,7 +3435,9 @@ public function setShippingDescription($description) } /** - * {@inheritdoc} + * Set IsVirtual + * + * @return $this */ public function setIsVirtual($isVirtual) { @@ -3376,7 +3445,9 @@ public function setIsVirtual($isVirtual) } /** - * {@inheritdoc} + * Set StoreId + * + * @return $this */ public function setStoreId($id) { @@ -3384,7 +3455,9 @@ public function setStoreId($id) } /** - * {@inheritdoc} + * Set CustomerId + * + * @return $this */ public function setCustomerId($id) { @@ -3392,7 +3465,9 @@ public function setCustomerId($id) } /** - * {@inheritdoc} + * Set BaseDiscountAmount + * + * @return $this */ public function setBaseDiscountAmount($amount) { @@ -3400,7 +3475,9 @@ public function setBaseDiscountAmount($amount) } /** - * {@inheritdoc} + * Set BaseDiscountCanceled + * + * @return $this */ public function setBaseDiscountCanceled($baseDiscountCanceled) { @@ -3408,7 +3485,9 @@ public function setBaseDiscountCanceled($baseDiscountCanceled) } /** - * {@inheritdoc} + * Set BaseDiscountInvoiced + * + * @return $this */ public function setBaseDiscountInvoiced($baseDiscountInvoiced) { @@ -3416,7 +3495,9 @@ public function setBaseDiscountInvoiced($baseDiscountInvoiced) } /** - * {@inheritdoc} + * Set BaseDiscountRefunded + * + * @return $this */ public function setBaseDiscountRefunded($baseDiscountRefunded) { @@ -3424,7 +3505,9 @@ public function setBaseDiscountRefunded($baseDiscountRefunded) } /** - * {@inheritdoc} + * Set BaseGrandTotal + * + * @return $this */ public function setBaseGrandTotal($amount) { @@ -3432,7 +3515,9 @@ public function setBaseGrandTotal($amount) } /** - * {@inheritdoc} + * Set BaseShippingAmount + * + * @return $this */ public function setBaseShippingAmount($amount) { @@ -3440,7 +3525,9 @@ public function setBaseShippingAmount($amount) } /** - * {@inheritdoc} + * Set BaseShippingCanceled + * + * @return $this */ public function setBaseShippingCanceled($baseShippingCanceled) { @@ -3448,7 +3535,9 @@ public function setBaseShippingCanceled($baseShippingCanceled) } /** - * {@inheritdoc} + * Set BaseShippingInvoiced + * + * @return $this */ public function setBaseShippingInvoiced($baseShippingInvoiced) { @@ -3456,7 +3545,9 @@ public function setBaseShippingInvoiced($baseShippingInvoiced) } /** - * {@inheritdoc} + * Set BaseShippingRefunded + * + * @return $this */ public function setBaseShippingRefunded($baseShippingRefunded) { @@ -3464,7 +3555,9 @@ public function setBaseShippingRefunded($baseShippingRefunded) } /** - * {@inheritdoc} + * Set BaseShippingTaxAmount + * + * @return $this */ public function setBaseShippingTaxAmount($amount) { @@ -3472,7 +3565,9 @@ public function setBaseShippingTaxAmount($amount) } /** - * {@inheritdoc} + * Set BaseShippingTaxRefunded + * + * @return $this */ public function setBaseShippingTaxRefunded($baseShippingTaxRefunded) { @@ -3480,7 +3575,9 @@ public function setBaseShippingTaxRefunded($baseShippingTaxRefunded) } /** - * {@inheritdoc} + * Set BaseSubtotal + * + * @return $this */ public function setBaseSubtotal($amount) { @@ -3488,7 +3585,9 @@ public function setBaseSubtotal($amount) } /** - * {@inheritdoc} + * Set BaseSubtotalCanceled + * + * @return $this */ public function setBaseSubtotalCanceled($baseSubtotalCanceled) { @@ -3496,7 +3595,9 @@ public function setBaseSubtotalCanceled($baseSubtotalCanceled) } /** - * {@inheritdoc} + * Set BaseSubtotalInvoiced + * + * @return $this */ public function setBaseSubtotalInvoiced($baseSubtotalInvoiced) { @@ -3504,7 +3605,9 @@ public function setBaseSubtotalInvoiced($baseSubtotalInvoiced) } /** - * {@inheritdoc} + * Set BaseSubtotalRefunded + * + * @return $this */ public function setBaseSubtotalRefunded($baseSubtotalRefunded) { @@ -3512,7 +3615,9 @@ public function setBaseSubtotalRefunded($baseSubtotalRefunded) } /** - * {@inheritdoc} + * Set BaseTaxAmount + * + * @return $this */ public function setBaseTaxAmount($amount) { @@ -3520,7 +3625,9 @@ public function setBaseTaxAmount($amount) } /** - * {@inheritdoc} + * Set BaseTaxCanceled + * + * @return $this */ public function setBaseTaxCanceled($baseTaxCanceled) { @@ -3528,7 +3635,9 @@ public function setBaseTaxCanceled($baseTaxCanceled) } /** - * {@inheritdoc} + * Set BaseTaxInvoiced + * + * @return $this */ public function setBaseTaxInvoiced($baseTaxInvoiced) { @@ -3536,7 +3645,9 @@ public function setBaseTaxInvoiced($baseTaxInvoiced) } /** - * {@inheritdoc} + * Set BaseTaxRefunded + * + * @return $this */ public function setBaseTaxRefunded($baseTaxRefunded) { @@ -3544,7 +3655,9 @@ public function setBaseTaxRefunded($baseTaxRefunded) } /** - * {@inheritdoc} + * Set BaseToGlobalRate + * + * @return $this */ public function setBaseToGlobalRate($rate) { @@ -3552,7 +3665,9 @@ public function setBaseToGlobalRate($rate) } /** - * {@inheritdoc} + * Set BaseToOrderRate + * + * @return $this */ public function setBaseToOrderRate($rate) { @@ -3560,7 +3675,9 @@ public function setBaseToOrderRate($rate) } /** - * {@inheritdoc} + * Set BaseTotalCanceled + * + * @return $this */ public function setBaseTotalCanceled($baseTotalCanceled) { @@ -3568,7 +3685,9 @@ public function setBaseTotalCanceled($baseTotalCanceled) } /** - * {@inheritdoc} + * Set BaseTotalInvoiced + * + * @return $this */ public function setBaseTotalInvoiced($baseTotalInvoiced) { @@ -3576,7 +3695,9 @@ public function setBaseTotalInvoiced($baseTotalInvoiced) } /** - * {@inheritdoc} + * Set BaseTotalInvoicedCost + * + * @return $this */ public function setBaseTotalInvoicedCost($baseTotalInvoicedCost) { @@ -3584,7 +3705,9 @@ public function setBaseTotalInvoicedCost($baseTotalInvoicedCost) } /** - * {@inheritdoc} + * Set BaseTotalOfflineRefunded + * + * @return $this */ public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded) { @@ -3592,7 +3715,9 @@ public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded) } /** - * {@inheritdoc} + * Set BaseTotalOnlineRefunded + * + * @return $this */ public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded) { @@ -3600,7 +3725,9 @@ public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded) } /** - * {@inheritdoc} + * Set BaseTotalPaid + * + * @return $this */ public function setBaseTotalPaid($baseTotalPaid) { @@ -3608,7 +3735,9 @@ public function setBaseTotalPaid($baseTotalPaid) } /** - * {@inheritdoc} + * Set BaseTotalQtyOrdered + * + * @return $this */ public function setBaseTotalQtyOrdered($baseTotalQtyOrdered) { @@ -3616,7 +3745,9 @@ public function setBaseTotalQtyOrdered($baseTotalQtyOrdered) } /** - * {@inheritdoc} + * Set BaseTotalRefunded + * + * @return $this */ public function setBaseTotalRefunded($baseTotalRefunded) { @@ -3624,7 +3755,9 @@ public function setBaseTotalRefunded($baseTotalRefunded) } /** - * {@inheritdoc} + * Set DiscountAmount + * + * @return $this */ public function setDiscountAmount($amount) { @@ -3632,7 +3765,9 @@ public function setDiscountAmount($amount) } /** - * {@inheritdoc} + * Set DiscountCanceled + * + * @return $this */ public function setDiscountCanceled($discountCanceled) { @@ -3640,7 +3775,9 @@ public function setDiscountCanceled($discountCanceled) } /** - * {@inheritdoc} + * Set DiscountInvoiced + * + * @return $this */ public function setDiscountInvoiced($discountInvoiced) { @@ -3648,7 +3785,9 @@ public function setDiscountInvoiced($discountInvoiced) } /** - * {@inheritdoc} + * Set DiscountRefunded + * + * @return $this */ public function setDiscountRefunded($discountRefunded) { @@ -3656,7 +3795,9 @@ public function setDiscountRefunded($discountRefunded) } /** - * {@inheritdoc} + * Set GrandTotal + * + * @return $this */ public function setGrandTotal($amount) { @@ -3664,7 +3805,9 @@ public function setGrandTotal($amount) } /** - * {@inheritdoc} + * Set ShippingAmount + * + * @return $this */ public function setShippingAmount($amount) { @@ -3672,7 +3815,9 @@ public function setShippingAmount($amount) } /** - * {@inheritdoc} + * Set ShippingCanceled + * + * @return $this */ public function setShippingCanceled($shippingCanceled) { @@ -3680,7 +3825,9 @@ public function setShippingCanceled($shippingCanceled) } /** - * {@inheritdoc} + * Set ShippingInvoiced + * + * @return $this */ public function setShippingInvoiced($shippingInvoiced) { @@ -3688,7 +3835,9 @@ public function setShippingInvoiced($shippingInvoiced) } /** - * {@inheritdoc} + * Set ShippingRefunded + * + * @return $this */ public function setShippingRefunded($shippingRefunded) { @@ -3696,7 +3845,9 @@ public function setShippingRefunded($shippingRefunded) } /** - * {@inheritdoc} + * Set ShippingTaxAmount + * + * @return $this */ public function setShippingTaxAmount($amount) { @@ -3704,7 +3855,9 @@ public function setShippingTaxAmount($amount) } /** - * {@inheritdoc} + * Set ShippingTaxRefunded + * + * @return $this */ public function setShippingTaxRefunded($shippingTaxRefunded) { @@ -3712,7 +3865,9 @@ public function setShippingTaxRefunded($shippingTaxRefunded) } /** - * {@inheritdoc} + * Set StoreToBaseRate + * + * @return $this */ public function setStoreToBaseRate($rate) { @@ -3720,7 +3875,9 @@ public function setStoreToBaseRate($rate) } /** - * {@inheritdoc} + * Set StoreToOrderRate + * + * @return $this */ public function setStoreToOrderRate($rate) { @@ -3728,7 +3885,9 @@ public function setStoreToOrderRate($rate) } /** - * {@inheritdoc} + * Set Subtotal + * + * @return $this */ public function setSubtotal($amount) { @@ -3736,7 +3895,9 @@ public function setSubtotal($amount) } /** - * {@inheritdoc} + * Set SubtotalCanceled + * + * @return $this */ public function setSubtotalCanceled($subtotalCanceled) { @@ -3744,7 +3905,9 @@ public function setSubtotalCanceled($subtotalCanceled) } /** - * {@inheritdoc} + * Set SubtotalInvoiced + * + * @return $this */ public function setSubtotalInvoiced($subtotalInvoiced) { @@ -3752,7 +3915,9 @@ public function setSubtotalInvoiced($subtotalInvoiced) } /** - * {@inheritdoc} + * Set SubtotalRefunded + * + * @return $this */ public function setSubtotalRefunded($subtotalRefunded) { @@ -3760,7 +3925,9 @@ public function setSubtotalRefunded($subtotalRefunded) } /** - * {@inheritdoc} + * Set TaxAmount + * + * @return $this */ public function setTaxAmount($amount) { @@ -3768,7 +3935,9 @@ public function setTaxAmount($amount) } /** - * {@inheritdoc} + * Set TaxCanceled + * + * @return $this */ public function setTaxCanceled($taxCanceled) { @@ -3776,7 +3945,9 @@ public function setTaxCanceled($taxCanceled) } /** - * {@inheritdoc} + * Set TaxInvoiced + * + * @return $this */ public function setTaxInvoiced($taxInvoiced) { @@ -3784,7 +3955,9 @@ public function setTaxInvoiced($taxInvoiced) } /** - * {@inheritdoc} + * Set TaxRefunded + * + * @return $this */ public function setTaxRefunded($taxRefunded) { @@ -3792,7 +3965,9 @@ public function setTaxRefunded($taxRefunded) } /** - * {@inheritdoc} + * Set TotalCanceled + * + * @return $this */ public function setTotalCanceled($totalCanceled) { @@ -3800,7 +3975,9 @@ public function setTotalCanceled($totalCanceled) } /** - * {@inheritdoc} + * Set TotalInvoiced + * + * @return $this */ public function setTotalInvoiced($totalInvoiced) { @@ -3808,7 +3985,9 @@ public function setTotalInvoiced($totalInvoiced) } /** - * {@inheritdoc} + * Set TotalOfflineRefunded + * + * @return $this */ public function setTotalOfflineRefunded($totalOfflineRefunded) { @@ -3816,7 +3995,9 @@ public function setTotalOfflineRefunded($totalOfflineRefunded) } /** - * {@inheritdoc} + * Set TotalOnlineRefunded + * + * @return $this */ public function setTotalOnlineRefunded($totalOnlineRefunded) { @@ -3824,7 +4005,9 @@ public function setTotalOnlineRefunded($totalOnlineRefunded) } /** - * {@inheritdoc} + * Set TotalPaid + * + * @return $this */ public function setTotalPaid($totalPaid) { @@ -3832,7 +4015,9 @@ public function setTotalPaid($totalPaid) } /** - * {@inheritdoc} + * Set TotalQtyOrdered + * + * @return $this */ public function setTotalQtyOrdered($totalQtyOrdered) { @@ -3840,7 +4025,9 @@ public function setTotalQtyOrdered($totalQtyOrdered) } /** - * {@inheritdoc} + * Set TotalRefunded + * + * @return $this */ public function setTotalRefunded($totalRefunded) { @@ -3848,7 +4035,9 @@ public function setTotalRefunded($totalRefunded) } /** - * {@inheritdoc} + * Set CanShipPartially + * + * @return $this */ public function setCanShipPartially($flag) { @@ -3856,7 +4045,9 @@ public function setCanShipPartially($flag) } /** - * {@inheritdoc} + * Set CanShipPartiallyItem + * + * @return $this */ public function setCanShipPartiallyItem($flag) { @@ -3864,7 +4055,9 @@ public function setCanShipPartiallyItem($flag) } /** - * {@inheritdoc} + * Set CustomerIsGuest + * + * @return $this */ public function setCustomerIsGuest($customerIsGuest) { @@ -3872,7 +4065,9 @@ public function setCustomerIsGuest($customerIsGuest) } /** - * {@inheritdoc} + * Set CustomerNoteNotify + * + * @return $this */ public function setCustomerNoteNotify($customerNoteNotify) { @@ -3880,7 +4075,9 @@ public function setCustomerNoteNotify($customerNoteNotify) } /** - * {@inheritdoc} + * Set BillingAddressId + * + * @return $this */ public function setBillingAddressId($id) { @@ -3888,7 +4085,9 @@ public function setBillingAddressId($id) } /** - * {@inheritdoc} + * Set CustomerGroupId + * + * @return $this */ public function setCustomerGroupId($id) { @@ -3896,7 +4095,9 @@ public function setCustomerGroupId($id) } /** - * {@inheritdoc} + * Set EditIncrement + * + * @return $this */ public function setEditIncrement($editIncrement) { @@ -3904,7 +4105,9 @@ public function setEditIncrement($editIncrement) } /** - * {@inheritdoc} + * Set EmailSent + * + * @return $this */ public function setEmailSent($emailSent) { @@ -3912,7 +4115,9 @@ public function setEmailSent($emailSent) } /** - * {@inheritdoc} + * Set ForcedShipmentWithInvoice + * + * @return $this */ public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice) { @@ -3920,7 +4125,9 @@ public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice) } /** - * {@inheritdoc} + * Set PaymentAuthExpiration + * + * @return $this */ public function setPaymentAuthExpiration($paymentAuthExpiration) { @@ -3928,7 +4135,9 @@ public function setPaymentAuthExpiration($paymentAuthExpiration) } /** - * {@inheritdoc} + * Set QuoteAddressId + * + * @return $this */ public function setQuoteAddressId($id) { @@ -3936,7 +4145,9 @@ public function setQuoteAddressId($id) } /** - * {@inheritdoc} + * Set QuoteId + * + * @return $this */ public function setQuoteId($id) { @@ -3944,7 +4155,9 @@ public function setQuoteId($id) } /** - * {@inheritdoc} + * Set AdjustmentNegative + * + * @return $this */ public function setAdjustmentNegative($adjustmentNegative) { @@ -3952,7 +4165,9 @@ public function setAdjustmentNegative($adjustmentNegative) } /** - * {@inheritdoc} + * Set AdjustmentPositive + * + * @return $this */ public function setAdjustmentPositive($adjustmentPositive) { @@ -3960,7 +4175,9 @@ public function setAdjustmentPositive($adjustmentPositive) } /** - * {@inheritdoc} + * Set BaseAdjustmentNegative + * + * @return $this */ public function setBaseAdjustmentNegative($baseAdjustmentNegative) { @@ -3968,7 +4185,9 @@ public function setBaseAdjustmentNegative($baseAdjustmentNegative) } /** - * {@inheritdoc} + * Set BaseAdjustmentPositive + * + * @return $this */ public function setBaseAdjustmentPositive($baseAdjustmentPositive) { @@ -3976,7 +4195,9 @@ public function setBaseAdjustmentPositive($baseAdjustmentPositive) } /** - * {@inheritdoc} + * Set BaseShippingDiscountAmount + * + * @return $this */ public function setBaseShippingDiscountAmount($amount) { @@ -3984,7 +4205,9 @@ public function setBaseShippingDiscountAmount($amount) } /** - * {@inheritdoc} + * Set BaseSubtotalInclTax + * + * @return $this */ public function setBaseSubtotalInclTax($amount) { @@ -3992,7 +4215,9 @@ public function setBaseSubtotalInclTax($amount) } /** - * {@inheritdoc} + * Set BaseTotalDue + * + * @return $this */ public function setBaseTotalDue($baseTotalDue) { @@ -4000,7 +4225,9 @@ public function setBaseTotalDue($baseTotalDue) } /** - * {@inheritdoc} + * Set PaymentAuthorizationAmount + * + * @return $this */ public function setPaymentAuthorizationAmount($amount) { @@ -4008,7 +4235,9 @@ public function setPaymentAuthorizationAmount($amount) } /** - * {@inheritdoc} + * Set ShippingDiscountAmount + * + * @return $this */ public function setShippingDiscountAmount($amount) { @@ -4016,7 +4245,9 @@ public function setShippingDiscountAmount($amount) } /** - * {@inheritdoc} + * Set SubtotalInclTax + * + * @return $this */ public function setSubtotalInclTax($amount) { @@ -4024,7 +4255,9 @@ public function setSubtotalInclTax($amount) } /** - * {@inheritdoc} + * Set TotalDue + * + * @return $this */ public function setTotalDue($totalDue) { @@ -4032,7 +4265,9 @@ public function setTotalDue($totalDue) } /** - * {@inheritdoc} + * Set Weight + * + * @return $this */ public function setWeight($weight) { @@ -4040,7 +4275,9 @@ public function setWeight($weight) } /** - * {@inheritdoc} + * Set CustomerDob + * + * @return $this */ public function setCustomerDob($customerDob) { @@ -4048,7 +4285,9 @@ public function setCustomerDob($customerDob) } /** - * {@inheritdoc} + * Set IncrementId + * + * @return $this */ public function setIncrementId($id) { @@ -4056,7 +4295,9 @@ public function setIncrementId($id) } /** - * {@inheritdoc} + * Set AppliedRuleIds + * + * @return $this */ public function setAppliedRuleIds($appliedRuleIds) { @@ -4064,7 +4305,9 @@ public function setAppliedRuleIds($appliedRuleIds) } /** - * {@inheritdoc} + * Set BaseCurrencyCode + * + * @return $this */ public function setBaseCurrencyCode($code) { @@ -4072,7 +4315,9 @@ public function setBaseCurrencyCode($code) } /** - * {@inheritdoc} + * Set CustomerEmail + * + * @return $this */ public function setCustomerEmail($customerEmail) { @@ -4080,7 +4325,9 @@ public function setCustomerEmail($customerEmail) } /** - * {@inheritdoc} + * Set CustomerFirstname + * + * @return $this */ public function setCustomerFirstname($customerFirstname) { @@ -4088,7 +4335,9 @@ public function setCustomerFirstname($customerFirstname) } /** - * {@inheritdoc} + * Set CustomerLastname + * + * @return $this */ public function setCustomerLastname($customerLastname) { @@ -4096,7 +4345,9 @@ public function setCustomerLastname($customerLastname) } /** - * {@inheritdoc} + * Set CustomerMiddlename + * + * @return $this */ public function setCustomerMiddlename($customerMiddlename) { @@ -4104,7 +4355,9 @@ public function setCustomerMiddlename($customerMiddlename) } /** - * {@inheritdoc} + * Set CustomerPrefix + * + * @return $this */ public function setCustomerPrefix($customerPrefix) { @@ -4112,7 +4365,9 @@ public function setCustomerPrefix($customerPrefix) } /** - * {@inheritdoc} + * Set CustomerSuffix + * + * @return $this */ public function setCustomerSuffix($customerSuffix) { @@ -4120,7 +4375,9 @@ public function setCustomerSuffix($customerSuffix) } /** - * {@inheritdoc} + * Set CustomerTaxvat + * + * @return $this */ public function setCustomerTaxvat($customerTaxvat) { @@ -4128,7 +4385,9 @@ public function setCustomerTaxvat($customerTaxvat) } /** - * {@inheritdoc} + * Set DiscountDescription + * + * @return $this */ public function setDiscountDescription($description) { @@ -4136,7 +4395,9 @@ public function setDiscountDescription($description) } /** - * {@inheritdoc} + * Set ExtCustomerId + * + * @return $this */ public function setExtCustomerId($id) { @@ -4144,7 +4405,9 @@ public function setExtCustomerId($id) } /** - * {@inheritdoc} + * Set ExtOrderId + * + * @return $this */ public function setExtOrderId($id) { @@ -4152,7 +4415,9 @@ public function setExtOrderId($id) } /** - * {@inheritdoc} + * Set GlobalCurrencyCode + * + * @return $this */ public function setGlobalCurrencyCode($code) { @@ -4160,7 +4425,9 @@ public function setGlobalCurrencyCode($code) } /** - * {@inheritdoc} + * Set HoldBeforeState + * + * @return $this */ public function setHoldBeforeState($holdBeforeState) { @@ -4168,7 +4435,9 @@ public function setHoldBeforeState($holdBeforeState) } /** - * {@inheritdoc} + * Set HoldBeforeStatus + * + * @return $this */ public function setHoldBeforeStatus($holdBeforeStatus) { @@ -4176,7 +4445,9 @@ public function setHoldBeforeStatus($holdBeforeStatus) } /** - * {@inheritdoc} + * Set OrderCurrencyCode + * + * @return $this */ public function setOrderCurrencyCode($code) { @@ -4184,7 +4455,9 @@ public function setOrderCurrencyCode($code) } /** - * {@inheritdoc} + * Set OriginalIncrementId + * + * @return $this */ public function setOriginalIncrementId($id) { @@ -4192,7 +4465,9 @@ public function setOriginalIncrementId($id) } /** - * {@inheritdoc} + * Set RelationChildId + * + * @return $this */ public function setRelationChildId($id) { @@ -4200,7 +4475,9 @@ public function setRelationChildId($id) } /** - * {@inheritdoc} + * Set RelationChildRealId + * + * @return $this */ public function setRelationChildRealId($realId) { @@ -4208,7 +4485,9 @@ public function setRelationChildRealId($realId) } /** - * {@inheritdoc} + * Set RelationParentId + * + * @return $this */ public function setRelationParentId($id) { @@ -4216,7 +4495,9 @@ public function setRelationParentId($id) } /** - * {@inheritdoc} + * Set RelationParentRealId + * + * @return $this */ public function setRelationParentRealId($realId) { @@ -4224,7 +4505,9 @@ public function setRelationParentRealId($realId) } /** - * {@inheritdoc} + * Set RemoteIp + * + * @return $this */ public function setRemoteIp($remoteIp) { @@ -4232,7 +4515,9 @@ public function setRemoteIp($remoteIp) } /** - * {@inheritdoc} + * Set StoreCurrencyCode + * + * @return $this */ public function setStoreCurrencyCode($code) { @@ -4240,7 +4525,9 @@ public function setStoreCurrencyCode($code) } /** - * {@inheritdoc} + * Set StoreName + * + * @return $this */ public function setStoreName($storeName) { @@ -4248,7 +4535,9 @@ public function setStoreName($storeName) } /** - * {@inheritdoc} + * Set XForwardedFor + * + * @return $this */ public function setXForwardedFor($xForwardedFor) { @@ -4256,7 +4545,9 @@ public function setXForwardedFor($xForwardedFor) } /** - * {@inheritdoc} + * Set CustomerNote + * + * @return $this */ public function setCustomerNote($customerNote) { @@ -4264,7 +4555,9 @@ public function setCustomerNote($customerNote) } /** - * {@inheritdoc} + * Set UpdatedAt + * + * @return $this */ public function setUpdatedAt($timestamp) { @@ -4272,7 +4565,9 @@ public function setUpdatedAt($timestamp) } /** - * {@inheritdoc} + * Set TotalItemCount + * + * @return $this */ public function setTotalItemCount($totalItemCount) { @@ -4280,7 +4575,9 @@ public function setTotalItemCount($totalItemCount) } /** - * {@inheritdoc} + * Set CustomerGender + * + * @return $this */ public function setCustomerGender($customerGender) { @@ -4288,7 +4585,9 @@ public function setCustomerGender($customerGender) } /** - * {@inheritdoc} + * Set DiscountTaxCompensationAmount + * + * @return $this */ public function setDiscountTaxCompensationAmount($amount) { @@ -4296,7 +4595,9 @@ public function setDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * Set BaseDiscountTaxCompensationAmount + * + * @return $this */ public function setBaseDiscountTaxCompensationAmount($amount) { @@ -4304,7 +4605,9 @@ public function setBaseDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * Set ShippingDiscountTaxCompensationAmount + * + * @return $this */ public function setShippingDiscountTaxCompensationAmount($amount) { @@ -4312,7 +4615,9 @@ public function setShippingDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * Set BaseShippingDiscountTaxCompensationAmnt + * + * @return $this */ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) { @@ -4320,7 +4625,9 @@ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) } /** - * {@inheritdoc} + * Set DiscountTaxCompensationInvoiced + * + * @return $this */ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoiced) { @@ -4328,7 +4635,9 @@ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoi } /** - * {@inheritdoc} + * Set BaseDiscountTaxCompensationInvoiced + * + * @return $this */ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensationInvoiced) { @@ -4339,7 +4648,9 @@ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensat } /** - * {@inheritdoc} + * Set DiscountTaxCompensationRefunded + * + * @return $this */ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefunded) { @@ -4350,7 +4661,9 @@ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefun } /** - * {@inheritdoc} + * Set BaseDiscountTaxCompensationRefunded + * + * @return $this */ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensationRefunded) { @@ -4361,7 +4674,9 @@ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensat } /** - * {@inheritdoc} + * Set ShippingInclTax + * + * @return $this */ public function setShippingInclTax($amount) { @@ -4369,7 +4684,7 @@ public function setShippingInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingInclTax($amount) { From d0b30a999698de2db9e05a89c1abbf4695c5bee1 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 17 Sep 2018 12:05:30 -0500 Subject: [PATCH 0111/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fix static tests --- app/code/Magento/Sales/Model/Order/Item.php | 210 +++++++++--------- .../Sales/Test/Unit/Model/OrderTest.php | 1 + 2 files changed, 106 insertions(+), 105 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index 7fa2f61554563..423d4b8d09d44 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -483,6 +483,7 @@ public function getProductOptions() /** * Get product options array by code. + * * If code is null return all options * * @param string $code @@ -540,8 +541,7 @@ public function getChildrenItems() } /** - * Return checking of what calculation - * type was for this product + * Return checking of what calculation type was for this product * * @return bool */ @@ -581,8 +581,7 @@ public function getForceApplyDiscountToParentItem() } /** - * Return checking of what shipment - * type was for this product + * Return checking of what shipment type was for this product * * @return bool */ @@ -605,9 +604,9 @@ public function isShipSeparately() } /** - * This is Dummy item or not - * if $shipment is true then we checking this for shipping situation if not - * then we checking this for calculation + * This is Dummy item or not. + * + * If $shipment is true then we checking this for shipping situation if not, we checking this for calculation. * * @param bool $shipment * @return bool @@ -652,8 +651,9 @@ public function isDummy($shipment = false) } /** - * Returns formatted buy request - object, holding request received from - * product view page with keys and options for configured product + * Returns formatted buy request. + * + * This object is holding request received from product view page with keys and options for configured product. * * @return \Magento\Framework\DataObject */ @@ -963,7 +963,7 @@ public function getCreatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCreatedAt($createdAt) { @@ -1621,7 +1621,7 @@ public function getWeight() } /** - * {@inheritdoc} + * @inheritdoc */ public function setUpdatedAt($timestamp) { @@ -1629,7 +1629,7 @@ public function setUpdatedAt($timestamp) } /** - * {@inheritdoc} + * @inheritdoc */ public function setItemId($id) { @@ -1637,7 +1637,7 @@ public function setItemId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOrderId($id) { @@ -1645,7 +1645,7 @@ public function setOrderId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setParentItemId($id) { @@ -1653,7 +1653,7 @@ public function setParentItemId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQuoteItemId($id) { @@ -1661,7 +1661,7 @@ public function setQuoteItemId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreId($id) { @@ -1669,7 +1669,7 @@ public function setStoreId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setProductId($id) { @@ -1677,7 +1677,7 @@ public function setProductId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setProductType($productType) { @@ -1685,7 +1685,7 @@ public function setProductType($productType) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeight($weight) { @@ -1693,7 +1693,7 @@ public function setWeight($weight) } /** - * {@inheritdoc} + * @inheritdoc */ public function setIsVirtual($isVirtual) { @@ -1701,7 +1701,7 @@ public function setIsVirtual($isVirtual) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSku($sku) { @@ -1709,7 +1709,7 @@ public function setSku($sku) } /** - * {@inheritdoc} + * @inheritdoc */ public function setName($name) { @@ -1717,7 +1717,7 @@ public function setName($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDescription($description) { @@ -1725,7 +1725,7 @@ public function setDescription($description) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAppliedRuleIds($appliedRuleIds) { @@ -1733,7 +1733,7 @@ public function setAppliedRuleIds($appliedRuleIds) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAdditionalData($additionalData) { @@ -1741,7 +1741,7 @@ public function setAdditionalData($additionalData) } /** - * {@inheritdoc} + * @inheritdoc */ public function setIsQtyDecimal($isQtyDecimal) { @@ -1749,7 +1749,7 @@ public function setIsQtyDecimal($isQtyDecimal) } /** - * {@inheritdoc} + * @inheritdoc */ public function setNoDiscount($noDiscount) { @@ -1757,7 +1757,7 @@ public function setNoDiscount($noDiscount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyBackordered($qtyBackordered) { @@ -1765,7 +1765,7 @@ public function setQtyBackordered($qtyBackordered) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyCanceled($qtyCanceled) { @@ -1773,7 +1773,7 @@ public function setQtyCanceled($qtyCanceled) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyInvoiced($qtyInvoiced) { @@ -1781,7 +1781,7 @@ public function setQtyInvoiced($qtyInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyOrdered($qtyOrdered) { @@ -1789,7 +1789,7 @@ public function setQtyOrdered($qtyOrdered) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyRefunded($qtyRefunded) { @@ -1797,7 +1797,7 @@ public function setQtyRefunded($qtyRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyShipped($qtyShipped) { @@ -1805,7 +1805,7 @@ public function setQtyShipped($qtyShipped) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseCost($baseCost) { @@ -1813,7 +1813,7 @@ public function setBaseCost($baseCost) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrice($price) { @@ -1821,7 +1821,7 @@ public function setPrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBasePrice($price) { @@ -1829,7 +1829,7 @@ public function setBasePrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOriginalPrice($price) { @@ -1837,7 +1837,7 @@ public function setOriginalPrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseOriginalPrice($price) { @@ -1845,7 +1845,7 @@ public function setBaseOriginalPrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxPercent($taxPercent) { @@ -1853,7 +1853,7 @@ public function setTaxPercent($taxPercent) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxAmount($amount) { @@ -1861,7 +1861,7 @@ public function setTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxAmount($amount) { @@ -1869,7 +1869,7 @@ public function setBaseTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxInvoiced($taxInvoiced) { @@ -1877,7 +1877,7 @@ public function setTaxInvoiced($taxInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxInvoiced($baseTaxInvoiced) { @@ -1885,7 +1885,7 @@ public function setBaseTaxInvoiced($baseTaxInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountPercent($discountPercent) { @@ -1893,7 +1893,7 @@ public function setDiscountPercent($discountPercent) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountAmount($amount) { @@ -1901,7 +1901,7 @@ public function setDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountAmount($amount) { @@ -1909,7 +1909,7 @@ public function setBaseDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountInvoiced($discountInvoiced) { @@ -1917,7 +1917,7 @@ public function setDiscountInvoiced($discountInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountInvoiced($baseDiscountInvoiced) { @@ -1925,7 +1925,7 @@ public function setBaseDiscountInvoiced($baseDiscountInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAmountRefunded($amountRefunded) { @@ -1933,7 +1933,7 @@ public function setAmountRefunded($amountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseAmountRefunded($baseAmountRefunded) { @@ -1941,7 +1941,7 @@ public function setBaseAmountRefunded($baseAmountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRowTotal($amount) { @@ -1949,7 +1949,7 @@ public function setRowTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseRowTotal($amount) { @@ -1957,7 +1957,7 @@ public function setBaseRowTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRowInvoiced($rowInvoiced) { @@ -1965,7 +1965,7 @@ public function setRowInvoiced($rowInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseRowInvoiced($baseRowInvoiced) { @@ -1973,7 +1973,7 @@ public function setBaseRowInvoiced($baseRowInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRowWeight($rowWeight) { @@ -1981,7 +1981,7 @@ public function setRowWeight($rowWeight) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxBeforeDiscount($baseTaxBeforeDiscount) { @@ -1989,7 +1989,7 @@ public function setBaseTaxBeforeDiscount($baseTaxBeforeDiscount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxBeforeDiscount($taxBeforeDiscount) { @@ -1997,7 +1997,7 @@ public function setTaxBeforeDiscount($taxBeforeDiscount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setExtOrderItemId($id) { @@ -2005,7 +2005,7 @@ public function setExtOrderItemId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setLockedDoInvoice($flag) { @@ -2013,7 +2013,7 @@ public function setLockedDoInvoice($flag) } /** - * {@inheritdoc} + * @inheritdoc */ public function setLockedDoShip($flag) { @@ -2021,7 +2021,7 @@ public function setLockedDoShip($flag) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPriceInclTax($amount) { @@ -2029,7 +2029,7 @@ public function setPriceInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBasePriceInclTax($amount) { @@ -2037,7 +2037,7 @@ public function setBasePriceInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRowTotalInclTax($amount) { @@ -2045,7 +2045,7 @@ public function setRowTotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseRowTotalInclTax($amount) { @@ -2053,7 +2053,7 @@ public function setBaseRowTotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationAmount($amount) { @@ -2061,7 +2061,7 @@ public function setDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountTaxCompensationAmount($amount) { @@ -2069,7 +2069,7 @@ public function setBaseDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoiced) { @@ -2077,7 +2077,7 @@ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoi } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensationInvoiced) { @@ -2088,7 +2088,7 @@ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensat } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefunded) { @@ -2096,7 +2096,7 @@ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefun } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensationRefunded) { @@ -2107,7 +2107,7 @@ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensat } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxCanceled($taxCanceled) { @@ -2115,7 +2115,7 @@ public function setTaxCanceled($taxCanceled) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationCanceled($discountTaxCompensationCanceled) { @@ -2123,7 +2123,7 @@ public function setDiscountTaxCompensationCanceled($discountTaxCompensationCance } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxRefunded($taxRefunded) { @@ -2131,7 +2131,7 @@ public function setTaxRefunded($taxRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxRefunded($baseTaxRefunded) { @@ -2139,7 +2139,7 @@ public function setBaseTaxRefunded($baseTaxRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountRefunded($discountRefunded) { @@ -2147,7 +2147,7 @@ public function setDiscountRefunded($discountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountRefunded($baseDiscountRefunded) { @@ -2155,7 +2155,7 @@ public function setBaseDiscountRefunded($baseDiscountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwId($id) { @@ -2163,7 +2163,7 @@ public function setGwId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBasePrice($price) { @@ -2171,7 +2171,7 @@ public function setGwBasePrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwPrice($price) { @@ -2179,7 +2179,7 @@ public function setGwPrice($price) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBaseTaxAmount($amount) { @@ -2187,7 +2187,7 @@ public function setGwBaseTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwTaxAmount($amount) { @@ -2195,7 +2195,7 @@ public function setGwTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBasePriceInvoiced($gwBasePriceInvoiced) { @@ -2203,7 +2203,7 @@ public function setGwBasePriceInvoiced($gwBasePriceInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwPriceInvoiced($gwPriceInvoiced) { @@ -2211,7 +2211,7 @@ public function setGwPriceInvoiced($gwPriceInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBaseTaxAmountInvoiced($gwBaseTaxAmountInvoiced) { @@ -2219,7 +2219,7 @@ public function setGwBaseTaxAmountInvoiced($gwBaseTaxAmountInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwTaxAmountInvoiced($gwTaxAmountInvoiced) { @@ -2227,7 +2227,7 @@ public function setGwTaxAmountInvoiced($gwTaxAmountInvoiced) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBasePriceRefunded($gwBasePriceRefunded) { @@ -2235,7 +2235,7 @@ public function setGwBasePriceRefunded($gwBasePriceRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwPriceRefunded($gwPriceRefunded) { @@ -2243,7 +2243,7 @@ public function setGwPriceRefunded($gwPriceRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwBaseTaxAmountRefunded($gwBaseTaxAmountRefunded) { @@ -2251,7 +2251,7 @@ public function setGwBaseTaxAmountRefunded($gwBaseTaxAmountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGwTaxAmountRefunded($gwTaxAmountRefunded) { @@ -2259,7 +2259,7 @@ public function setGwTaxAmountRefunded($gwTaxAmountRefunded) } /** - * {@inheritdoc} + * @inheritdoc */ public function setFreeShipping($freeShipping) { @@ -2267,7 +2267,7 @@ public function setFreeShipping($freeShipping) } /** - * {@inheritdoc} + * @inheritdoc */ public function setQtyReturned($qtyReturned) { @@ -2275,7 +2275,7 @@ public function setQtyReturned($qtyReturned) } /** - * {@inheritdoc} + * @inheritdoc */ public function setEventId($id) { @@ -2283,7 +2283,7 @@ public function setEventId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseWeeeTaxAppliedAmount($amount) { @@ -2291,7 +2291,7 @@ public function setBaseWeeeTaxAppliedAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseWeeeTaxAppliedRowAmnt($amnt) { @@ -2299,7 +2299,7 @@ public function setBaseWeeeTaxAppliedRowAmnt($amnt) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeeeTaxAppliedAmount($amount) { @@ -2307,7 +2307,7 @@ public function setWeeeTaxAppliedAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeeeTaxAppliedRowAmount($amount) { @@ -2315,7 +2315,7 @@ public function setWeeeTaxAppliedRowAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeeeTaxApplied($weeeTaxApplied) { @@ -2323,7 +2323,7 @@ public function setWeeeTaxApplied($weeeTaxApplied) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeeeTaxDisposition($weeeTaxDisposition) { @@ -2331,7 +2331,7 @@ public function setWeeeTaxDisposition($weeeTaxDisposition) } /** - * {@inheritdoc} + * @inheritdoc */ public function setWeeeTaxRowDisposition($weeeTaxRowDisposition) { @@ -2339,7 +2339,7 @@ public function setWeeeTaxRowDisposition($weeeTaxRowDisposition) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseWeeeTaxDisposition($baseWeeeTaxDisposition) { @@ -2347,7 +2347,7 @@ public function setBaseWeeeTaxDisposition($baseWeeeTaxDisposition) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseWeeeTaxRowDisposition($baseWeeeTaxRowDisposition) { @@ -2355,7 +2355,7 @@ public function setBaseWeeeTaxRowDisposition($baseWeeeTaxRowDisposition) } /** - * {@inheritdoc} + * @inheritdoc */ public function getProductOption() { @@ -2363,7 +2363,7 @@ public function getProductOption() } /** - * {@inheritdoc} + * @inheritdoc */ public function setProductOption(\Magento\Catalog\Api\Data\ProductOptionInterface $productOption) { @@ -2371,7 +2371,7 @@ public function setProductOption(\Magento\Catalog\Api\Data\ProductOptionInterfac } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Sales\Api\Data\OrderItemExtensionInterface|null */ @@ -2381,7 +2381,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Sales\Api\Data\OrderItemExtensionInterface $extensionAttributes * @return $this diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php index b75e3adb7402b..873cd64e9c364 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php @@ -18,6 +18,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * @SuppressWarnings(PHPMD.ExcessivePublicCount) */ class OrderTest extends \PHPUnit\Framework\TestCase { From b91f5c81dc994d070aca3e7bb453f08cdc8eb756 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 17 Sep 2018 20:29:49 +0300 Subject: [PATCH 0112/1415] GraphQL-133: Complexity limiter prototype --- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 15e0edb2400ec..b302f4272527a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -13,6 +13,8 @@ use GraphQL\Validator\Rules\QueryComplexity; /** + * QueryComplexityLimiter + * * Sets limits for query complexity. A single GraphQL query can potentially * generate thousands of database operations so, the very complex queries * should be filtered and rejected. @@ -43,6 +45,11 @@ public function __construct( $this->queryComplexity = $queryComplexity; } + /** + * Sets limits for query complexity + * + * @return void + */ public function execute(): void { DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); From cb428a129e74c5e520478995d4e4b1856d1c39ca Mon Sep 17 00:00:00 2001 From: Devagouda Patil <depatil@Devagoudas-MacBook-Pro.local> Date: Mon, 17 Sep 2018 12:51:21 -0500 Subject: [PATCH 0113/1415] MAGETWO-93993: MFTF Flaky Test: StorefrontCustomerCheckoutTestWithMultipleAddressesAndTaxRates - Added fix for the MFTF test --- .../Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index 6ea8d8a167294..13e4e286311b2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -91,9 +91,7 @@ <description value="Should be able to place an order as a customer with multiple addresses and tax rates."/> <testCaseId value="MAGETWO-93109"/> <severity value="AVERAGE"/> - <skip> - <issueId value="MQE-1187" /> - </skip> + <group value="checkout"/> </annotations> <before> <createData entity="SimpleSubCategory" stepKey="simplecategory"/> @@ -183,6 +181,8 @@ <click stepKey="changeShippingAddress" selector="{{CheckoutShippingMethodsSection.shipHereButton}}"/> <waitForElementNotVisible stepKey="waitForShippingMethodLoaderNotVisible" selector="{{CheckoutShippingMethodsSection.shippingMethodLoader}}" time="30"/> + <waitForElementVisible stepKey="waitForShippingMethodRadioToBeVisible" selector="{{CheckoutShippingMethodsSection.firstShippingMethod}}" time="30"/> + <waitForPageLoad stepKey="waitForPageLoad23"/> <click stepKey="selectFirstShippingMethod2" selector="{{CheckoutShippingMethodsSection.firstShippingMethod}}"/> <waitForElement stepKey="waitForShippingMethodSelect2" selector="{{CheckoutShippingMethodsSection.next}}" time="30"/> <click stepKey="clickNextOnShippingMethodLoad2" selector="{{CheckoutShippingMethodsSection.next}}" /> From e1b02178c68dceadb10ca1667ab9ffadd21c3948 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 17 Sep 2018 13:35:37 -0500 Subject: [PATCH 0114/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fix static tests --- app/code/Magento/Sales/Model/Order.php | 542 +++++--------------- app/code/Magento/Sales/Model/Order/Item.php | 184 +++---- 2 files changed, 233 insertions(+), 493 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 47979591a5843..14c6154f0cb0a 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -979,7 +979,7 @@ public function getShippingAddress() } /** - * Set order state + * @inheritdoc * * @param string $state * @return $this @@ -1496,9 +1496,7 @@ public function getPaymentById($paymentId) } /** - * Set payment - * - * @return \Magento\Sales\Api\Data\OrderPaymentInterface|null + * @inheritdoc */ public function setPayment(\Magento\Sales\Api\Data\OrderPaymentInterface $payment = null) { @@ -1581,7 +1579,7 @@ public function getStatusHistoryById($statusId) } /** - * Set the order status history object and the order object to each other. + * @inheritdoc * * Adds the object to the status history collection, which is automatically saved when the order is saved. * See the entity_id attribute backend model. @@ -1632,9 +1630,9 @@ public function getOrderCurrency() /** * Get formatted price value including order currency rate to order website currency * - * @param float $price - * @param bool $addBrackets - * @return string + * @param float $price + * @param bool $addBrackets + * @return string */ public function formatPrice($price, $addBrackets = false) { @@ -1773,7 +1771,7 @@ public function getInvoiceCollection() } /** - * Set order invoices collection + * @inheritdoc * * @param InvoiceCollection $invoices * @return $this @@ -1878,6 +1876,8 @@ public function getRelatedObjects() } /** + * Get customer name + * * @return string */ public function getCustomerName() @@ -2031,9 +2031,7 @@ public function getItems() } /** - * Set Items - * - * @return $this + * @inheritdoc * @codeCoverageIgnore */ public function setItems($items) @@ -2084,7 +2082,7 @@ public function getExtensionAttributes() } /** - * Set ExtensionAttributes + * @inheritdoc * * @param \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes * @return $this @@ -2288,7 +2286,7 @@ public function getBaseShippingInclTax() /** * Return base_shipping_invoiced - + * * @return float|null */ public function getBaseShippingInvoiced() @@ -3385,9 +3383,7 @@ public function getXForwardedFor() } /** - * Set StatusHistories - * - * @return $this + * @inheritdoc */ public function setStatusHistories(array $statusHistories = null) { @@ -3395,9 +3391,7 @@ public function setStatusHistories(array $statusHistories = null) } /** - * Set Status - * - * @return $this + * @inheritdoc */ public function setStatus($status) { @@ -3405,9 +3399,7 @@ public function setStatus($status) } /** - * Set CouponCode - * - * @return $this + * @inheritdoc */ public function setCouponCode($code) { @@ -3415,9 +3407,7 @@ public function setCouponCode($code) } /** - * Set ProtectCode - * - * @return $this + * @inheritdoc */ public function setProtectCode($code) { @@ -3425,9 +3415,7 @@ public function setProtectCode($code) } /** - * Set ShippingDescription - * - * @return $this + * @inheritdoc */ public function setShippingDescription($description) { @@ -3435,9 +3423,7 @@ public function setShippingDescription($description) } /** - * Set IsVirtual - * - * @return $this + * @inheritdoc */ public function setIsVirtual($isVirtual) { @@ -3445,9 +3431,7 @@ public function setIsVirtual($isVirtual) } /** - * Set StoreId - * - * @return $this + * @inheritdoc */ public function setStoreId($id) { @@ -3455,9 +3439,7 @@ public function setStoreId($id) } /** - * Set CustomerId - * - * @return $this + * @inheritdoc */ public function setCustomerId($id) { @@ -3465,9 +3447,7 @@ public function setCustomerId($id) } /** - * Set BaseDiscountAmount - * - * @return $this + * @inheritdoc */ public function setBaseDiscountAmount($amount) { @@ -3475,9 +3455,7 @@ public function setBaseDiscountAmount($amount) } /** - * Set BaseDiscountCanceled - * - * @return $this + * @inheritdoc */ public function setBaseDiscountCanceled($baseDiscountCanceled) { @@ -3485,9 +3463,7 @@ public function setBaseDiscountCanceled($baseDiscountCanceled) } /** - * Set BaseDiscountInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseDiscountInvoiced($baseDiscountInvoiced) { @@ -3495,9 +3471,7 @@ public function setBaseDiscountInvoiced($baseDiscountInvoiced) } /** - * Set BaseDiscountRefunded - * - * @return $this + * @inheritdoc */ public function setBaseDiscountRefunded($baseDiscountRefunded) { @@ -3505,9 +3479,7 @@ public function setBaseDiscountRefunded($baseDiscountRefunded) } /** - * Set BaseGrandTotal - * - * @return $this + * @inheritdoc */ public function setBaseGrandTotal($amount) { @@ -3515,9 +3487,7 @@ public function setBaseGrandTotal($amount) } /** - * Set BaseShippingAmount - * - * @return $this + * @inheritdoc */ public function setBaseShippingAmount($amount) { @@ -3525,9 +3495,7 @@ public function setBaseShippingAmount($amount) } /** - * Set BaseShippingCanceled - * - * @return $this + * @inheritdoc */ public function setBaseShippingCanceled($baseShippingCanceled) { @@ -3535,9 +3503,7 @@ public function setBaseShippingCanceled($baseShippingCanceled) } /** - * Set BaseShippingInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseShippingInvoiced($baseShippingInvoiced) { @@ -3545,9 +3511,7 @@ public function setBaseShippingInvoiced($baseShippingInvoiced) } /** - * Set BaseShippingRefunded - * - * @return $this + * @inheritdoc */ public function setBaseShippingRefunded($baseShippingRefunded) { @@ -3555,9 +3519,7 @@ public function setBaseShippingRefunded($baseShippingRefunded) } /** - * Set BaseShippingTaxAmount - * - * @return $this + * @inheritdoc */ public function setBaseShippingTaxAmount($amount) { @@ -3565,9 +3527,7 @@ public function setBaseShippingTaxAmount($amount) } /** - * Set BaseShippingTaxRefunded - * - * @return $this + * @inheritdoc */ public function setBaseShippingTaxRefunded($baseShippingTaxRefunded) { @@ -3575,9 +3535,7 @@ public function setBaseShippingTaxRefunded($baseShippingTaxRefunded) } /** - * Set BaseSubtotal - * - * @return $this + * @inheritdoc */ public function setBaseSubtotal($amount) { @@ -3585,9 +3543,7 @@ public function setBaseSubtotal($amount) } /** - * Set BaseSubtotalCanceled - * - * @return $this + * @inheritdoc */ public function setBaseSubtotalCanceled($baseSubtotalCanceled) { @@ -3595,9 +3551,7 @@ public function setBaseSubtotalCanceled($baseSubtotalCanceled) } /** - * Set BaseSubtotalInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseSubtotalInvoiced($baseSubtotalInvoiced) { @@ -3605,9 +3559,7 @@ public function setBaseSubtotalInvoiced($baseSubtotalInvoiced) } /** - * Set BaseSubtotalRefunded - * - * @return $this + * @inheritdoc */ public function setBaseSubtotalRefunded($baseSubtotalRefunded) { @@ -3615,9 +3567,7 @@ public function setBaseSubtotalRefunded($baseSubtotalRefunded) } /** - * Set BaseTaxAmount - * - * @return $this + * @inheritdoc */ public function setBaseTaxAmount($amount) { @@ -3625,9 +3575,7 @@ public function setBaseTaxAmount($amount) } /** - * Set BaseTaxCanceled - * - * @return $this + * @inheritdoc */ public function setBaseTaxCanceled($baseTaxCanceled) { @@ -3635,9 +3583,7 @@ public function setBaseTaxCanceled($baseTaxCanceled) } /** - * Set BaseTaxInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseTaxInvoiced($baseTaxInvoiced) { @@ -3645,9 +3591,7 @@ public function setBaseTaxInvoiced($baseTaxInvoiced) } /** - * Set BaseTaxRefunded - * - * @return $this + * @inheritdoc */ public function setBaseTaxRefunded($baseTaxRefunded) { @@ -3655,9 +3599,7 @@ public function setBaseTaxRefunded($baseTaxRefunded) } /** - * Set BaseToGlobalRate - * - * @return $this + * @inheritdoc */ public function setBaseToGlobalRate($rate) { @@ -3665,9 +3607,7 @@ public function setBaseToGlobalRate($rate) } /** - * Set BaseToOrderRate - * - * @return $this + * @inheritdoc */ public function setBaseToOrderRate($rate) { @@ -3675,9 +3615,7 @@ public function setBaseToOrderRate($rate) } /** - * Set BaseTotalCanceled - * - * @return $this + * @inheritdoc */ public function setBaseTotalCanceled($baseTotalCanceled) { @@ -3685,9 +3623,7 @@ public function setBaseTotalCanceled($baseTotalCanceled) } /** - * Set BaseTotalInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseTotalInvoiced($baseTotalInvoiced) { @@ -3695,9 +3631,7 @@ public function setBaseTotalInvoiced($baseTotalInvoiced) } /** - * Set BaseTotalInvoicedCost - * - * @return $this + * @inheritdoc */ public function setBaseTotalInvoicedCost($baseTotalInvoicedCost) { @@ -3705,9 +3639,7 @@ public function setBaseTotalInvoicedCost($baseTotalInvoicedCost) } /** - * Set BaseTotalOfflineRefunded - * - * @return $this + * @inheritdoc */ public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded) { @@ -3715,9 +3647,7 @@ public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded) } /** - * Set BaseTotalOnlineRefunded - * - * @return $this + * @inheritdoc */ public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded) { @@ -3725,9 +3655,7 @@ public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded) } /** - * Set BaseTotalPaid - * - * @return $this + * @inheritdoc */ public function setBaseTotalPaid($baseTotalPaid) { @@ -3735,9 +3663,7 @@ public function setBaseTotalPaid($baseTotalPaid) } /** - * Set BaseTotalQtyOrdered - * - * @return $this + * @inheritdoc */ public function setBaseTotalQtyOrdered($baseTotalQtyOrdered) { @@ -3745,9 +3671,7 @@ public function setBaseTotalQtyOrdered($baseTotalQtyOrdered) } /** - * Set BaseTotalRefunded - * - * @return $this + * @inheritdoc */ public function setBaseTotalRefunded($baseTotalRefunded) { @@ -3755,9 +3679,7 @@ public function setBaseTotalRefunded($baseTotalRefunded) } /** - * Set DiscountAmount - * - * @return $this + * @inheritdoc */ public function setDiscountAmount($amount) { @@ -3765,9 +3687,7 @@ public function setDiscountAmount($amount) } /** - * Set DiscountCanceled - * - * @return $this + * @inheritdoc */ public function setDiscountCanceled($discountCanceled) { @@ -3775,9 +3695,7 @@ public function setDiscountCanceled($discountCanceled) } /** - * Set DiscountInvoiced - * - * @return $this + * @inheritdoc */ public function setDiscountInvoiced($discountInvoiced) { @@ -3785,9 +3703,7 @@ public function setDiscountInvoiced($discountInvoiced) } /** - * Set DiscountRefunded - * - * @return $this + * @inheritdoc */ public function setDiscountRefunded($discountRefunded) { @@ -3795,9 +3711,7 @@ public function setDiscountRefunded($discountRefunded) } /** - * Set GrandTotal - * - * @return $this + * @inheritdoc */ public function setGrandTotal($amount) { @@ -3805,9 +3719,7 @@ public function setGrandTotal($amount) } /** - * Set ShippingAmount - * - * @return $this + * @inheritdoc */ public function setShippingAmount($amount) { @@ -3815,9 +3727,7 @@ public function setShippingAmount($amount) } /** - * Set ShippingCanceled - * - * @return $this + * @inheritdoc */ public function setShippingCanceled($shippingCanceled) { @@ -3825,9 +3735,7 @@ public function setShippingCanceled($shippingCanceled) } /** - * Set ShippingInvoiced - * - * @return $this + * @inheritdoc */ public function setShippingInvoiced($shippingInvoiced) { @@ -3835,9 +3743,7 @@ public function setShippingInvoiced($shippingInvoiced) } /** - * Set ShippingRefunded - * - * @return $this + * @inheritdoc */ public function setShippingRefunded($shippingRefunded) { @@ -3845,9 +3751,7 @@ public function setShippingRefunded($shippingRefunded) } /** - * Set ShippingTaxAmount - * - * @return $this + * @inheritdoc */ public function setShippingTaxAmount($amount) { @@ -3855,9 +3759,7 @@ public function setShippingTaxAmount($amount) } /** - * Set ShippingTaxRefunded - * - * @return $this + * @inheritdoc */ public function setShippingTaxRefunded($shippingTaxRefunded) { @@ -3865,9 +3767,7 @@ public function setShippingTaxRefunded($shippingTaxRefunded) } /** - * Set StoreToBaseRate - * - * @return $this + * @inheritdoc */ public function setStoreToBaseRate($rate) { @@ -3875,9 +3775,7 @@ public function setStoreToBaseRate($rate) } /** - * Set StoreToOrderRate - * - * @return $this + * @inheritdoc */ public function setStoreToOrderRate($rate) { @@ -3885,9 +3783,7 @@ public function setStoreToOrderRate($rate) } /** - * Set Subtotal - * - * @return $this + * @inheritdoc */ public function setSubtotal($amount) { @@ -3895,9 +3791,7 @@ public function setSubtotal($amount) } /** - * Set SubtotalCanceled - * - * @return $this + * @inheritdoc */ public function setSubtotalCanceled($subtotalCanceled) { @@ -3905,9 +3799,7 @@ public function setSubtotalCanceled($subtotalCanceled) } /** - * Set SubtotalInvoiced - * - * @return $this + * @inheritdoc */ public function setSubtotalInvoiced($subtotalInvoiced) { @@ -3915,9 +3807,7 @@ public function setSubtotalInvoiced($subtotalInvoiced) } /** - * Set SubtotalRefunded - * - * @return $this + * @inheritdoc */ public function setSubtotalRefunded($subtotalRefunded) { @@ -3925,9 +3815,7 @@ public function setSubtotalRefunded($subtotalRefunded) } /** - * Set TaxAmount - * - * @return $this + * @inheritdoc */ public function setTaxAmount($amount) { @@ -3935,9 +3823,7 @@ public function setTaxAmount($amount) } /** - * Set TaxCanceled - * - * @return $this + * @inheritdoc */ public function setTaxCanceled($taxCanceled) { @@ -3945,9 +3831,7 @@ public function setTaxCanceled($taxCanceled) } /** - * Set TaxInvoiced - * - * @return $this + * @inheritdoc */ public function setTaxInvoiced($taxInvoiced) { @@ -3955,9 +3839,7 @@ public function setTaxInvoiced($taxInvoiced) } /** - * Set TaxRefunded - * - * @return $this + * @inheritdoc */ public function setTaxRefunded($taxRefunded) { @@ -3965,9 +3847,7 @@ public function setTaxRefunded($taxRefunded) } /** - * Set TotalCanceled - * - * @return $this + * @inheritdoc */ public function setTotalCanceled($totalCanceled) { @@ -3975,9 +3855,7 @@ public function setTotalCanceled($totalCanceled) } /** - * Set TotalInvoiced - * - * @return $this + * @inheritdoc */ public function setTotalInvoiced($totalInvoiced) { @@ -3985,9 +3863,7 @@ public function setTotalInvoiced($totalInvoiced) } /** - * Set TotalOfflineRefunded - * - * @return $this + * @inheritdoc */ public function setTotalOfflineRefunded($totalOfflineRefunded) { @@ -3995,9 +3871,7 @@ public function setTotalOfflineRefunded($totalOfflineRefunded) } /** - * Set TotalOnlineRefunded - * - * @return $this + * @inheritdoc */ public function setTotalOnlineRefunded($totalOnlineRefunded) { @@ -4005,9 +3879,7 @@ public function setTotalOnlineRefunded($totalOnlineRefunded) } /** - * Set TotalPaid - * - * @return $this + * @inheritdoc */ public function setTotalPaid($totalPaid) { @@ -4015,9 +3887,7 @@ public function setTotalPaid($totalPaid) } /** - * Set TotalQtyOrdered - * - * @return $this + * @inheritdoc */ public function setTotalQtyOrdered($totalQtyOrdered) { @@ -4025,9 +3895,7 @@ public function setTotalQtyOrdered($totalQtyOrdered) } /** - * Set TotalRefunded - * - * @return $this + * @inheritdoc */ public function setTotalRefunded($totalRefunded) { @@ -4035,9 +3903,7 @@ public function setTotalRefunded($totalRefunded) } /** - * Set CanShipPartially - * - * @return $this + * @inheritdoc */ public function setCanShipPartially($flag) { @@ -4045,9 +3911,7 @@ public function setCanShipPartially($flag) } /** - * Set CanShipPartiallyItem - * - * @return $this + * @inheritdoc */ public function setCanShipPartiallyItem($flag) { @@ -4055,9 +3919,7 @@ public function setCanShipPartiallyItem($flag) } /** - * Set CustomerIsGuest - * - * @return $this + * @inheritdoc */ public function setCustomerIsGuest($customerIsGuest) { @@ -4065,9 +3927,7 @@ public function setCustomerIsGuest($customerIsGuest) } /** - * Set CustomerNoteNotify - * - * @return $this + * @inheritdoc */ public function setCustomerNoteNotify($customerNoteNotify) { @@ -4075,9 +3935,7 @@ public function setCustomerNoteNotify($customerNoteNotify) } /** - * Set BillingAddressId - * - * @return $this + * @inheritdoc */ public function setBillingAddressId($id) { @@ -4085,9 +3943,7 @@ public function setBillingAddressId($id) } /** - * Set CustomerGroupId - * - * @return $this + * @inheritdoc */ public function setCustomerGroupId($id) { @@ -4095,9 +3951,7 @@ public function setCustomerGroupId($id) } /** - * Set EditIncrement - * - * @return $this + * @inheritdoc */ public function setEditIncrement($editIncrement) { @@ -4105,9 +3959,7 @@ public function setEditIncrement($editIncrement) } /** - * Set EmailSent - * - * @return $this + * @inheritdoc */ public function setEmailSent($emailSent) { @@ -4115,9 +3967,7 @@ public function setEmailSent($emailSent) } /** - * Set ForcedShipmentWithInvoice - * - * @return $this + * @inheritdoc */ public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice) { @@ -4125,9 +3975,7 @@ public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice) } /** - * Set PaymentAuthExpiration - * - * @return $this + * @inheritdoc */ public function setPaymentAuthExpiration($paymentAuthExpiration) { @@ -4135,9 +3983,7 @@ public function setPaymentAuthExpiration($paymentAuthExpiration) } /** - * Set QuoteAddressId - * - * @return $this + * @inheritdoc */ public function setQuoteAddressId($id) { @@ -4145,9 +3991,7 @@ public function setQuoteAddressId($id) } /** - * Set QuoteId - * - * @return $this + * @inheritdoc */ public function setQuoteId($id) { @@ -4155,9 +3999,7 @@ public function setQuoteId($id) } /** - * Set AdjustmentNegative - * - * @return $this + * @inheritdoc */ public function setAdjustmentNegative($adjustmentNegative) { @@ -4165,9 +4007,7 @@ public function setAdjustmentNegative($adjustmentNegative) } /** - * Set AdjustmentPositive - * - * @return $this + * @inheritdoc */ public function setAdjustmentPositive($adjustmentPositive) { @@ -4175,9 +4015,7 @@ public function setAdjustmentPositive($adjustmentPositive) } /** - * Set BaseAdjustmentNegative - * - * @return $this + * @inheritdoc */ public function setBaseAdjustmentNegative($baseAdjustmentNegative) { @@ -4185,9 +4023,7 @@ public function setBaseAdjustmentNegative($baseAdjustmentNegative) } /** - * Set BaseAdjustmentPositive - * - * @return $this + * @inheritdoc */ public function setBaseAdjustmentPositive($baseAdjustmentPositive) { @@ -4195,9 +4031,7 @@ public function setBaseAdjustmentPositive($baseAdjustmentPositive) } /** - * Set BaseShippingDiscountAmount - * - * @return $this + * @inheritdoc */ public function setBaseShippingDiscountAmount($amount) { @@ -4205,9 +4039,7 @@ public function setBaseShippingDiscountAmount($amount) } /** - * Set BaseSubtotalInclTax - * - * @return $this + * @inheritdoc */ public function setBaseSubtotalInclTax($amount) { @@ -4215,9 +4047,7 @@ public function setBaseSubtotalInclTax($amount) } /** - * Set BaseTotalDue - * - * @return $this + * @inheritdoc */ public function setBaseTotalDue($baseTotalDue) { @@ -4225,9 +4055,7 @@ public function setBaseTotalDue($baseTotalDue) } /** - * Set PaymentAuthorizationAmount - * - * @return $this + * @inheritdoc */ public function setPaymentAuthorizationAmount($amount) { @@ -4235,9 +4063,7 @@ public function setPaymentAuthorizationAmount($amount) } /** - * Set ShippingDiscountAmount - * - * @return $this + * @inheritdoc */ public function setShippingDiscountAmount($amount) { @@ -4245,9 +4071,7 @@ public function setShippingDiscountAmount($amount) } /** - * Set SubtotalInclTax - * - * @return $this + * @inheritdoc */ public function setSubtotalInclTax($amount) { @@ -4255,9 +4079,7 @@ public function setSubtotalInclTax($amount) } /** - * Set TotalDue - * - * @return $this + * @inheritdoc */ public function setTotalDue($totalDue) { @@ -4265,9 +4087,7 @@ public function setTotalDue($totalDue) } /** - * Set Weight - * - * @return $this + * @inheritdoc */ public function setWeight($weight) { @@ -4275,9 +4095,7 @@ public function setWeight($weight) } /** - * Set CustomerDob - * - * @return $this + * @inheritdoc */ public function setCustomerDob($customerDob) { @@ -4285,9 +4103,7 @@ public function setCustomerDob($customerDob) } /** - * Set IncrementId - * - * @return $this + * @inheritdoc */ public function setIncrementId($id) { @@ -4295,9 +4111,7 @@ public function setIncrementId($id) } /** - * Set AppliedRuleIds - * - * @return $this + * @inheritdoc */ public function setAppliedRuleIds($appliedRuleIds) { @@ -4305,9 +4119,7 @@ public function setAppliedRuleIds($appliedRuleIds) } /** - * Set BaseCurrencyCode - * - * @return $this + * @inheritdoc */ public function setBaseCurrencyCode($code) { @@ -4315,9 +4127,7 @@ public function setBaseCurrencyCode($code) } /** - * Set CustomerEmail - * - * @return $this + * @inheritdoc */ public function setCustomerEmail($customerEmail) { @@ -4325,9 +4135,7 @@ public function setCustomerEmail($customerEmail) } /** - * Set CustomerFirstname - * - * @return $this + * @inheritdoc */ public function setCustomerFirstname($customerFirstname) { @@ -4335,9 +4143,7 @@ public function setCustomerFirstname($customerFirstname) } /** - * Set CustomerLastname - * - * @return $this + * @inheritdoc */ public function setCustomerLastname($customerLastname) { @@ -4345,9 +4151,7 @@ public function setCustomerLastname($customerLastname) } /** - * Set CustomerMiddlename - * - * @return $this + * @inheritdoc */ public function setCustomerMiddlename($customerMiddlename) { @@ -4355,9 +4159,7 @@ public function setCustomerMiddlename($customerMiddlename) } /** - * Set CustomerPrefix - * - * @return $this + * @inheritdoc */ public function setCustomerPrefix($customerPrefix) { @@ -4365,9 +4167,7 @@ public function setCustomerPrefix($customerPrefix) } /** - * Set CustomerSuffix - * - * @return $this + * @inheritdoc */ public function setCustomerSuffix($customerSuffix) { @@ -4375,9 +4175,7 @@ public function setCustomerSuffix($customerSuffix) } /** - * Set CustomerTaxvat - * - * @return $this + * @inheritdoc */ public function setCustomerTaxvat($customerTaxvat) { @@ -4385,9 +4183,7 @@ public function setCustomerTaxvat($customerTaxvat) } /** - * Set DiscountDescription - * - * @return $this + * @inheritdoc */ public function setDiscountDescription($description) { @@ -4395,9 +4191,7 @@ public function setDiscountDescription($description) } /** - * Set ExtCustomerId - * - * @return $this + * @inheritdoc */ public function setExtCustomerId($id) { @@ -4405,9 +4199,7 @@ public function setExtCustomerId($id) } /** - * Set ExtOrderId - * - * @return $this + * @inheritdoc */ public function setExtOrderId($id) { @@ -4415,9 +4207,7 @@ public function setExtOrderId($id) } /** - * Set GlobalCurrencyCode - * - * @return $this + * @inheritdoc */ public function setGlobalCurrencyCode($code) { @@ -4425,9 +4215,7 @@ public function setGlobalCurrencyCode($code) } /** - * Set HoldBeforeState - * - * @return $this + * @inheritdoc */ public function setHoldBeforeState($holdBeforeState) { @@ -4435,9 +4223,7 @@ public function setHoldBeforeState($holdBeforeState) } /** - * Set HoldBeforeStatus - * - * @return $this + * @inheritdoc */ public function setHoldBeforeStatus($holdBeforeStatus) { @@ -4445,9 +4231,7 @@ public function setHoldBeforeStatus($holdBeforeStatus) } /** - * Set OrderCurrencyCode - * - * @return $this + * @inheritdoc */ public function setOrderCurrencyCode($code) { @@ -4455,9 +4239,7 @@ public function setOrderCurrencyCode($code) } /** - * Set OriginalIncrementId - * - * @return $this + * @inheritdoc */ public function setOriginalIncrementId($id) { @@ -4465,9 +4247,7 @@ public function setOriginalIncrementId($id) } /** - * Set RelationChildId - * - * @return $this + * @inheritdoc */ public function setRelationChildId($id) { @@ -4475,9 +4255,7 @@ public function setRelationChildId($id) } /** - * Set RelationChildRealId - * - * @return $this + * @inheritdoc */ public function setRelationChildRealId($realId) { @@ -4485,9 +4263,7 @@ public function setRelationChildRealId($realId) } /** - * Set RelationParentId - * - * @return $this + * @inheritdoc */ public function setRelationParentId($id) { @@ -4495,9 +4271,7 @@ public function setRelationParentId($id) } /** - * Set RelationParentRealId - * - * @return $this + * @inheritdoc */ public function setRelationParentRealId($realId) { @@ -4505,9 +4279,7 @@ public function setRelationParentRealId($realId) } /** - * Set RemoteIp - * - * @return $this + * @inheritdoc */ public function setRemoteIp($remoteIp) { @@ -4515,9 +4287,7 @@ public function setRemoteIp($remoteIp) } /** - * Set StoreCurrencyCode - * - * @return $this + * @inheritdoc */ public function setStoreCurrencyCode($code) { @@ -4525,9 +4295,7 @@ public function setStoreCurrencyCode($code) } /** - * Set StoreName - * - * @return $this + * @inheritdoc */ public function setStoreName($storeName) { @@ -4535,9 +4303,7 @@ public function setStoreName($storeName) } /** - * Set XForwardedFor - * - * @return $this + * @inheritdoc */ public function setXForwardedFor($xForwardedFor) { @@ -4545,9 +4311,7 @@ public function setXForwardedFor($xForwardedFor) } /** - * Set CustomerNote - * - * @return $this + * @inheritdoc */ public function setCustomerNote($customerNote) { @@ -4555,9 +4319,7 @@ public function setCustomerNote($customerNote) } /** - * Set UpdatedAt - * - * @return $this + * @inheritdoc */ public function setUpdatedAt($timestamp) { @@ -4565,9 +4327,7 @@ public function setUpdatedAt($timestamp) } /** - * Set TotalItemCount - * - * @return $this + * @inheritdoc */ public function setTotalItemCount($totalItemCount) { @@ -4575,9 +4335,7 @@ public function setTotalItemCount($totalItemCount) } /** - * Set CustomerGender - * - * @return $this + * @inheritdoc */ public function setCustomerGender($customerGender) { @@ -4585,9 +4343,7 @@ public function setCustomerGender($customerGender) } /** - * Set DiscountTaxCompensationAmount - * - * @return $this + * @inheritdoc */ public function setDiscountTaxCompensationAmount($amount) { @@ -4595,9 +4351,7 @@ public function setDiscountTaxCompensationAmount($amount) } /** - * Set BaseDiscountTaxCompensationAmount - * - * @return $this + * @inheritdoc */ public function setBaseDiscountTaxCompensationAmount($amount) { @@ -4605,9 +4359,7 @@ public function setBaseDiscountTaxCompensationAmount($amount) } /** - * Set ShippingDiscountTaxCompensationAmount - * - * @return $this + * @inheritdoc */ public function setShippingDiscountTaxCompensationAmount($amount) { @@ -4615,9 +4367,7 @@ public function setShippingDiscountTaxCompensationAmount($amount) } /** - * Set BaseShippingDiscountTaxCompensationAmnt - * - * @return $this + * @inheritdoc */ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) { @@ -4625,9 +4375,7 @@ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) } /** - * Set DiscountTaxCompensationInvoiced - * - * @return $this + * @inheritdoc */ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoiced) { @@ -4635,9 +4383,7 @@ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoi } /** - * Set BaseDiscountTaxCompensationInvoiced - * - * @return $this + * @inheritdoc */ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensationInvoiced) { @@ -4648,9 +4394,7 @@ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensat } /** - * Set DiscountTaxCompensationRefunded - * - * @return $this + * @inheritdoc */ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefunded) { @@ -4661,9 +4405,7 @@ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefun } /** - * Set BaseDiscountTaxCompensationRefunded - * - * @return $this + * @inheritdoc */ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensationRefunded) { @@ -4674,9 +4416,7 @@ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensat } /** - * Set ShippingInclTax - * - * @return $this + * @inheritdoc */ public function setShippingInclTax($amount) { diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index 423d4b8d09d44..cc8bb7aae780c 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -651,7 +651,7 @@ public function isDummy($shipment = false) } /** - * Returns formatted buy request. + * Return formatted buy request. * * This object is holding request received from product view page with keys and options for configured product. * @@ -703,7 +703,7 @@ public function getStore() //@codeCoverageIgnoreStart /** - * Returns additional_data + * Return additional_data * * @return string|null */ @@ -713,7 +713,7 @@ public function getAdditionalData() } /** - * Returns amount_refunded + * Return amount_refunded * * @return float|null */ @@ -723,7 +723,7 @@ public function getAmountRefunded() } /** - * Returns applied_rule_ids + * Return applied_rule_ids * * @return string|null */ @@ -733,7 +733,7 @@ public function getAppliedRuleIds() } /** - * Returns base_amount_refunded + * Return base_amount_refunded * * @return float|null */ @@ -743,7 +743,7 @@ public function getBaseAmountRefunded() } /** - * Returns base_cost + * Return base_cost * * @return float|null */ @@ -753,7 +753,7 @@ public function getBaseCost() } /** - * Returns base_discount_amount + * Return base_discount_amount * * @return float|null */ @@ -763,7 +763,7 @@ public function getBaseDiscountAmount() } /** - * Returns base_discount_invoiced + * Return base_discount_invoiced * * @return float|null */ @@ -773,7 +773,7 @@ public function getBaseDiscountInvoiced() } /** - * Returns base_discount_refunded + * Return base_discount_refunded * * @return float|null */ @@ -783,7 +783,7 @@ public function getBaseDiscountRefunded() } /** - * Returns base_discount_tax_compensation_amount + * Return base_discount_tax_compensation_amount * * @return float|null */ @@ -793,7 +793,7 @@ public function getBaseDiscountTaxCompensationAmount() } /** - * Returns base_discount_tax_compensation_invoiced + * Return base_discount_tax_compensation_invoiced * * @return float|null */ @@ -803,7 +803,7 @@ public function getBaseDiscountTaxCompensationInvoiced() } /** - * Returns base_discount_tax_compensation_refunded + * Return base_discount_tax_compensation_refunded * * @return float|null */ @@ -813,7 +813,7 @@ public function getBaseDiscountTaxCompensationRefunded() } /** - * Returns base_original_price + * Return base_original_price * * @return float|null */ @@ -823,7 +823,7 @@ public function getBaseOriginalPrice() } /** - * Returns base_price + * Return base_price * * @return float|null */ @@ -833,7 +833,7 @@ public function getBasePrice() } /** - * Returns base_price_incl_tax + * Return base_price_incl_tax * * @return float|null */ @@ -843,7 +843,7 @@ public function getBasePriceInclTax() } /** - * Returns base_row_invoiced + * Return base_row_invoiced * * @return float|null */ @@ -853,7 +853,7 @@ public function getBaseRowInvoiced() } /** - * Returns base_row_total + * Return base_row_total * * @return float|null */ @@ -863,7 +863,7 @@ public function getBaseRowTotal() } /** - * Returns base_row_total_incl_tax + * Return base_row_total_incl_tax * * @return float|null */ @@ -873,7 +873,7 @@ public function getBaseRowTotalInclTax() } /** - * Returns base_tax_amount + * Return base_tax_amount * * @return float|null */ @@ -883,7 +883,7 @@ public function getBaseTaxAmount() } /** - * Returns base_tax_before_discount + * Return base_tax_before_discount * * @return float|null */ @@ -893,7 +893,7 @@ public function getBaseTaxBeforeDiscount() } /** - * Returns base_tax_invoiced + * Return base_tax_invoiced * * @return float|null */ @@ -903,7 +903,7 @@ public function getBaseTaxInvoiced() } /** - * Returns base_tax_refunded + * Return base_tax_refunded * * @return float|null */ @@ -913,7 +913,7 @@ public function getBaseTaxRefunded() } /** - * Returns base_weee_tax_applied_amount + * Return base_weee_tax_applied_amount * * @return float|null */ @@ -923,7 +923,7 @@ public function getBaseWeeeTaxAppliedAmount() } /** - * Returns base_weee_tax_applied_row_amnt + * Return base_weee_tax_applied_row_amnt * * @return float|null */ @@ -933,7 +933,7 @@ public function getBaseWeeeTaxAppliedRowAmnt() } /** - * Returns base_weee_tax_disposition + * Return base_weee_tax_disposition * * @return float|null */ @@ -943,7 +943,7 @@ public function getBaseWeeeTaxDisposition() } /** - * Returns base_weee_tax_row_disposition + * Return base_weee_tax_row_disposition * * @return float|null */ @@ -953,7 +953,7 @@ public function getBaseWeeeTaxRowDisposition() } /** - * Returns created_at + * Return created_at * * @return string|null */ @@ -971,7 +971,7 @@ public function setCreatedAt($createdAt) } /** - * Returns description + * Return description * * @return string|null */ @@ -981,7 +981,7 @@ public function getDescription() } /** - * Returns discount_amount + * Return discount_amount * * @return float|null */ @@ -991,7 +991,7 @@ public function getDiscountAmount() } /** - * Returns discount_invoiced + * Return discount_invoiced * * @return float|null */ @@ -1001,7 +1001,7 @@ public function getDiscountInvoiced() } /** - * Returns discount_percent + * Return discount_percent * * @return float|null */ @@ -1011,7 +1011,7 @@ public function getDiscountPercent() } /** - * Returns discount_refunded + * Return discount_refunded * * @return float|null */ @@ -1021,7 +1021,7 @@ public function getDiscountRefunded() } /** - * Returns event_id + * Return event_id * * @return int|null */ @@ -1031,7 +1031,7 @@ public function getEventId() } /** - * Returns ext_order_item_id + * Return ext_order_item_id * * @return string|null */ @@ -1041,7 +1041,7 @@ public function getExtOrderItemId() } /** - * Returns free_shipping + * Return free_shipping * * @return int|null */ @@ -1051,7 +1051,7 @@ public function getFreeShipping() } /** - * Returns gw_base_price + * Return gw_base_price * * @return float|null */ @@ -1061,7 +1061,7 @@ public function getGwBasePrice() } /** - * Returns gw_base_price_invoiced + * Return gw_base_price_invoiced * * @return float|null */ @@ -1071,7 +1071,7 @@ public function getGwBasePriceInvoiced() } /** - * Returns gw_base_price_refunded + * Return gw_base_price_refunded * * @return float|null */ @@ -1081,7 +1081,7 @@ public function getGwBasePriceRefunded() } /** - * Returns gw_base_tax_amount + * Return gw_base_tax_amount * * @return float|null */ @@ -1091,7 +1091,7 @@ public function getGwBaseTaxAmount() } /** - * Returns gw_base_tax_amount_invoiced + * Return gw_base_tax_amount_invoiced * * @return float|null */ @@ -1101,7 +1101,7 @@ public function getGwBaseTaxAmountInvoiced() } /** - * Returns gw_base_tax_amount_refunded + * Return gw_base_tax_amount_refunded * * @return float|null */ @@ -1111,7 +1111,7 @@ public function getGwBaseTaxAmountRefunded() } /** - * Returns gw_id + * Return gw_id * * @return int|null */ @@ -1121,7 +1121,7 @@ public function getGwId() } /** - * Returns gw_price + * Return gw_price * * @return float|null */ @@ -1131,7 +1131,7 @@ public function getGwPrice() } /** - * Returns gw_price_invoiced + * Return gw_price_invoiced * * @return float|null */ @@ -1141,7 +1141,7 @@ public function getGwPriceInvoiced() } /** - * Returns gw_price_refunded + * Return gw_price_refunded * * @return float|null */ @@ -1151,7 +1151,7 @@ public function getGwPriceRefunded() } /** - * Returns gw_tax_amount + * Return gw_tax_amount * * @return float|null */ @@ -1161,7 +1161,7 @@ public function getGwTaxAmount() } /** - * Returns gw_tax_amount_invoiced + * Return gw_tax_amount_invoiced * * @return float|null */ @@ -1171,7 +1171,7 @@ public function getGwTaxAmountInvoiced() } /** - * Returns gw_tax_amount_refunded + * Return gw_tax_amount_refunded * * @return float|null */ @@ -1181,7 +1181,7 @@ public function getGwTaxAmountRefunded() } /** - * Returns discount_tax_compensation_amount + * Return discount_tax_compensation_amount * * @return float|null */ @@ -1191,7 +1191,7 @@ public function getDiscountTaxCompensationAmount() } /** - * Returns discount_tax_compensation_canceled + * Return discount_tax_compensation_canceled * * @return float|null */ @@ -1201,7 +1201,7 @@ public function getDiscountTaxCompensationCanceled() } /** - * Returns discount_tax_compensation_invoiced + * Return discount_tax_compensation_invoiced * * @return float|null */ @@ -1211,7 +1211,7 @@ public function getDiscountTaxCompensationInvoiced() } /** - * Returns discount_tax_compensation_refunded + * Return discount_tax_compensation_refunded * * @return float|null */ @@ -1221,7 +1221,7 @@ public function getDiscountTaxCompensationRefunded() } /** - * Returns is_qty_decimal + * Return is_qty_decimal * * @return int|null */ @@ -1231,7 +1231,7 @@ public function getIsQtyDecimal() } /** - * Returns is_virtual + * Return is_virtual * * @return int|null */ @@ -1241,7 +1241,7 @@ public function getIsVirtual() } /** - * Returns item_id + * Return item_id * * @return int|null */ @@ -1251,7 +1251,7 @@ public function getItemId() } /** - * Returns locked_do_invoice + * Return locked_do_invoice * * @return int|null */ @@ -1261,7 +1261,7 @@ public function getLockedDoInvoice() } /** - * Returns locked_do_ship + * Return locked_do_ship * * @return int|null */ @@ -1271,7 +1271,7 @@ public function getLockedDoShip() } /** - * Returns name + * Return name * * @return string|null */ @@ -1281,7 +1281,7 @@ public function getName() } /** - * Returns no_discount + * Return no_discount * * @return int|null */ @@ -1291,7 +1291,7 @@ public function getNoDiscount() } /** - * Returns order_id + * Return order_id * * @return int|null */ @@ -1301,7 +1301,7 @@ public function getOrderId() } /** - * Returns parent_item_id + * Return parent_item_id * * @return int|null */ @@ -1311,7 +1311,7 @@ public function getParentItemId() } /** - * Returns price + * Return price * * @return float|null */ @@ -1321,7 +1321,7 @@ public function getPrice() } /** - * Returns price_incl_tax + * Return price_incl_tax * * @return float|null */ @@ -1331,7 +1331,7 @@ public function getPriceInclTax() } /** - * Returns product_id + * Return product_id * * @return int|null */ @@ -1341,7 +1341,7 @@ public function getProductId() } /** - * Returns product_type + * Return product_type * * @return string|null */ @@ -1351,7 +1351,7 @@ public function getProductType() } /** - * Returns qty_backordered + * Return qty_backordered * * @return float|null */ @@ -1361,7 +1361,7 @@ public function getQtyBackordered() } /** - * Returns qty_canceled + * Return qty_canceled * * @return float|null */ @@ -1371,7 +1371,7 @@ public function getQtyCanceled() } /** - * Returns qty_invoiced + * Return qty_invoiced * * @return float|null */ @@ -1381,7 +1381,7 @@ public function getQtyInvoiced() } /** - * Returns qty_ordered + * Return qty_ordered * * @return float|null */ @@ -1391,7 +1391,7 @@ public function getQtyOrdered() } /** - * Returns qty_refunded + * Return qty_refunded * * @return float|null */ @@ -1401,7 +1401,7 @@ public function getQtyRefunded() } /** - * Returns qty_returned + * Return qty_returned * * @return float|null */ @@ -1411,7 +1411,7 @@ public function getQtyReturned() } /** - * Returns qty_shipped + * Return qty_shipped * * @return float|null */ @@ -1421,7 +1421,7 @@ public function getQtyShipped() } /** - * Returns quote_item_id + * Return quote_item_id * * @return int|null */ @@ -1431,7 +1431,7 @@ public function getQuoteItemId() } /** - * Returns row_invoiced + * Return row_invoiced * * @return float|null */ @@ -1441,7 +1441,7 @@ public function getRowInvoiced() } /** - * Returns row_total + * Return row_total * * @return float|null */ @@ -1451,7 +1451,7 @@ public function getRowTotal() } /** - * Returns row_total_incl_tax + * Return row_total_incl_tax * * @return float|null */ @@ -1461,7 +1461,7 @@ public function getRowTotalInclTax() } /** - * Returns row_weight + * Return row_weight * * @return float|null */ @@ -1471,7 +1471,7 @@ public function getRowWeight() } /** - * Returns sku + * Return sku * * @return string */ @@ -1481,7 +1481,7 @@ public function getSku() } /** - * Returns store_id + * Return store_id * * @return int|null */ @@ -1491,7 +1491,7 @@ public function getStoreId() } /** - * Returns tax_amount + * Return tax_amount * * @return float|null */ @@ -1501,7 +1501,7 @@ public function getTaxAmount() } /** - * Returns tax_before_discount + * Return tax_before_discount * * @return float|null */ @@ -1511,7 +1511,7 @@ public function getTaxBeforeDiscount() } /** - * Returns tax_canceled + * Return tax_canceled * * @return float|null */ @@ -1521,7 +1521,7 @@ public function getTaxCanceled() } /** - * Returns tax_invoiced + * Return tax_invoiced * * @return float|null */ @@ -1531,7 +1531,7 @@ public function getTaxInvoiced() } /** - * Returns tax_percent + * Return tax_percent * * @return float|null */ @@ -1541,7 +1541,7 @@ public function getTaxPercent() } /** - * Returns tax_refunded + * Return tax_refunded * * @return float|null */ @@ -1551,7 +1551,7 @@ public function getTaxRefunded() } /** - * Returns updated_at + * Return updated_at * * @return string|null */ @@ -1561,7 +1561,7 @@ public function getUpdatedAt() } /** - * Returns weee_tax_applied + * Return weee_tax_applied * * @return string|null */ @@ -1571,7 +1571,7 @@ public function getWeeeTaxApplied() } /** - * Returns weee_tax_applied_amount + * Return weee_tax_applied_amount * * @return float|null */ @@ -1581,7 +1581,7 @@ public function getWeeeTaxAppliedAmount() } /** - * Returns weee_tax_applied_row_amount + * Return weee_tax_applied_row_amount * * @return float|null */ @@ -1591,7 +1591,7 @@ public function getWeeeTaxAppliedRowAmount() } /** - * Returns weee_tax_disposition + * Return weee_tax_disposition * * @return float|null */ @@ -1601,7 +1601,7 @@ public function getWeeeTaxDisposition() } /** - * Returns weee_tax_row_disposition + * Return weee_tax_row_disposition * * @return float|null */ @@ -1611,7 +1611,7 @@ public function getWeeeTaxRowDisposition() } /** - * Returns weight + * Return weight * * @return float|null */ From 341d68cc42e6a06cfdccf2d1fcb4475f69bb9318 Mon Sep 17 00:00:00 2001 From: RomanKis <romaikiss@gmail.com> Date: Tue, 5 Dec 2017 18:01:25 +0200 Subject: [PATCH 0115/1415] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Upport fix from 2.2-develop --- .../Model/Checkout/Type/Multishipping.php | 53 +++++++++++++++++-- .../Model/Checkout/Type/MultishippingTest.php | 42 ++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 9412b13895599..8d740b4ea6b92 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -897,13 +897,21 @@ public function reset() */ public function validateMinimumAmount() { - return !($this->_scopeConfig->isSetFlag( + $minimumOrderActive = $this->_scopeConfig->isSetFlag( 'sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && $this->_scopeConfig->isSetFlag( + ); + + if ($this->_scopeConfig->isSetFlag( 'sales/minimum_order/multi_address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && !$this->getQuote()->validateMinimumAmount()); + \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) { + $result = !($minimumOrderActive && !$this->getQuote()->validateMinimumAmount()); + } else { + $result = !($minimumOrderActive && !$this->validateMinimumAmountForAddressItems()); + } + + return $result; } /** @@ -1115,6 +1123,43 @@ private function getShippingAssignmentProcessor() return $this->shippingAssignmentProcessor; } + /** + * Validate minimum amount for "Checkout with Multiple Addresses" when + * "Validate Each Address Separately in Multi-address Checkout" is No. + * + * @return bool + */ + private function validateMinimumAmountForAddressItems() + { + $result = true; + $storeId = $this->getQuote()->getStoreId(); + + $minAmount = $this->_scopeConfig->getValue( + 'sales/minimum_order/amount', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + $taxInclude = $this->_scopeConfig->getValue( + 'sales/minimum_order/tax_including', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + + $addresses = $this->getQuote()->getAllAddresses(); + + $baseTotal = 0; + foreach ($addresses as $address) { + $taxes = $taxInclude ? $address->getBaseTaxAmount() : 0; + $baseTotal += $address->getBaseSubtotalWithDiscount() + $taxes; + } + + if ($baseTotal < $minAmount) { + $result = false; + } + + return $result; + } + /** * Remove successfully placed items from quote. * diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index 94c11bef1d311..da206cf266219 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -167,13 +167,18 @@ class MultishippingTest extends \PHPUnit\Framework\TestCase */ private $sessionMock; + /** + * @var PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + protected function setUp() { $this->checkoutSessionMock = $this->createSimpleMock(Session::class); $this->customerSessionMock = $this->createSimpleMock(CustomerSession::class); $this->orderFactoryMock = $this->createSimpleMock(OrderFactory::class); $eventManagerMock = $this->createSimpleMock(ManagerInterface::class); - $scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); + $this->scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); $this->sessionMock = $this->createSimpleMock(Generic::class); $addressFactoryMock = $this->createSimpleMock(AddressFactory::class); $this->toOrderMock = $this->createSimpleMock(ToOrder::class); @@ -224,7 +229,7 @@ protected function setUp() $this->orderFactoryMock, $this->addressRepositoryMock, $eventManagerMock, - $scopeConfigMock, + $this->scopeConfigMock, $this->sessionMock, $addressFactoryMock, $this->toOrderMock, @@ -807,4 +812,37 @@ private function createSimpleMock($className) ->disableOriginalConstructor() ->getMock(); } + + public function testValidateMinimumAmountMultiAddressTrue() + { + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, true); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->willReturn(false); + $this->assertFalse($this->model->validateMinimumAmount()); + } + + public function testValidateMinimumAmountMultiAddressFalse() + { + $addressMock = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, false); + + $this->scopeConfigMock->expects($this->exactly(2))->method('getValue')->withConsecutive( + ['sales/minimum_order/amount', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/tax_including', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(100, false); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('getStoreId')->willReturn(1); + $this->quoteMock->expects($this->once())->method('getAllAddresses')->willReturn([$addressMock]); + $addressMock->expects($this->once())->method('getBaseSubtotalWithDiscount')->willReturn(101); + + $this->assertTrue($this->model->validateMinimumAmount()); + } } From e323c7b3661191c9eeb52776ab1b4c0c6fb5d8ad Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Mon, 17 Sep 2018 14:50:10 -0500 Subject: [PATCH 0116/1415] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Fix issue with upport that doesn't trigger totals to re-calculate before validation - Remove redundant form markup from addresses template - Update unit test to account for changes --- .../Model/Checkout/Type/Multishipping.php | 3 ++- .../Unit/Model/Checkout/Type/MultishippingTest.php | 8 ++++++++ .../view/frontend/templates/checkout/addresses.phtml | 11 ----------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 8d740b4ea6b92..f55af40388fdf 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -874,7 +874,7 @@ private function logExceptions(array $exceptionList) */ public function save() { - $this->getQuote()->collectTotals(); + $this->getQuote()->setTotalsCollectedFlag(false)->collectTotals(); $this->quoteRepository->save($this->getQuote()); return $this; } @@ -1145,6 +1145,7 @@ private function validateMinimumAmountForAddressItems() $storeId ); + $this->getQuote()->collectTotals(); $addresses = $this->getQuote()->getAllAddresses(); $baseTotal = 0; diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index da206cf266219..67ff233f717eb 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -282,6 +282,10 @@ public function testSetShippingItemsInformation() ->willReturn(null); $this->quoteMock->expects($this->atLeastOnce())->method('getAllItems')->willReturn([]); + $this->quoteMock->expects($this->once()) + ->method('__call') + ->with('setTotalsCollectedFlag', [false]) + ->willReturnSelf(); $this->filterBuilderMock->expects($this->atLeastOnce())->method('setField')->willReturnSelf(); $this->filterBuilderMock->expects($this->atLeastOnce())->method('setValue')->willReturnSelf(); @@ -421,6 +425,10 @@ public function testSetShippingMethods() $addressMock->expects($this->once())->method('getId')->willReturn($addressId); $this->quoteMock->expects($this->once())->method('getAllShippingAddresses')->willReturn([$addressMock]); $addressMock->expects($this->once())->method('setShippingMethod')->with($methodsArray[$addressId]); + $this->quoteMock->expects($this->once()) + ->method('__call') + ->with('setTotalsCollectedFlag', [false]) + ->willReturnSelf(); $this->mockShippingAssignment(); diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml index 0f96f7cdb708a..a29013cc71722 100644 --- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml +++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml @@ -14,17 +14,6 @@ * @var $block \Magento\Multishipping\Block\Checkout\Addresses */ ?> -<form id="checkout_multishipping_form" - data-mage-init='{ - "multiShipping":{}, - "validation":{}, - "cartUpdate": { - "validationURL": "/multishipping/checkout/checkItems", - "eventName": "updateMulticartItemQty" - }}' - action="<?= $block->escapeUrl($block->getPostActionUrl()) ?>" - method="post" - class="multicheckout address form"> <form id="checkout_multishipping_form" data-mage-init='{ "multiShipping":{}, From 5372c7df5e16601f2cce687e15ff25ecdd0b82ce Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 17:18:04 -0300 Subject: [PATCH 0117/1415] #17744 Fixing syntax pattern --- .../view/frontend/web/js/model/checkout-data-resolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 7a1ba9513ec42..6f4c99438610b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -227,7 +227,7 @@ define([ return; } - if(quote.isVirtual()) { + if (quote.isVirtual()) { isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { selectBillingAddress(addrs); From d0840536ed651a94bc684489a57207ce34048545 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 17 Sep 2018 16:04:01 -0500 Subject: [PATCH 0118/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Controller/Adminhtml/Product/Attribute/Save.php | 2 +- .../Controller/Adminhtml/Product/Attribute/Validate.php | 2 +- .../Mftf/Test/AdminEditTextEditorProductAttributeTest.xml | 7 +++---- .../Controller/Adminhtml/Product/Attribute/SaveTest.php | 6 +++--- .../Adminhtml/Product/Attribute/ValidateTest.php | 8 ++++---- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index e32d84b393aeb..e730381b0ea58 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -140,7 +140,7 @@ public function execute() { try { $optionData = $this->optionsDataSerializer - ->unserialize($this->getRequest()->getParam('serialized_options')); + ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " . "If the error persists, please try again later."); diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 34dcf6639f943..16449762b4a7b 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -83,7 +83,7 @@ public function execute() $response->setError(false); try { $optionsData = $this->optionsDataSerializer - ->unserialize($this->getRequest()->getParam('serialized_options')); + ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be validated due to an error. Verify your information and try again. " . "If the error persists, please try again later."); diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml index 7603400ba8dcd..e914b8c96d03e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml @@ -26,10 +26,9 @@ <requiredEntity createDataKey="myProductAttributeCreation"/> </createData> </before> - <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid1"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - <click selector="{{AdminProductAttributeGridSection.AttributeCode($$myProductAttributeCreation.attribute_code$$)}}" stepKey="navigateToAttributeEditPage1" /> - <waitForPageLoad stepKey="waitForPageLoad2" /> + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="productAttributeWysiwyg"/> + </actionGroup> <seeOptionIsSelected selector="{{AttributePropertiesSection.InputType}}" userInput="Text Editor" stepKey="seeTextEditorSelected" /> <see selector="{{AttributePropertiesSection.InputType}}" userInput="Text Area" stepKey="seeTextArea1" /> <selectOption selector="{{AttributePropertiesSection.InputType}}" userInput="Text Area" stepKey="selectTextArea" /> diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php index b9b1aeb9157db..f34a70260a2e0 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php @@ -180,7 +180,7 @@ public function testExecuteWithEmptyData() ->method('getParam') ->willReturnMap([ ['isAjax', null, null], - ['serialized_options', null, ''], + ['serialized_options', '[]', ''], ]); $this->optionsDataSerializerMock ->expects($this->once()) @@ -211,7 +211,7 @@ public function testExecute() ->method('getParam') ->willReturnMap([ ['isAjax', null, null], - ['serialized_options', null, ''], + ['serialized_options', '[]', ''], ]); $this->optionsDataSerializerMock ->expects($this->once()) @@ -271,7 +271,7 @@ public function testExecuteWithOptionsDataError() ->method('getParam') ->willReturnMap([ ['isAjax', null, true], - ['serialized_options', null, $serializedOptions], + ['serialized_options', '[]', $serializedOptions], ]); $this->optionsDataSerializerMock ->expects($this->once()) diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index e9fc8bf3362b3..17af610fed76c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -130,7 +130,7 @@ public function testExecute() ['frontend_label', null, 'test_frontend_label'], ['attribute_code', null, 'test_attribute_code'], ['new_attribute_set_name', null, 'test_attribute_set_name'], - ['serialized_options', null, $serializedOptions], + ['serialized_options', '[]', $serializedOptions], ]); $this->objectManagerMock->expects($this->exactly(2)) ->method('create') @@ -181,7 +181,7 @@ public function testUniqueValidation(array $options, $isError) ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], ['message_key', null, Validate::DEFAULT_MESSAGE_KEY], - ['serialized_options', null, $serializedOptions], + ['serialized_options', '[]', $serializedOptions], ]); $this->optionsDataSerializerMock @@ -316,7 +316,7 @@ public function testEmptyOption(array $options, $result) ['attribute_code', null, "test_attribute_code"], ['new_attribute_set_name', null, 'test_attribute_set_name'], ['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'], - ['serialized_options', null, $serializedOptions], + ['serialized_options', '[]', $serializedOptions], ]); $this->optionsDataSerializerMock @@ -428,7 +428,7 @@ public function testExecuteWithOptionsDataError() ['attribute_code', null, 'test_attribute_code'], ['new_attribute_set_name', null, 'test_attribute_set_name'], ['message_key', Validate::DEFAULT_MESSAGE_KEY, 'message'], - ['serialized_options', null, $serializedOptions], + ['serialized_options', '[]', $serializedOptions], ]); $this->optionsDataSerializerMock From d1cbcc0e238fe7328c1af2b504908ec6473a1435 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 17 Sep 2018 16:42:37 -0500 Subject: [PATCH 0119/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form -- fix merge conflict --- .../Adminhtml/Product/Attribute/Validate.php | 5 ++++- .../Adminhtml/Product/AttributeTest.php | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 16449762b4a7b..d9627ddd1476d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -8,15 +8,18 @@ namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; +use Magento\Catalog\Controller\Adminhtml\Product\Attribute as AttributeAction; /** * Product attribute validate controller. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute +class Validate extends AttributeAction implements HttpGetActionInterface, HttpPostActionInterface { const DEFAULT_MESSAGE_KEY = 'message'; diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 1a0073b154ffa..36e216ab4e57e 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -7,6 +7,8 @@ namespace Magento\Swatches\Controller\Adminhtml\Product; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Exception\LocalizedException; /** @@ -17,6 +19,21 @@ */ class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendController { + /** + * @var FormKey + */ + private $formKey; + + /** + * @inheritDoc + */ + protected function setUp() + { + parent::setUp(); + + $this->formKey = $this->_objectManager->get(FormKey::class); + } + /** * Generate random hex color. * @@ -116,6 +133,7 @@ private function getAttributePreset() : array { return [ 'form_key' => 'XxtpPYjm2YPYUlAt', + 'serialized_options' => '[]', 'frontend_label' => [ 0 => 'asdasd', 1 => '', @@ -178,7 +196,9 @@ public function testLargeOptionsDataSet( int $expectedOptionsCount, array $expectedLabels ) : void { + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); $this->getRequest()->setPostValue($attributeData); + $this->getRequest()->setPostValue('form_key', $this->formKey->getFormKey()); $this->dispatch('backend/catalog/product_attribute/save'); $entityTypeId = $this->_objectManager->create( \Magento\Eav\Model\Entity::class From 945eb0094a1f8298fe71c1b9852d9bbb324d4019 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 18 Sep 2018 10:38:13 +0400 Subject: [PATCH 0120/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Update automated test --- .../Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml index dd34777d3658c..9180636db7821 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAvailabilityCreditMemoWithNoPaymentTest.xml @@ -33,7 +33,7 @@ <createData entity="DisableFreeShippingConfig" stepKey="disableFreeShippingConfig"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="logOut"/> </after> <!-- Flush Magento Cache --> From 7ddff219604b24bfc73b5890bf2db4147b79d6e2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 13 Sep 2018 17:07:20 +0300 Subject: [PATCH 0121/1415] MAGETWO-94482: Fixed procedure of creating mapping for dynamic fields in elasticsearch --- .../CategoryFieldsProvider.php | 16 +- .../Adapter/DataMapper/ProductDataMapper.php | 12 +- .../FieldMapper/ProductFieldMapper.php | 207 +++++++----------- .../CategoryFieldsProvider.php | 16 +- .../BatchDataMapper/PriceFieldsProvider.php | 21 +- .../Adapter/DataMapper/ProductDataMapper.php | 36 +-- .../Model/Adapter/Elasticsearch.php | 7 +- .../FieldNameResolverPoolInterface.php | 23 ++ .../FieldName/Resolver/CategoryName.php | 66 ++++++ .../FieldName/Resolver/DefaultResolver.php | 102 +++++++++ .../FieldName/Resolver/NotEavAttribute.php | 23 ++ .../Product/FieldName/Resolver/Position.php | 66 ++++++ .../Product/FieldName/Resolver/Price.php | 42 ++++ .../FieldName/Resolver/SpecialAttribute.php | 23 ++ .../Product/FieldName/ResolverInterface.php | 19 ++ .../Specification/CategoryNameAttribute.php | 29 +++ .../Specification/DummySpecification.php | 25 +++ .../Specification/NotEavAttribute.php | 47 ++++ .../Specification/PositionAttribute.php | 29 +++ .../Specification/PriceAttribute.php | 29 +++ .../Specification/SpecialAttribute.php | 29 +++ .../FieldName/Specification/Specification.php | 54 +++++ .../FieldName/SpecificationInterface.php | 38 ++++ .../Product/FieldNameResolverPool.php | 56 +++++ .../FieldMapper/ProductFieldMapper.php | 93 +------- app/code/Magento/Elasticsearch/etc/di.xml | 40 ++++ 26 files changed, 877 insertions(+), 271 deletions(-) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 009c07602fc2a..3e6164208b422 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -7,6 +7,7 @@ use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; /** * Provide data mapping for categories fields @@ -18,12 +19,19 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface */ private $resourceIndex; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex + * @param FieldMapperInterface $fieldMapper */ - public function __construct(Index $resourceIndex) + public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) { $this->resourceIndex = $resourceIndex; + $this->fieldMapper = $fieldMapper; } /** @@ -59,8 +67,10 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => $categoryIds]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index 659df0f8447f9..bcf0d0bfe26cd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -364,9 +364,11 @@ protected function getProductPriceData($productId, $storeId, array $priceIndexDa $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; - $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = 'price_' . $customerGroupId . '_' . $websiteId; + $fieldName = $this->fieldMapper->getFieldName( + 'price', + ['customerGroupId' => $customerGroupId] + ); $result[$fieldName] = sprintf('%F', $price); } } @@ -398,8 +400,10 @@ protected function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index be198e7190ec9..247eb624b2a56 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -5,13 +5,14 @@ */ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper; +use Magento\Catalog\Api\CategoryListInterface; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use \Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\Api\SearchCriteriaBuilder; /** * Class ProductFieldMapper @@ -29,43 +30,50 @@ class ProductFieldMapper implements FieldMapperInterface protected $fieldType; /** - * @var CustomerSession + * Category list. + * + * @var CategoryListInterface */ - protected $customerSession; + private $categoryList; /** - * Store manager + * Customer group repository. * - * @var StoreManager + * @var GroupRepositoryInterface */ - protected $storeManager; + private $groupRepository; /** - * Core registry + * Search criteria builder. * - * @var Registry + * @var SearchCriteriaBuilder */ - protected $coreRegistry; + private $searchCriteriaBuilder; + + /** + * @var FieldNameResolverPoolInterface + */ + private $fieldNameResolverPool; /** * @param Config $eavConfig * @param FieldType $fieldType - * @param CustomerSession $customerSession - * @param StoreManager $storeManager - * @param Registry $coreRegistry + * @param GroupRepositoryInterface $groupRepository + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param FieldNameResolverPoolInterface $fieldNameResolverPool */ public function __construct( Config $eavConfig, FieldType $fieldType, - CustomerSession $customerSession, - StoreManager $storeManager, - Registry $coreRegistry + GroupRepositoryInterface $groupRepository, + SearchCriteriaBuilder $searchCriteriaBuilder, + FieldNameResolverPoolInterface $fieldNameResolverPool ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->groupRepository = $groupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->fieldNameResolverPool = $fieldNameResolverPool; } /** @@ -77,35 +85,7 @@ public function __construct( */ public function getFieldName($attributeCode, $context = []) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute || in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - if ($attributeCode === 'price') { - return $this->getPriceFieldName($context); - } - if ($attributeCode === 'position') { - return $this->getPositionFiledName($context); - } - $fieldType = $this->fieldType->getFieldType($attribute); - $frontendInput = $attribute->getFrontendInput(); - if (empty($context['type'])) { - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if ($fieldType === FieldType::ES_DATA_TYPE_TEXT) { - return $this->getFieldName( - $attributeCode, - array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) - ); - } - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { - $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); - } else { - $fieldName = 'sort_' . $attributeCode; - } - - return $fieldName; + return $this->fieldNameResolverPool->getResolver($attributeCode)->getFieldName($attributeCode, $context); } /** @@ -113,10 +93,33 @@ public function getFieldName($attributeCode, $context = []) * * @param array $context * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getAllAttributesTypes($context = []) + { + return array_merge( + $this->getAllStaticAttributesTypes(), + $this->getAllDynamicAttributesTypes() + ); + } + + /** + * @param Object $attribute + * @return bool + */ + protected function isAttributeUsedInAdvancedSearch($attribute) + { + return $attribute->getIsVisibleInAdvancedSearch() + || $attribute->getIsFilterable() + || $attribute->getIsFilterableInSearch(); + } + + /** + * Prepare mapping data for static attributes. + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @return array + */ + private function getAllStaticAttributesTypes() { $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); $allAttributes = []; @@ -163,89 +166,37 @@ public function getAllAttributesTypes($context = []) } /** - * Is attribute used in advanced search. + * Prepare mapping data for dynamic attributes. * - * @param Object $attribute - * @return bool - */ - protected function isAttributeUsedInAdvancedSearch($attribute) - { - return $attribute->getIsVisibleInAdvancedSearch() - || $attribute->getIsFilterable() - || $attribute->getIsFilterableInSearch(); - } - - /** - * Get refined field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string - */ - protected function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) - { - switch ($frontendInput) { - case 'select': - case 'multiselect': - return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; - case 'boolean': - return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; - default: - return $attributeCode; - } - } - - /** - * Get query type field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string + * @return array */ - protected function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode) + private function getAllDynamicAttributesTypes() { - if ($attributeCode === '*') { - $fieldName = '_all'; - } else { - $fieldName = $this->getRefinedFieldName($frontendInput, $fieldType, $attributeCode); + $allAttributes = []; + $searchCriteria = $this->searchCriteriaBuilder->create(); + $categories = $this->categoryList->getList($searchCriteria)->getItems(); + foreach ($categories as $category) { + $categoryPositionKey = $this->getFieldName('position', ['categoryId' => $category->getId()]); + $categoryNameKey = $this->getFieldName('category_name', ['categoryId' => $category->getId()]); + $allAttributes[$categoryPositionKey] = [ + 'type' => FieldType::ES_DATA_TYPE_TEXT, + 'index' => false + ]; + $allAttributes[$categoryNameKey] = [ + 'type' => FieldType::ES_DATA_TYPE_TEXT, + 'index' => false + ]; } - return $fieldName; - } - /** - * Get "position" field name - * - * @param array $context - * @return string - */ - protected function getPositionFiledName($context) - { - if (isset($context['categoryId'])) { - $category = $context['categoryId']; - } else { - $category = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + foreach ($groups as $group) { + $groupPriceKey = $this->getFieldName('price', ['customerGroupId' => $group->getId()]); + $allAttributes[$groupPriceKey] = [ + 'type' => FieldType::ES_DATA_TYPE_FLOAT, + 'store' => true + ]; } - return 'position_category_' . $category; - } - /** - * Prepare price field name for search engine - * - * @param array $context - * @return string - */ - protected function getPriceFieldName($context) - { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); - return 'price_' . $customerGroupId . '_' . $websiteId; + return $allAttributes; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index e2de4aec717a4..7d2af3b31d9ac 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -7,6 +7,7 @@ use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; /** * Provide data mapping for categories fields @@ -18,12 +19,19 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface */ private $resourceIndex; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex + * @param FieldMapperInterface $fieldMapper */ - public function __construct(Index $resourceIndex) + public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) { $this->resourceIndex = $resourceIndex; + $this->fieldMapper = $fieldMapper; } /** @@ -59,8 +67,10 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index f5e8a23525a07..f97cc89c5c875 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -5,6 +5,7 @@ */ namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\Store\Model\StoreManagerInterface; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; @@ -30,19 +31,27 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface */ private $storeManager; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager + * @param FieldMapperInterface $fieldMapper */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + FieldMapperInterface $fieldMapper ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; $this->storeManager = $storeManager; + $this->fieldMapper = $fieldMapper; } /** @@ -56,7 +65,7 @@ public function getFields(array $productIds, $storeId) $fields = []; foreach ($productIds as $productId) { - $fields[$productId] = $this->getProductPriceData($productId, $storeId, $priceData); + $fields[$productId] = $this->getProductPriceData($productId, $priceData); } return $fields; @@ -66,17 +75,19 @@ public function getFields(array $productIds, $storeId) * Prepare price index for product * * @param int $productId - * @param int $websiteId * @param array $priceIndexData * @return array */ - private function getProductPriceData($productId, $websiteId, array $priceIndexData) + private function getProductPriceData($productId, array $priceIndexData) { $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = 'price_' . $customerGroupId . '_' . $websiteId; + $fieldName = $this->fieldMapper->getFieldName( + 'price', + ['customerGroupId' => $customerGroupId] + ); $result[$fieldName] = sprintf('%F', $price); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index da37c8d7647d8..1ca24a0c73025 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -5,9 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\DataMapper; -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Customer\Api\Data\GroupInterface; use Magento\Elasticsearch\Model\Adapter\DataMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper as ElasticSearch5ProductDataMapper; @@ -17,36 +14,5 @@ */ class ProductDataMapper extends ElasticSearch5ProductDataMapper implements DataMapperInterface { - /** - * Prepare category index data for product - * - * @param int $productId - * @param array $categoryIndexData - * @return array - */ - protected function getProductCategoryData($productId, array $categoryIndexData) - { - $result = []; - $categoryIds = []; - - if (array_key_exists($productId, $categoryIndexData)) { - $indexData = $categoryIndexData[$productId]; - $result = $indexData; - } - - if (array_key_exists($productId, $categoryIndexData)) { - $indexData = $categoryIndexData[$productId]; - foreach ($indexData as $categoryData) { - $categoryIds[] = $categoryData['id']; - } - if (count($categoryIds)) { - $result = ['category_ids' => implode(' ', $categoryIds)]; - foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; - } - } - } - return $result; - } + // } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 7fc45eed35650..fdf23332fff04 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -347,9 +347,12 @@ public function updateAlias($storeId, $mappedIndexerId) protected function prepareIndex($storeId, $indexName, $mappedIndexerId) { $this->indexBuilder->setStoreId($storeId); - $this->client->createIndex($indexName, ['settings' => $this->indexBuilder->build()]); + $settings = $this->indexBuilder->build(); + $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]); + $settings['index']['mapping']['total_fields']['limit'] = count($allAttributeTypes); + $this->client->createIndex($indexName, ['settings' => $settings]); $this->client->addFieldsMapping( - $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]), + $allAttributeTypes, $indexName, $this->clientConfig->getEntityType() ); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php new file mode 100644 index 0000000000000..50172e8381d59 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Identify field name resolver for attribute. + */ +interface FieldNameResolverPoolInterface +{ + /** + * Get field name resolver. + * + * @param string $attributeCode + * @param array $context + * @return ResolverInterface + */ + public function getResolver(string $attributeCode, $context = []) : ResolverInterface; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php new file mode 100644 index 0000000000000..8b3c79f66e38a --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for Category name attribute. + */ +class CategoryName implements ResolverInterface +{ + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * @param StoreManager $storeManager + * @param Registry $coreRegistry + */ + public function __construct( + StoreManager $storeManager, + Registry $coreRegistry + ) { + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return 'name_category_' . $this->resolveCategoryId($context); + } + + /** + * Resolve category id. + * + * @param array $context + * @return int + */ + private function resolveCategoryId($context) + { + if (isset($context['categoryId'])) { + $id = $context['categoryId']; + } else { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } + + return $id; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php new file mode 100644 index 0000000000000..d62354daf7638 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php @@ -0,0 +1,102 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Default name resolver. + */ +class DefaultResolver implements ResolverInterface +{ + /** + * @var Config + */ + private $eavConfig; + + /** + * @var FieldType + */ + private $fieldType; + + /** + * @param Config $eavConfig + * @param FieldType $fieldType + */ + public function __construct( + Config $eavConfig, + FieldType $fieldType + ) { + $this->eavConfig = $eavConfig; + $this->fieldType = $fieldType; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + $fieldType = $this->fieldType->getFieldType($attribute); + $frontendInput = $attribute->getFrontendInput(); + if (empty($context['type'])) { + $fieldName = $attributeCode; + } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { + if (in_array($fieldType, ['string', FieldType::ES_DATA_TYPE_TEXT], true)) { + return $this->getFieldName( + $attributeCode, + array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) + ); + } + $fieldName = $attributeCode; + } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { + $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); + } else { + $fieldName = 'sort_' . $attributeCode; + } + + return $fieldName; + } + + /** + * @param string $frontendInput + * @param string $fieldType + * @param string $attributeCode + * @return string + */ + private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode) + { + if ($attributeCode === '*') { + $fieldName = '_all'; + } else { + $fieldName = $this->getRefinedFieldName($frontendInput, $fieldType, $attributeCode); + } + return $fieldName; + } + + /** + * @param string $frontendInput + * @param string $fieldType + * @param string $attributeCode + * @return string + */ + private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) + { + switch ($frontendInput) { + case 'select': + return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; + case 'boolean': + return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; + default: + return $attributeCode; + } + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php new file mode 100644 index 0000000000000..3c19ab7e216cc --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for not EAV attribute. + */ +class NotEavAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return $attributeCode; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php new file mode 100644 index 0000000000000..8082e48e57b5e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for position attribute. + */ +class Position implements ResolverInterface +{ + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * @param StoreManager $storeManager + * @param Registry $coreRegistry + */ + public function __construct( + StoreManager $storeManager, + Registry $coreRegistry + ) { + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return 'position_category_' . $this->resolveCategoryId($context); + } + + /** + * Resolve category id. + * + * @param array $context + * @return int + */ + private function resolveCategoryId($context) + { + if (isset($context['categoryId'])) { + $id = $context['categoryId']; + } else { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } + + return $id; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php new file mode 100644 index 0000000000000..0a09740e9747d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for price attribute. + */ +class Price implements ResolverInterface +{ + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @param CustomerSession $customerSession + */ + public function __construct( + CustomerSession $customerSession + ) { + $this->customerSession = $customerSession; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); + + return 'price_' . $customerGroupId; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php new file mode 100644 index 0000000000000..5318797db5f07 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for not special attribute. + */ +class SpecialAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return $attributeCode; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php new file mode 100644 index 0000000000000..8b04bd281a71f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php @@ -0,0 +1,19 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; + +interface ResolverInterface +{ + /** + * Get field name. + * + * @param $attributeCode + * @param array $context + * @return string + */ + public function getFieldName($attributeCode, $context = []); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php new file mode 100644 index 0000000000000..918f465569a7f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the category name attribute. + */ +class CategoryNameAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'CATEGORY_NAME_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'category_name') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php new file mode 100644 index 0000000000000..1c003e64683a8 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Dummy specification. + */ +class DummySpecification extends Specification implements SpecificationInterface +{ + const TYPE = 'DUMMY'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + return self::TYPE; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php new file mode 100644 index 0000000000000..27da660c54c9e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Eav\Model\Config; + +/** + * Class ProductFieldMapper + */ +class NotEavAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'NOT_EAV_ATTRIBUTE'; + + /** + * @var Config + */ + private $eavConfig; + + /** + * @param SpecificationInterface $specification + * @param Config $eavConfig + */ + public function __construct(SpecificationInterface $specification, Config $eavConfig) + { + parent::__construct($specification); + $this->eavConfig = $eavConfig; + } + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (!$attribute) { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php new file mode 100644 index 0000000000000..0af6ea796e042 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the position attribute. + */ +class PositionAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'POSITION_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'position') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php new file mode 100644 index 0000000000000..ead561c0d5f8a --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the price attribute. + */ +class PriceAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'PRICE_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'price') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php new file mode 100644 index 0000000000000..c96e447ea7cc5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the special attributes. + */ +class SpecialAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'SPECIAL_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php new file mode 100644 index 0000000000000..86462e31a7b58 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Framework\Exception\NotFoundException; + +/** + * Abstract class for resolving type of specification. + */ +abstract class Specification implements SpecificationInterface +{ + /** + * @var SpecificationInterface + */ + private $next; + + /** + * @param SpecificationInterface $specification + */ + public function __construct(SpecificationInterface $specification) + { + $this->next = $specification; + } + + /** + * {@inheritdoc} + */ + public abstract function resolve(string $attributeCode): string; + + /** + * {@inheritdoc} + */ + public function getNext(): SpecificationInterface + { + if (!$this->hasNext()) { + throw new NotFoundException(__('Next specification not found.')); + } + + return $this->next; + } + + /** + * {@inheritdoc} + */ + public function hasNext(): bool + { + return null !== $this->next; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php new file mode 100644 index 0000000000000..2e397fbf76c50 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; + +use Magento\Framework\Exception\NotFoundException; + +/** + * Resolve name of type specification. + */ +interface SpecificationInterface +{ + /** + * Get specification name. + * + * @param string $attributeCode + * @return string + */ + public function resolve(string $attributeCode): string; + + /** + * Get next specification. + * + * @return SpecificationInterface + * @throws NotFoundException + */ + public function getNext(): SpecificationInterface; + + /** + * Check if next specification present. + * + * @return bool + */ + public function hasNext(): bool; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php new file mode 100644 index 0000000000000..93334bf4c40c3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Pool of field name resolvers. + */ +class FieldNameResolverPool implements FieldNameResolverPoolInterface +{ + /** + * @var ResolverInterface[] + */ + private $map; + + /** + * @var SpecificationInterface + */ + private $specification; + + /** + * @param SpecificationInterface $specification + * @param array $map + */ + public function __construct( + SpecificationInterface $specification, + array $map + ) { + $this->specification = $specification; + $this->map = $map; + } + + /** + * Get field name resolver. + * + * @param string $attributeCode + * @param array $context + * @return ResolverInterface + */ + public function getResolver(string $attributeCode, $context = []): ResolverInterface + { + $specification = $this->specification->resolve($attributeCode, $context); + if (!isset($this->map[$specification])) { + $specification = 'default'; + } + + return $this->map[$specification]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php index 12645d0341417..e78983c62f6d2 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -6,11 +6,7 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use \Magento\Customer\Model\Session as CustomerSession; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper as Elasticsearch5ProductFieldMapper; use Magento\Elasticsearch\Model\Adapter\FieldType; @@ -21,76 +17,12 @@ class ProductFieldMapper extends Elasticsearch5ProductFieldMapper implements FieldMapperInterface { /** - * @param Config $eavConfig - * @param FieldType $fieldType - * @param CustomerSession $customerSession - * @param StoreManager $storeManager - * @param Registry $coreRegistry - */ - public function __construct( - Config $eavConfig, - FieldType $fieldType, - CustomerSession $customerSession, - StoreManager $storeManager, - Registry $coreRegistry - ) { - $this->eavConfig = $eavConfig; - $this->fieldType = $fieldType; - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; - } - - /** - * Get field name. - * - * @param string $attributeCode - * @param array $context - * @return string - */ - public function getFieldName($attributeCode, $context = []) - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute || in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - if ($attributeCode === 'price') { - return $this->getPriceFieldName($context); - } - if ($attributeCode === 'position') { - return $this->getPositionFiledName($context); - } - $fieldType = $this->fieldType->getFieldType($attribute); - $frontendInput = $attribute->getFrontendInput(); - if (empty($context['type'])) { - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if ($fieldType === 'string') { - return $this->getFieldName( - $attributeCode, - array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) - ); - } - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { - $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); - } else { - $fieldName = 'sort_' . $attributeCode; - } - - return $fieldName; - } - - /** - * Get all attributes types. - * - * @param array $context * @return array */ - public function getAllAttributesTypes($context = []) + private function getAllStaticAttributesTypes() { - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); $allAttributes = []; + $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); // List of attributes which are required to be indexable $alwaysIndexableAttributes = [ 'category_ids', @@ -122,25 +54,4 @@ public function getAllAttributesTypes($context = []) return $allAttributes; } - - /** - * Get refined field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string - */ - protected function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) - { - switch ($frontendInput) { - case 'select': - case 'multiselect': - return in_array($fieldType, ['string','integer'], true) ? $attributeCode . '_value' : $attributeCode; - case 'boolean': - return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; - default: - return $attributeCode; - } - } } diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 0cfaba845fd6a..b27f4d7e42118 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,6 +7,8 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -271,4 +273,42 @@ </argument> </arguments> </type> + <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute</argument> + <argument name="map" xsi:type="array"> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Special</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</item> + </argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\DummySpecification</argument> + </arguments> + </type> </config> From 7c40efce41f49a0c84fb4200a5fa63295464716c Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 18 Sep 2018 10:14:07 +0300 Subject: [PATCH 0122/1415] MAGETWO-94482: Fixed procedure of creating mapping for dynamic fields in elasticsearch - refactor --- .../FieldMapper/ProductFieldMapper.php | 14 ++--- .../FieldNameResolverPoolInterface.php | 23 -------- .../FieldName/Resolver/CategoryName.php | 13 ++++- .../FieldName/Resolver/DefaultResolver.php | 7 ++- .../FieldName/Resolver/NotEavAttribute.php | 28 +++++++++- .../Product/FieldName/Resolver/Position.php | 13 ++++- .../Product/FieldName/Resolver/Price.php | 19 +++++-- .../Resolver.php} | 22 ++++---- .../FieldName/Resolver/SpecialAttribute.php | 10 +++- .../Product/FieldName/ResolverInterface.php | 22 +++++++- .../Specification/CategoryNameAttribute.php | 29 ---------- .../Specification/DummySpecification.php | 25 --------- .../Specification/NotEavAttribute.php | 47 ---------------- .../Specification/PositionAttribute.php | 29 ---------- .../Specification/PriceAttribute.php | 29 ---------- .../Specification/SpecialAttribute.php | 29 ---------- .../FieldName/SpecificationInterface.php | 38 ------------- .../Product/FieldNameResolverPool.php | 56 ------------------- app/code/Magento/Elasticsearch/etc/di.xml | 36 ++++-------- 19 files changed, 120 insertions(+), 369 deletions(-) delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/{Specification/Specification.php => Resolver/Resolver.php} (53%) delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 247eb624b2a56..87112032e1e27 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -9,7 +9,7 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -51,29 +51,29 @@ class ProductFieldMapper implements FieldMapperInterface private $searchCriteriaBuilder; /** - * @var FieldNameResolverPoolInterface + * @var ResolverInterface */ - private $fieldNameResolverPool; + private $fieldNameResolver; /** * @param Config $eavConfig * @param FieldType $fieldType * @param GroupRepositoryInterface $groupRepository * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param FieldNameResolverPoolInterface $fieldNameResolverPool + * @param ResolverInterface $fieldNameResolver */ public function __construct( Config $eavConfig, FieldType $fieldType, GroupRepositoryInterface $groupRepository, SearchCriteriaBuilder $searchCriteriaBuilder, - FieldNameResolverPoolInterface $fieldNameResolverPool + ResolverInterface $fieldNameResolver ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->fieldNameResolverPool = $fieldNameResolverPool; + $this->fieldNameResolver = $fieldNameResolver; } /** @@ -85,7 +85,7 @@ public function __construct( */ public function getFieldName($attributeCode, $context = []) { - return $this->fieldNameResolverPool->getResolver($attributeCode)->getFieldName($attributeCode, $context); + return $this->fieldNameResolver->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php deleted file mode 100644 index 50172e8381d59..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Identify field name resolver for attribute. - */ -interface FieldNameResolverPoolInterface -{ - /** - * Get field name resolver. - * - * @param string $attributeCode - * @param array $context - * @return ResolverInterface - */ - public function getResolver(string $attributeCode, $context = []) : ResolverInterface; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php index 8b3c79f66e38a..9e012c1427218 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php @@ -13,7 +13,7 @@ /** * Resolver field name for Category name attribute. */ -class CategoryName implements ResolverInterface +class CategoryName extends Resolver implements ResolverInterface { /** * @var StoreManager @@ -26,13 +26,16 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** + * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + ResolverInterface $resolver, StoreManager $storeManager, Registry $coreRegistry ) { + parent::__construct($resolver); $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; } @@ -40,9 +43,13 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return 'name_category_' . $this->resolveCategoryId($context); + if ($attributeCode === 'category_name') { + return 'name_category_' . $this->resolveCategoryId($context); + } + + return $this->getNext()->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php index d62354daf7638..afc0b6a0c6f99 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php @@ -15,7 +15,7 @@ /** * Default name resolver. */ -class DefaultResolver implements ResolverInterface +class DefaultResolver extends Resolver implements ResolverInterface { /** * @var Config @@ -28,13 +28,16 @@ class DefaultResolver implements ResolverInterface private $fieldType; /** + * @param ResolverInterface $resolver * @param Config $eavConfig * @param FieldType $fieldType */ public function __construct( + ResolverInterface $resolver, Config $eavConfig, FieldType $fieldType ) { + parent::__construct($resolver); $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; } @@ -42,7 +45,7 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); $fieldType = $this->fieldType->getFieldType($attribute); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php index 3c19ab7e216cc..8c8b58943a5b3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php @@ -7,17 +7,39 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Eav\Model\Config; /** * Resolver field name for not EAV attribute. */ -class NotEavAttribute implements ResolverInterface +class NotEavAttribute extends Resolver implements ResolverInterface { + /** + * @var Config + */ + private $eavConfig; + + /** + * @param ResolverInterface $resolver + * @param Config $eavConfig + */ + public function __construct(ResolverInterface $resolver, Config $eavConfig) + { + parent::__construct($resolver); + $this->eavConfig = $eavConfig; + } + /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return $attributeCode; + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (!$attribute) { + return $attributeCode; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php index 8082e48e57b5e..d4839012f0b8c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php @@ -13,7 +13,7 @@ /** * Resolver field name for position attribute. */ -class Position implements ResolverInterface +class Position extends Resolver implements ResolverInterface { /** * @var StoreManager @@ -26,13 +26,16 @@ class Position implements ResolverInterface private $coreRegistry; /** + * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + ResolverInterface $resolver, StoreManager $storeManager, Registry $coreRegistry ) { + parent::__construct($resolver); $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; } @@ -40,9 +43,13 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return 'position_category_' . $this->resolveCategoryId($context); + if ($attributeCode === 'position') { + return 'position_category_' . $this->resolveCategoryId($context); + } + + return $this->getNext()->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php index 0a09740e9747d..ea64972868d0a 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php @@ -12,7 +12,7 @@ /** * Resolver field name for price attribute. */ -class Price implements ResolverInterface +class Price extends Resolver implements ResolverInterface { /** * @var CustomerSession @@ -20,23 +20,30 @@ class Price implements ResolverInterface private $customerSession; /** + * @param ResolverInterface $resolver * @param CustomerSession $customerSession */ public function __construct( + ResolverInterface $resolver, CustomerSession $customerSession ) { + parent::__construct($resolver); $this->customerSession = $customerSession; } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); + if ($attributeCode === 'price') { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); - return 'price_' . $customerGroupId; + return 'price_' . $customerGroupId; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php similarity index 53% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php index 86462e31a7b58..492fc70848530 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php @@ -4,41 +4,41 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; use Magento\Framework\Exception\NotFoundException; /** - * Abstract class for resolving type of specification. + * Abstract class for resolving field name. */ -abstract class Specification implements SpecificationInterface +abstract class Resolver implements ResolverInterface { /** - * @var SpecificationInterface + * @var ResolverInterface */ private $next; /** - * @param SpecificationInterface $specification + * @param ResolverInterface $resolver */ - public function __construct(SpecificationInterface $specification) + public function __construct(ResolverInterface $resolver) { - $this->next = $specification; + $this->next = $resolver; } /** * {@inheritdoc} */ - public abstract function resolve(string $attributeCode): string; + public abstract function getFieldName($attributeCode, $context = []): string; /** * {@inheritdoc} */ - public function getNext(): SpecificationInterface + public function getNext(): ResolverInterface { if (!$this->hasNext()) { - throw new NotFoundException(__('Next specification not found.')); + throw new NotFoundException(__('Next resolver not found.')); } return $this->next; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php index 5318797db5f07..518cd548536b2 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php @@ -11,13 +11,17 @@ /** * Resolver field name for not special attribute. */ -class SpecialAttribute implements ResolverInterface +class SpecialAttribute extends Resolver implements ResolverInterface { /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return $attributeCode; + if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { + return $attributeCode; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php index 8b04bd281a71f..0b7bc187ecd68 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php @@ -6,6 +6,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; +use Magento\Framework\Exception\NotFoundException; + +/** + * Field name resolver interface. + */ interface ResolverInterface { /** @@ -15,5 +20,20 @@ interface ResolverInterface * @param array $context * @return string */ - public function getFieldName($attributeCode, $context = []); + public function getFieldName($attributeCode, $context = []): string; + + /** + * Get next resolver. + * + * @return ResolverInterface + * @throws NotFoundException + */ + public function getNext(): ResolverInterface; + + /** + * Check if next resolver present. + * + * @return bool + */ + public function hasNext(): bool; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php deleted file mode 100644 index 918f465569a7f..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the category name attribute. - */ -class CategoryNameAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'CATEGORY_NAME_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'category_name') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php deleted file mode 100644 index 1c003e64683a8..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Dummy specification. - */ -class DummySpecification extends Specification implements SpecificationInterface -{ - const TYPE = 'DUMMY'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - return self::TYPE; - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php deleted file mode 100644 index 27da660c54c9e..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; - -/** - * Class ProductFieldMapper - */ -class NotEavAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'NOT_EAV_ATTRIBUTE'; - - /** - * @var Config - */ - private $eavConfig; - - /** - * @param SpecificationInterface $specification - * @param Config $eavConfig - */ - public function __construct(SpecificationInterface $specification, Config $eavConfig) - { - parent::__construct($specification); - $this->eavConfig = $eavConfig; - } - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute) { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php deleted file mode 100644 index 0af6ea796e042..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the position attribute. - */ -class PositionAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'POSITION_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'position') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php deleted file mode 100644 index ead561c0d5f8a..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the price attribute. - */ -class PriceAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'PRICE_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'price') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php deleted file mode 100644 index c96e447ea7cc5..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the special attributes. - */ -class SpecialAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'SPECIAL_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php deleted file mode 100644 index 2e397fbf76c50..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; - -use Magento\Framework\Exception\NotFoundException; - -/** - * Resolve name of type specification. - */ -interface SpecificationInterface -{ - /** - * Get specification name. - * - * @param string $attributeCode - * @return string - */ - public function resolve(string $attributeCode): string; - - /** - * Get next specification. - * - * @return SpecificationInterface - * @throws NotFoundException - */ - public function getNext(): SpecificationInterface; - - /** - * Check if next specification present. - * - * @return bool - */ - public function hasNext(): bool; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php deleted file mode 100644 index 93334bf4c40c3..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Pool of field name resolvers. - */ -class FieldNameResolverPool implements FieldNameResolverPoolInterface -{ - /** - * @var ResolverInterface[] - */ - private $map; - - /** - * @var SpecificationInterface - */ - private $specification; - - /** - * @param SpecificationInterface $specification - * @param array $map - */ - public function __construct( - SpecificationInterface $specification, - array $map - ) { - $this->specification = $specification; - $this->map = $map; - } - - /** - * Get field name resolver. - * - * @param string $attributeCode - * @param array $context - * @return ResolverInterface - */ - public function getResolver(string $attributeCode, $context = []): ResolverInterface - { - $specification = $this->specification->resolve($attributeCode, $context); - if (!isset($this->map[$specification])) { - $specification = 'default'; - } - - return $this->map[$specification]; - } -} diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index b27f4d7e42118..18772756b12a2 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,8 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -273,42 +272,29 @@ </argument> </arguments> </type> - <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute</argument> - <argument name="map" xsi:type="array"> - <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Special</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</item> - </argument> - </arguments> - </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute"> - <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\DummySpecification</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</argument> </arguments> </type> </config> From b871ea91610bd14c57ee99aa520ed7350c65b584 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <strpwebstudio@gmail.com> Date: Tue, 18 Sep 2018 10:34:27 +0300 Subject: [PATCH 0123/1415] #17744 Adding logic to get default billing address Fixed var declaration --- .../view/frontend/web/js/model/checkout-data-resolver.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6f4c99438610b..142f6af91cc29 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -218,8 +218,8 @@ define([ * Apply resolved billing address to quote */ applyBillingAddress: function () { - var shippingAddress; - var isBillingAddressInitialized; + var shippingAddress, + isBillingAddressInitialized; if (quote.billingAddress()) { selectBillingAddress(quote.billingAddress()); From 540397d5f61fa76d1f6bc64c0c36dc4baaeebb40 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Tue, 18 Sep 2018 12:32:24 +0200 Subject: [PATCH 0124/1415] MC-4189: IE11 - PageBuilder Does Not Load - Fix IE 11 loading of TinyMCE --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js index 223c6d6ab04ea..06943b25de55e 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js @@ -30,7 +30,7 @@ define([ _.bindAll(this, 'openFileBrowser'); - config = Object.assign({}, baseConfig, config || {}); + config = _.extend({}, baseConfig, config || {}); this.wysiwygInstance = new WysiwygInstancePrototype(htmlId, config); this.wysiwygInstance.eventBus = this.eventBus = new window.varienEvents(); }, From beb1f0cd690209a7d71c01482c8627775944363e Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Tue, 18 Sep 2018 13:24:21 +0200 Subject: [PATCH 0125/1415] MC-4189: IE11 - PageBuilder Does Not Load - Update WeakMap polyfill to resolve stack memory errors in IE 11 --- lib/web/es6-collections.js | 273 +++++++------------------------------ 1 file changed, 46 insertions(+), 227 deletions(-) diff --git a/lib/web/es6-collections.js b/lib/web/es6-collections.js index 50ff560e53a8a..ed8e80c1fd07e 100644 --- a/lib/web/es6-collections.js +++ b/lib/web/es6-collections.js @@ -1,227 +1,46 @@ -(function (exports) {'use strict'; - //shared pointer - var i; - //shortcuts - var defineProperty = Object.defineProperty, is = function(a,b) { return isNaN(a)? isNaN(b): a === b; }; - - - //Polyfill global objects - if (typeof WeakMap == 'undefined') { - exports.WeakMap = createCollection({ - // WeakMap#delete(key:void*):boolean - 'delete': sharedDelete, - // WeakMap#clear(): - clear: sharedClear, - // WeakMap#get(key:void*):void* - get: sharedGet, - // WeakMap#has(key:void*):boolean - has: mapHas, - // WeakMap#set(key:void*, value:void*):void - set: sharedSet - }, true); - } - - if (typeof Map == 'undefined' || typeof ((new Map).values) !== 'function' || !(new Map).values().next) { - exports.Map = createCollection({ - // WeakMap#delete(key:void*):boolean - 'delete': sharedDelete, - //:was Map#get(key:void*[, d3fault:void*]):void* - // Map#has(key:void*):boolean - has: mapHas, - // Map#get(key:void*):boolean - get: sharedGet, - // Map#set(key:void*, value:void*):void - set: sharedSet, - // Map#keys(void):Iterator - keys: sharedKeys, - // Map#values(void):Iterator - values: sharedValues, - // Map#entries(void):Iterator - entries: mapEntries, - // Map#forEach(callback:Function, context:void*):void ==> callback.call(context, key, value, mapObject) === not in specs` - forEach: sharedForEach, - // Map#clear(): - clear: sharedClear - }); - } - - if (typeof Set == 'undefined' || typeof ((new Set).values) !== 'function' || !(new Set).values().next) { - exports.Set = createCollection({ - // Set#has(value:void*):boolean - has: setHas, - // Set#add(value:void*):boolean - add: sharedAdd, - // Set#delete(key:void*):boolean - 'delete': sharedDelete, - // Set#clear(): - clear: sharedClear, - // Set#keys(void):Iterator - keys: sharedValues, // specs actually say "the same function object as the initial value of the values property" - // Set#values(void):Iterator - values: sharedValues, - // Set#entries(void):Iterator - entries: setEntries, - // Set#forEach(callback:Function, context:void*):void ==> callback.call(context, value, index) === not in specs - forEach: sharedForEach - }); - } - - if (typeof WeakSet == 'undefined') { - exports.WeakSet = createCollection({ - // WeakSet#delete(key:void*):boolean - 'delete': sharedDelete, - // WeakSet#add(value:void*):boolean - add: sharedAdd, - // WeakSet#clear(): - clear: sharedClear, - // WeakSet#has(value:void*):boolean - has: setHas - }, true); - } - - - /** - * ES6 collection constructor - * @return {Function} a collection class - */ - function createCollection(proto, objectOnly){ - function Collection(a){ - if (!this || this.constructor !== Collection) return new Collection(a); - this._keys = []; - this._values = []; - this._itp = []; // iteration pointers - this.objectOnly = objectOnly; - - //parse initial iterable argument passed - if (a) init.call(this, a); - } - - //define size for non object-only collections - if (!objectOnly) { - defineProperty(proto, 'size', { - get: sharedSize - }); - } - - //set prototype - proto.constructor = Collection; - Collection.prototype = proto; - - return Collection; - } - - - /** parse initial iterable argument passed */ - function init(a){ - var i; - //init Set argument, like `[1,2,3,{}]` - if (this.add) - a.forEach(this.add, this); - //init Map argument like `[[1,2], [{}, 4]]` - else - a.forEach(function(a){this.set(a[0],a[1])}, this); - } - - - /** delete */ - function sharedDelete(key) { - if (this.has(key)) { - this._keys.splice(i, 1); - this._values.splice(i, 1); - // update iteration pointers - this._itp.forEach(function(p) { if (i < p[0]) p[0]--; }); - } - // Aurora here does it while Canary doesn't - return -1 < i; - }; - - function sharedGet(key) { - return this.has(key) ? this._values[i] : undefined; - } - - function has(list, key) { - if (this.objectOnly && key !== Object(key)) - throw new TypeError("Invalid value used as weak collection key"); - //NaN or 0 passed - if (key != key || key === 0) for (i = list.length; i-- && !is(list[i], key);){} - else i = list.indexOf(key); - return -1 < i; - } - - function setHas(value) { - return has.call(this, this._values, value); - } - - function mapHas(value) { - return has.call(this, this._keys, value); - } - - /** @chainable */ - function sharedSet(key, value) { - this.has(key) ? - this._values[i] = value - : - this._values[this._keys.push(key) - 1] = value - ; - return this; - } - - /** @chainable */ - function sharedAdd(value) { - if (!this.has(value)) this._values.push(value); - return this; - } - - function sharedClear() { - this._values.length = 0; - } - - /** keys, values, and iterate related methods */ - function sharedKeys() { - return sharedIterator(this._itp, this._keys); - } - - function sharedValues() { - return sharedIterator(this._itp, this._values); - } - - function mapEntries() { - return sharedIterator(this._itp, this._keys, this._values); - } - - function setEntries() { - return sharedIterator(this._itp, this._values, this._values); - } - - function sharedIterator(itp, array, array2) { - var p = [0], done = false; - itp.push(p); - return { - next: function() { - var v, k = p[0]; - if (!done && k < array.length) { - v = array2 ? [array[k], array2[k]]: array[k]; - p[0]++; - } else { - done = true; - itp.splice(itp.indexOf(p), 1); - } - return { done: done, value: v }; - } - }; - } - - function sharedSize() { - return this._values.length; - } - - function sharedForEach(callback, context) { - var it = this.entries(); - for (;;) { - var r = it.next(); - if (r.done) break; - callback.call(context, r.value[1], r.value[0], this); - } - } - -})(typeof exports != 'undefined' && typeof global != 'undefined' ? global : window ); \ No newline at end of file +/* + * Copyright 2012 The Polymer Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +if (typeof WeakMap === 'undefined') { + (function() { + var defineProperty = Object.defineProperty; + var counter = Date.now() % 1e9; + + var WeakMap = function() { + this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); + }; + + WeakMap.prototype = { + set: function(key, value) { + var entry = key[this.name]; + if (entry && entry[0] === key) + entry[1] = value; + else + defineProperty(key, this.name, {value: [key, value], writable: true}); + return this; + }, + get: function(key) { + var entry; + return (entry = key[this.name]) && entry[0] === key ? + entry[1] : undefined; + }, + delete: function(key) { + var entry = key[this.name]; + if (!entry) return false; + var hasValue = entry[0] === key; + entry[0] = entry[1] = undefined; + return hasValue; + }, + has: function(key) { + var entry = key[this.name]; + if (!entry) return false; + return entry[0] === key; + } + }; + + window.WeakMap = WeakMap; + })(); +} \ No newline at end of file From 02ab61cc1a9ac377aca9d7b2d488fcd2a3858da6 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Sat, 15 Sep 2018 13:32:00 +0300 Subject: [PATCH 0126/1415] MAGETWO-59265: Import doesn't allow to set default value per store view (dropdown fields) - Changed logic of setting default value of attributes type "select" --- .../Model/Import/Product/Type/AbstractType.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php index afd018f077d20..8b04b7ec3532f 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php @@ -195,6 +195,8 @@ public function __construct( } /** + * Initialize template for error message. + * * @param array $templateCollection * @return $this */ @@ -377,6 +379,8 @@ public function retrieveAttributeFromCache($attributeCode) } /** + * Adding attribute option. + * * In case we've dynamically added new attribute option during import we need to add it to our cache * in order to keep it up to date. * @@ -508,8 +512,10 @@ public function isSuitable() } /** - * Prepare attributes values for save: exclude non-existent, static or with empty values attributes; - * set default values if needed + * Adding default attribute to product before save. + * + * Prepare attributes values for save: exclude non-existent, static or with empty values attributes, + * set default values if needed. * * @param array $rowData * @param bool $withDefaultValue @@ -539,7 +545,8 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe } } elseif (array_key_exists($attrCode, $rowData)) { $resultAttrs[$attrCode] = $rowData[$attrCode]; - } elseif ($withDefaultValue && null !== $attrParams['default_value']) { + } elseif ($withDefaultValue && null !== $attrParams['default_value'] + && 'select' == $attrParams['type'] && null === $rowData['_store']) { $resultAttrs[$attrCode] = $attrParams['default_value']; } } @@ -611,7 +618,8 @@ protected function getProductEntityLinkField() } /** - * Clean cached values + * Clean cached values. + * * @since 100.2.0 */ public function __destruct() From a63bd68321b3cab035b98876be34c5bf60581254 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Tue, 18 Sep 2018 16:59:41 +0300 Subject: [PATCH 0127/1415] MAGETWO-91614: Cannot filter customers by status - Add new locators --- .../Section/AdminCustomerAccountInformationSection.xml | 7 +++++++ .../Test/Mftf/Section/AdminCustomerFiltersSection.xml | 3 +++ 2 files changed, 10 insertions(+) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index a485069341a03..41547806e70e3 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -9,10 +9,17 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerAccountInformationSection"> + <element name="statusInactive" type="button" selector=".admin__actions-switch-label"/> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> + <element name="accountInformationButton" type="text" selector="//a/span[text()='Account Information']"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> <element name="group" type="select" selector="[name='customer[group_id]']"/> + <element name="groupValue" type="button" selector="//span[text()='{{groupValue}}']" parameterized="true"/> + <element name="associateToWebsite" type="select" selector="//select[@name='customer[website_id]']"/> + <element name="saveCustomer" type="button" selector="//button[@title='Save Customer']"/> + <element name="storeView" type="select" selector="//select[@name='customer[sendemail_store_id]']"/> + <element name="statusInactive" type="button" selector=".admin__actions-switch-label"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml index bfff885bcbbe1..1c43dd6fe63db 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml @@ -9,10 +9,13 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerFiltersSection"> + <element name="customerStatus" type="button" selector="select[name='status']"/> <element name="filtersButton" type="button" selector="#container > div > div.admin__data-grid-header > div:nth-child(1) > div.data-grid-filters-actions-wrap > div > button" timeout="30"/> <element name="nameInput" type="input" selector="input[name=name]"/> <element name="emailInput" type="input" selector="input[name=email]"/> <element name="apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> <element name="clearAllFilters" type="text" selector=".admin__current-filters-actions-wrap.action-clear"/> + <element name="clearAll" type="button" selector=".action-tertiary.action-clear"/> + <element name="customerStatus" type="button" selector="select[name='status']"/> </section> </sections> From fc80a85de0d29219660c18c47d36866ab377fc97 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 18 Sep 2018 16:05:52 +0200 Subject: [PATCH 0128/1415] Removed temp debug logic --- lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 98e6c840ba682..a6ad10dded849 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,7 +55,6 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - var_dump($this->exceptionFormatter->shouldShowDetail()); if (!$this->exceptionFormatter->shouldShowDetail()) { $this->queryComplexityLimiter->execute(); } From a00e05588001e9e50c26d3902b416f24e756019a Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 18 Sep 2018 09:07:00 -0500 Subject: [PATCH 0129/1415] MAGETWO-90540: MFTF Test failure - Advanced Reporting configuration permission --- .../Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml | 3 --- .../Test/Mftf/Test/AdminConfigurationIndustryTest.xml | 3 --- 2 files changed, 6 deletions(-) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml index d9617209dcdff..1706383fc7866 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml @@ -16,9 +16,6 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-66465"/> <group value="analytics"/> - <skip> - <issueId value="MAGETWO-90659"/> - </skip> </annotations> <after> <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index 2d5594a43b1a7..dcfdca9e8edd7 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -17,9 +17,6 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-63898"/> <group value="analytics"/> - <skip> - <issueId value="MAGETWO-90659"/> - </skip> </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> From e5f051c51a6ebdcdf58137691b061548c321b362 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 13 Sep 2018 17:03:35 +0300 Subject: [PATCH 0130/1415] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed an issue with incorect url rewrites generation for children categories; - Modified unit tests for the new functionality; --- .../Category/ChildrenUrlRewriteGenerator.php | 35 ++++++++++++++----- .../ChildrenUrlRewriteGeneratorTest.php | 19 +++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php index 6aa33f37cd31f..f6049bbff02c4 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php @@ -10,7 +10,11 @@ use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; use Magento\UrlRewrite\Model\MergeDataProviderFactory; use Magento\Framework\App\ObjectManager; +use Magento\Catalog\Api\CategoryRepositoryInterface; +/** + * Model for generate url rewrites for children categories + */ class ChildrenUrlRewriteGenerator { /** @@ -28,15 +32,22 @@ class ChildrenUrlRewriteGenerator */ private $mergeDataProviderPrototype; + /** + * @var CategoryRepositoryInterface + */ + private $categoryRepository; + /** * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider $childrenCategoriesProvider * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory * @param \Magento\UrlRewrite\Model\MergeDataProviderFactory|null $mergeDataProviderFactory + * @param CategoryRepositoryInterface|null $categoryRepository */ public function __construct( ChildrenCategoriesProvider $childrenCategoriesProvider, CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory, - MergeDataProviderFactory $mergeDataProviderFactory = null + MergeDataProviderFactory $mergeDataProviderFactory = null, + CategoryRepositoryInterface $categoryRepository = null ) { $this->childrenCategoriesProvider = $childrenCategoriesProvider; $this->categoryUrlRewriteGeneratorFactory = $categoryUrlRewriteGeneratorFactory; @@ -44,6 +55,8 @@ public function __construct( $mergeDataProviderFactory = ObjectManager::getInstance()->get(MergeDataProviderFactory::class); } $this->mergeDataProviderPrototype = $mergeDataProviderFactory->create(); + $this->categoryRepository = $categoryRepository + ?: ObjectManager::getInstance()->get(CategoryRepositoryInterface::class); } /** @@ -53,18 +66,22 @@ public function __construct( * @param \Magento\Catalog\Model\Category $category * @param int|null $rootCategoryId * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function generate($storeId, Category $category, $rootCategoryId = null) { $mergeDataProvider = clone $this->mergeDataProviderPrototype; - foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) { - $childCategory->setStoreId($storeId); - $childCategory->setData('save_rewrites_history', $category->getData('save_rewrites_history')); - /** @var CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator */ - $categoryUrlRewriteGenerator = $this->categoryUrlRewriteGeneratorFactory->create(); - $mergeDataProvider->merge( - $categoryUrlRewriteGenerator->generate($childCategory, false, $rootCategoryId) - ); + if ($childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true)) { + foreach ($childrenIds as $childId) { + /** @var Category $childCategory */ + $childCategory = $this->categoryRepository->get($childId, $storeId); + $childCategory->setData('save_rewrites_history', $category->getData('save_rewrites_history')); + /** @var CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator */ + $categoryUrlRewriteGenerator = $this->categoryUrlRewriteGeneratorFactory->create(); + $mergeDataProvider->merge( + $categoryUrlRewriteGenerator->generate($childCategory, false, $rootCategoryId) + ); + } } return $mergeDataProvider->getData(); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php index 3f641256b1259..f8422c7c05fa6 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php @@ -31,6 +31,9 @@ class ChildrenUrlRewriteGeneratorTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject */ private $serializerMock; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $categoryRepository; + protected function setUp() { $this->serializerMock = $this->getMockBuilder(Json::class) @@ -47,6 +50,9 @@ protected function setUp() $this->categoryUrlRewriteGenerator = $this->getMockBuilder( \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator::class )->disableOriginalConstructor()->getMock(); + $this->categoryRepository = $this->getMockBuilder( + \Magento\Catalog\Model\CategoryRepository::class + )->disableOriginalConstructor()->getMock(); $mergeDataProviderFactory = $this->createPartialMock( \Magento\UrlRewrite\Model\MergeDataProviderFactory::class, ['create'] @@ -59,14 +65,15 @@ protected function setUp() [ 'childrenCategoriesProvider' => $this->childrenCategoriesProvider, 'categoryUrlRewriteGeneratorFactory' => $this->categoryUrlRewriteGeneratorFactory, - 'mergeDataProviderFactory' => $mergeDataProviderFactory + 'mergeDataProviderFactory' => $mergeDataProviderFactory, + 'categoryRepository' => $this->categoryRepository ] ); } public function testNoChildrenCategories() { - $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, true) + $this->childrenCategoriesProvider->expects($this->once())->method('getChildrenIds')->with($this->category, true) ->will($this->returnValue([])); $this->assertEquals([], $this->childrenUrlRewriteGenerator->generate('store_id', $this->category)); @@ -76,14 +83,16 @@ public function testGenerate() { $storeId = 'store_id'; $saveRewritesHistory = 'flag'; + $childId = 2; $childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor()->getMock(); - $childCategory->expects($this->once())->method('setStoreId')->with($storeId); $childCategory->expects($this->once())->method('setData') ->with('save_rewrites_history', $saveRewritesHistory); - $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, true) - ->will($this->returnValue([$childCategory])); + $this->childrenCategoriesProvider->expects($this->once())->method('getChildrenIds')->with($this->category, true) + ->will($this->returnValue([$childId])); + $this->categoryRepository->expects($this->once())->method('get') + ->with($childId, $storeId)->willReturn($childCategory); $this->category->expects($this->any())->method('getData')->with('save_rewrites_history') ->will($this->returnValue($saveRewritesHistory)); $this->categoryUrlRewriteGeneratorFactory->expects($this->once())->method('create') From 929f82e33639500a400cbdfbc2264aca7cce5bab Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 18 Sep 2018 17:44:35 +0300 Subject: [PATCH 0131/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Update automated test --- .../Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index ecc415585eb16..f0111ede64c9b 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -107,6 +107,8 @@ <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryLoad"/> + <magentoCLI stepKey="runCron" command="cron:run --group='index'"/> + <!-- Wait till cron job runs for schedule updates --> <wait time="60" stepKey="waitForUpdateStarts"/> From 1b9ae1174da8a34ac898ea2bc69cfa39f75eb252 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 18 Sep 2018 15:32:37 +0300 Subject: [PATCH 0132/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixes according to code review. --- .../Block/Product/ProductList/Toolbar.php | 2 ++ .../Framework}/App/Action/ContextPlugin.php | 28 ++++++++----------- .../Magento/Catalog/etc/adminhtml/system.xml | 3 +- app/code/Magento/Catalog/etc/frontend/di.xml | 2 +- 4 files changed, 16 insertions(+), 19 deletions(-) rename app/code/Magento/Catalog/{Model => Plugin/Framework}/App/Action/ContextPlugin.php (60%) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 3e3f86cd7de01..12c691d1365c3 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -150,6 +150,8 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\App\Http\Context|null $httpContext * @param \Magento\Framework\Data\Form\FormKey|null $formKey * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, diff --git a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php b/app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php similarity index 60% rename from app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php rename to app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php index c5ed81540e29e..6add542b15554 100644 --- a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php @@ -6,7 +6,7 @@ declare(strict_types=1); -namespace Magento\Catalog\Model\App\Action; +namespace Magento\Catalog\Plugin\Framework\App\Action; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; @@ -56,21 +56,17 @@ public function __construct( public function beforeDispatch() { if ($this->toolbarMemorizer->isMemorizingAllowed()) { - $order = $this->catalogSession->getData(ToolbarModel::ORDER_PARAM_NAME); - if ($order) { - $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, false); - } - $direction = $this->catalogSession->getData(ToolbarModel::DIRECTION_PARAM_NAME); - if ($direction) { - $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $direction, false); - } - $mode = $this->catalogSession->getData(ToolbarModel::MODE_PARAM_NAME); - if ($mode) { - $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, false); - } - $limit = $this->catalogSession->getData(ToolbarModel::LIMIT_PARAM_NAME); - if ($limit) { - $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, false); + $params = [ + ToolbarModel::ORDER_PARAM_NAME, + ToolbarModel::DIRECTION_PARAM_NAME, + ToolbarModel::MODE_PARAM_NAME, + ToolbarModel::LIMIT_PARAM_NAME + ]; + foreach ($params as $param) { + $paramValue = $this->catalogSession->getData($param); + if ($paramValue) { + $this->httpContext->setValue($param, $paramValue, false); + } } } } diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index be35ae2e5549d..adfe4c735201c 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -94,8 +94,7 @@ </field> <field id="remember_pagination" translate="label comment" type="select" sortOrder="7" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Remember Category Pagination</label> - <comment>Note that SEO and performance experience may be negative by this feature enabled. - Also it will increase cache storage consumption.</comment> + <comment>Changing may affect SEO and cache storage consumption.</comment> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> diff --git a/app/code/Magento/Catalog/etc/frontend/di.xml b/app/code/Magento/Catalog/etc/frontend/di.xml index a1520b66e83dc..ee9c5b29da894 100644 --- a/app/code/Magento/Catalog/etc/frontend/di.xml +++ b/app/code/Magento/Catalog/etc/frontend/di.xml @@ -118,6 +118,6 @@ </type> <type name="Magento\Framework\App\Action\AbstractAction"> <plugin name="catalog_app_action_dispatch_controller_context_plugin" - type="Magento\Catalog\Model\App\Action\ContextPlugin" /> + type="Magento\Catalog\Plugin\Framework\App\Action\ContextPlugin" /> </type> </config> From 1992a368332102563331372d2267f633e3752940 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 18 Sep 2018 17:32:06 +0200 Subject: [PATCH 0133/1415] Travis api-functional testsuite check --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index cc730ca5a2cd4..e909bb1980752 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ env: - TEST_SUITE=integration INTEGRATION_INDEX=2 - TEST_SUITE=integration INTEGRATION_INDEX=3 - TEST_SUITE=functional + - TEST_SUITE=api-functional matrix: exclude: - php: 7.1 From 0c7edc5a71a02bcc6df929ac0d0f7518b18a376b Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 18 Sep 2018 20:35:30 +0400 Subject: [PATCH 0134/1415] MAGETWO-91617: Ordered Products Report Error for restricted scope admin - Add some helpers for automated test --- .../ActionGroup/AdminProductActionGroup.xml | 17 +++++++- ...omerWithWebsiteAndStoreViewActionGroup.xml | 43 +++++++++++++++++++ .../AdminDeleteCustomerActionGroup.xml | 23 ++++++++++ .../Customer/Test/Mftf/Data/AddressData.xml | 1 + ...AdminCustomerAccountInformationSection.xml | 1 + .../Section/AdminCustomerAddressesSection.xml | 24 +++++++++++ .../AdminCustomerGridMainActionsSection.xml | 2 + .../AdminReviewOrderActionGroup.xml | 24 +++++++++++ .../Mftf/Section/OrderedProductsSection.xml | 17 ++++++++ .../ActionGroup/AdminOrderActionGroup.xml | 24 +++++++++++ .../AdminInvoicePaymentShippingSection.xml | 2 + .../AdminOrderStoreScopeTreeSection.xml | 1 + .../Mftf/Section/AdminOrdersGridSection.xml | 2 + .../Test/Mftf/Section/OrdersGridSection.xml | 3 +- .../Store/Test/Mftf/Data/StoreData.xml | 12 ++++++ .../AdminCreateUserActionGroup.xml | 23 ++++++++++ .../AdminDeleteCreatedUserActionGroup.xml | 23 ++++++++++ 17 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml create mode 100644 app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9f8d827b20849..91141a573cf5b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -276,5 +276,20 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptStoreSwitchingMessage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> - + <actionGroup name="CreatedProductConnectToWebsite"> + <arguments> + <argument name="website"/> + <argument name="product"/> + </arguments> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="navigateToProductPage"/> + <waitForPageLoad stepKey="waitForProductsList"/> + <click stepKey="openProduct" selector="{{AdminProductGridActionSection.productName(product.name)}}"/> + <waitForPageLoad stepKey="waitForProductPage"/> + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openWebsitesList"/> + <waitForPageLoad stepKey="waitForWebsitesList"/> + <click selector="{{ProductInWebsitesSection.website(website.name)}}" stepKey="SelectWebsite"/> + <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForSave"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml new file mode 100644 index 0000000000000..0071acf2ef1e0 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateCustomerWithWebsiteAndStoreViewActionGroup"> + <arguments> + <argument name="customerData"/> + <argument name="address"/> + <argument name="website" type="string"/> + <argument name="storeView" type="string"/> + </arguments> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersPage"/> + <click stepKey="addNewCustomer" selector="{{AdminCustomerGridMainActionsSection.addNewCustomer}}"/> + <selectOption stepKey="selectWebSite" selector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" userInput="{{website}}"/> + <fillField stepKey="FillFirstName" selector="{{AdminCustomerAccountInformationSection.firstName}}" userInput="{{customerData.firstname}}"/> + <fillField stepKey="FillLastName" selector="{{AdminCustomerAccountInformationSection.lastName}}" userInput="{{customerData.lastname}}"/> + <fillField stepKey="FillEmail" selector="{{AdminCustomerAccountInformationSection.email}}" userInput="{{customerData.email}}"/> + <selectOption stepKey="selectStoreView" selector="{{AdminCustomerAccountInformationSection.storeView}}" userInput="{{storeView}}"/> + <scrollToTopOfPage stepKey="scrollToTopOfThePage"/> + <click stepKey="goToAddresses" selector="{{AdminCustomerAccountInformationSection.addressesButton}}"/> + <waitForPageLoad stepKey="waitForAddresses"/> + <click stepKey="clickOnAddNewAddress" selector="{{AdminCustomerAddressesSection.addNewAddress}}"/> + <waitForPageLoad stepKey="waitForAddressFields"/> + <click stepKey="thickBillingAddress" selector="{{AdminCustomerAddressesSection.defaultBillingAddress}}"/> + <click stepKey="thickShippingAddress" selector="{{AdminCustomerAddressesSection.defaultShippingAddress}}"/> + <fillField stepKey="fillFirstNameForAddress" selector="{{AdminCustomerAddressesSection.firstNameForAddress}}" userInput="{{address.firstname}}"/> + <fillField stepKey="fillLastNameForAddress" selector="{{AdminCustomerAddressesSection.lastNameForAddress}}" userInput="{{address.lastname}}"/> + <fillField stepKey="fillStreetAddress" selector="{{AdminCustomerAddressesSection.streetAddress}}" userInput="{{address.street[0]}}"/> + <fillField stepKey="fillCity" selector="{{AdminCustomerAddressesSection.city}}" userInput="{{address.city}}"/> + <selectOption stepKey="selectCountry" selector="{{AdminCustomerAddressesSection.country}}" userInput="{{address.country}}"/> + <selectOption stepKey="selectState" selector="{{AdminCustomerAddressesSection.state}}" userInput="{{address.state}}"/> + <fillField stepKey="fillZip" selector="{{AdminCustomerAddressesSection.zip}}" userInput="{{address.postcode}}"/> + <fillField stepKey="fillPhoneNumber" selector="{{AdminCustomerAddressesSection.phoneNumber}}" userInput="{{address.telephone}}"/> + <click stepKey="save" selector="{{AdminCustomerAccountInformationSection.saveCustomer}}"/> + <waitForPageLoad stepKey="waitForCustomersPage"/> + <see stepKey="seeSuccessMessage" userInput="You saved the customer."/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml new file mode 100644 index 0000000000000..68f6b49e80996 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCustomerActionGroup"> + <arguments> + <argument name="customerEmail"/> + </arguments> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomersPage"/> + <click stepKey="chooseCustomer" selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}"/> + <click stepKey="openActions" selector="{{AdminCustomerGridMainActionsSection.actions}}"/> + <waitForPageLoad stepKey="waitActions"/> + <click stepKey="delete" selector="{{AdminCustomerGridMainActionsSection.delete}}"/> + <waitForPageLoad stepKey="waitForConfirmationAlert"/> + <click stepKey="accept" selector="{{AdminCustomerGridMainActionsSection.ok}}"/> + <see stepKey="seeSuccessMessage" userInput="were deleted."/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index d090620145105..033add209a4c2 100755 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -65,6 +65,7 @@ <data key="default_billing">Yes</data> <data key="default_shipping">Yes</data> <requiredEntity type="region">RegionNY</requiredEntity> + <data key="country">United States</data> </entity> <entity name="US_Address_CA" type="address"> <data key="firstname">John</data> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index 32746a66621eb..8510fd385f92b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -11,6 +11,7 @@ <section name="AdminCustomerAccountInformationSection"> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> <element name="accountInformationButton" type="text" selector="//a/span[text()='Account Information']"/> + <element name="addressesButton" type="select" selector="//a//span[contains(text(), 'Addresses')]"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml new file mode 100644 index 0000000000000..175c7ab573d37 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCustomerAddressesSection"> + <element name="addNewAddress" type="button" selector="//span[text()='Add New Addresses']"/> + <element name="defaultBillingAddress" type="button" selector="//label[text()='Default Billing Address']"/> + <element name="defaultShippingAddress" type="button" selector="//label[text()='Default Shipping Address']"/> + <element name="firstNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'firstname')]"/> + <element name="lastNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'lastname')]"/> + <element name="streetAddress" type="button" selector="//input[contains(@name, 'street')]"/> + <element name="city" type="input" selector="//input[contains(@name, 'city')]"/> + <element name="country" type="select" selector="//select[contains(@name, 'country_id')]"/> + <element name="state" type="select" selector="//select[contains(@name, 'address[new_0][region_id]')]"/> + <element name="zip" type="input" selector="//input[contains(@name, 'postcode')]"/> + <element name="phoneNumber" type="input" selector="//input[contains(@name, 'telephone')]"/> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml index 1f0c4b4998a9f..d644b581088bc 100755 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml @@ -13,5 +13,7 @@ <element name="multicheck" type="checkbox" selector="#container>div>div.admin__data-grid-wrap>table>thead>tr>th.data-grid-multicheck-cell>div>label"/> <element name="delete" type="button" selector="//*[contains(@class, 'admin__data-grid-header')]//span[contains(@class,'action-menu-item') and text()='Delete']"/> <element name="actions" type="text" selector=".action-select"/> + <element name="customerCheckbox" type="button" selector="//*[contains(text(),'{{arg}}')]/parent::td/preceding-sibling::td/label[@class='data-grid-checkbox-cell-inner']//input" parameterized="true"/> + <element name="ok" type="button" selector="//button[@data-role='action']//span[text()='OK']"/> </section> </sections> diff --git a/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml b/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml new file mode 100644 index 0000000000000..003a5e6655f34 --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminReviewOrderActionGroup"> + <arguments> + <argument name="productName" type="string"/> + </arguments> + <click stepKey="openReports" selector="{{OrderedProductsSection.reports}}"/> + <waitForPageLoad stepKey="waitForReports" time="5"/> + <click stepKey="openOrdered" selector="{{OrderedProductsSection.ordered}}"/> + <waitForPageLoad stepKey="waitForOrdersPage" time="5"/> + <click stepKey="refresh" selector="{{OrderedProductsSection.refresh}}"/> + <waitForPageLoad stepKey="waitForOrderList" time="5"/> + <scrollTo stepKey="scrollTo" selector="{{OrderedProductsSection.total}}"/> + <see stepKey="seeOrder" userInput="{{productName}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml new file mode 100644 index 0000000000000..89e8497dddcea --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="OrderedProductsSection"> + <element name="reports" type="button" selector="//li[@data-ui-id='menu-magento-reports-report']"/> + <element name="ordered" type="button" selector="//li[@data-ui-id='menu-magento-reports-report-products-sold']"/> + <element name="refresh" type="button" selector="//button[@title='Refresh']" timeout="30"/> + <element name="total" type="text" selector="//tfoot//th[contains(text(), 'Total')]"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index c82623632d782..ffa6a2a5f2d99 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -268,4 +268,28 @@ <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> </actionGroup> + + <actionGroup name="CreateOrderInStoreActionGroup"> + <arguments> + <argument name="product"/> + <argument name="customer"/> + <argument name="storeView"/> + </arguments> + <amOnPage stepKey="navigateToNewOrderPage" url="{{AdminOrderCreatePage.url}}"/> + <click stepKey="chooseCustomer" selector="{{AdminOrdersGridSection.customerInOrdersSection(customer.firstname)}}"/> + <waitForPageLoad stepKey="waitForStoresPageOpened"/> + <click stepKey="chooseStore" selector="{{AdminOrderStoreScopeTreeSection.storeForOrder(storeView.name)}}"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickOnAddProducts"/> + <waitForPageLoad stepKey="waitForProductsListForOrder"/> + <click selector="{{AdminOrdersGridSection.productForOrder(product.sku)}}" stepKey="chooseTheProduct"/> + <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="addSelectedProductToOrder"/> + <waitForPageLoad stepKey="waitForProductAddedInOrder"/> + <click selector="{{AdminInvoicePaymentShippingSection.getShippingMethodAndRates}}" stepKey="openShippingMethod"/> + <waitForPageLoad stepKey="waitForShippingMethods"/> + <click selector="{{AdminInvoicePaymentShippingSection.shippingMethod}}" stepKey="chooseShippingMethod"/> + <waitForPageLoad stepKey="waitForShippingMethodsThickened"/> + <click selector="{{OrdersGridSection.submitOrder}}" stepKey="submitOrder"/> + <see stepKey="seeSuccessMessageForOrder" userInput="You created the order."/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml index 918a8e814b555..8d7c64733972e 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml @@ -15,5 +15,7 @@ <element name="ShippingMethod" type="text" selector=".order-shipping-address .shipping-description-title"/> <element name="ShippingPrice" type="text" selector=".order-shipping-address .shipping-description-content .price"/> <element name="CreateShipment" type="checkbox" selector=".order-shipping-address input[name='invoice[do_shipment]']"/> + <element name="getShippingMethodAndRates" type="button" selector="//span[text()='Get shipping methods and rates']"/> + <element name="shippingMethod" type="button" selector="//label[contains(text(), 'Fixed')]"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml index 050e1ba8b2df4..cbe17499319f9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml @@ -11,5 +11,6 @@ <section name="AdminOrderStoreScopeTreeSection"> <element name="storeTree" type="text" selector="div.tree-store-scope"/> <element name="storeOption" type="radio" selector="//div[contains(@class, 'tree-store-scope')]//label[contains(text(), '{{name}}')]/preceding-sibling::input" parameterized="true" timeout="30"/> + <element name="storeForOrder" type="radio" selector="//div[contains(@class, 'tree-store-scope')]//label[contains(text(), '{{arg}}')]" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml index 7ece18fb863b7..53a6cbffcdac6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml @@ -29,5 +29,7 @@ <element name="viewBookmark" type="button" selector="//div[contains(@class, 'admin__data-grid-action-bookmarks')]/ul/li/div/a[text() = '{{label}}']" parameterized="true" timeout="30"/> <element name="columnsDropdown" type="button" selector="div.admin__data-grid-action-columns button" timeout="30"/> <element name="viewColumnCheckbox" type="checkbox" selector="//div[contains(@class,'admin__data-grid-action-columns')]//div[contains(@class, 'admin__field-option')]//label[text() = '{{column}}']/preceding-sibling::input" parameterized="true"/> + <element name="customerInOrdersSection" type="button" selector="(//td[contains(text(),'{{customer}}')])[1]" parameterized="true"/> + <element name="productForOrder" type="button" selector="//td[contains(text(),'{{var}}')]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml index 8d99bf4872d0a..717022322698f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml @@ -18,7 +18,7 @@ <element name="createNewOrder" type="button" selector="button[title='Create New Order'"/> <element name="website" type="radio" selector="//label[contains(text(), '{{arg}}')]" parameterized="true"/> - <element name="addProducts" type="button" selector="//span[text()='Add Products']"/> + <element name="addProducts" type="button" selector="#add_products"/> <element name="selectProduct" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-select col-in_products')]" parameterized="true"/> <element name="setQuantity" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-qty')]/input" parameterized="true"/> <element name="addProductsToOrder" type="button" selector="//span[text()='Add Selected Product(s) to Order']"/> @@ -29,5 +29,6 @@ <element name="productPrice" type="text" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td[@class='col-price col-row-subtotal']/span" parameterized="true"/> <element name="removeItems" type="select" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td/select[@class='admin__control-select']" parameterized="true"/> <element name="applyCoupon" type="input" selector="#coupons:code"/> + <element name="submitOrder" type="button" selector="#submit_order_top_button"/> </section> </sections> diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml index 2bff20e05435a..b0f04dbe703a9 100644 --- a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml +++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml @@ -49,4 +49,16 @@ <data key="store_type">store</data> <requiredEntity type="storeGroup">customStoreGroup</requiredEntity> </entity> + <entity name="NewStoreData" type="store"> + <data key="name" unique="suffix">Store</data> + <data key="code" unique="suffix">StoreCode</data> + </entity> + <entity name="NewWebSiteData" type="webSite"> + <data key="name" unique="suffix">WebSite</data> + <data key="code" unique="suffix">WebSiteCode</data> + </entity> + <entity name="NewStoreViewData"> + <data key="name" unique="suffix">StoreView</data> + <data key="code" unique="suffix">StoreViewCode</data> + </entity> </entities> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml index de887d2de6704..9a0fa4a205799 100644 --- a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml @@ -31,4 +31,27 @@ <waitForPageLoad stepKey="waitForPageLoad2" /> <see userInput="You saved the user." stepKey="seeSuccessMessage" /> </actionGroup> + + <!--Create new user with role--> + <actionGroup name="AdminCreateUserWithRoleActionGroup"> + <arguments> + <argument name="role"/> + <argument name="user" defaultValue="newAdmin"/> + </arguments> + <amOnPage url="{{AdminEditUserPage.url}}" stepKey="navigateToNewUser"/> + <waitForPageLoad stepKey="waitForUsersPage" /> + <fillField selector="{{AdminCreateUserSection.usernameTextField}}" userInput="{{user.username}}" stepKey="enterUserName" /> + <fillField selector="{{AdminCreateUserSection.firstNameTextField}}" userInput="{{user.firstName}}" stepKey="enterFirstName" /> + <fillField selector="{{AdminCreateUserSection.lastNameTextField}}" userInput="{{user.lastName}}" stepKey="enterLastName" /> + <fillField selector="{{AdminCreateUserSection.emailTextField}}" userInput="{{user.username}}@magento.com" stepKey="enterEmail" /> + <fillField selector="{{AdminCreateUserSection.passwordTextField}}" userInput="{{user.password}}" stepKey="enterPassword" /> + <fillField selector="{{AdminCreateUserSection.pwConfirmationTextField}}" userInput="{{user.password}}" stepKey="confirmPassword" /> + <fillField selector="{{AdminCreateUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterCurrentPassword" /> + <scrollToTopOfPage stepKey="scrollToTopOfPage" /> + <click stepKey="clickUserRole" selector="{{AdminCreateUserSection.userRoleTab}}"/> + <click stepKey="chooseRole" selector="{{AdminStoreSection.createdRoleInUserPage(role.name)}}"/> + <click selector="{{AdminCreateUserSection.saveButton}}" stepKey="clickSaveUser" /> + <waitForPageLoad stepKey="waitForSaveTheUser" /> + <see userInput="You saved the user." stepKey="seeSuccessMessage" /> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml new file mode 100644 index 0000000000000..7f1ed3be1ca57 --- /dev/null +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCreatedUserActionGroup"> + <arguments> + <argument name="user"/> + </arguments> + <amOnPage stepKey="amOnAdminUsersPage" url="{{AdminUsersPage.url}}"/> + <click stepKey="openTheUser" selector="{{AdminDeleteUserSection.role(user.username)}}"/> + <fillField stepKey="TypeCurrentPassword" selector="{{AdminDeleteUserSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="clickToDeleteUser" selector="{{AdminDeleteUserSection.delete}}"/> + <waitForPageLoad stepKey="waitForConfirmationPopup"/> + <click stepKey="clickToConfirm" selector="{{AdminDeleteUserSection.confirm}}"/> + <see stepKey="seeDeleteMessageForUser" userInput="You deleted the user."/> + </actionGroup> +</actionGroups> From 7674152461aeaee9de3b53534c2868c83f0dc2af Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Tue, 18 Sep 2018 21:31:21 +0300 Subject: [PATCH 0135/1415] Fix Tests --- .../Model/Recommendations/DataProvider.php | 35 +++-- .../CatalogInventory/Model/Configuration.php | 40 +++-- .../Test/Unit/Model/ConfigurationTest.php | 2 +- app/code/Magento/Checkout/Helper/Data.php | 34 +++-- .../Checkout/Test/Unit/Helper/DataTest.php | 2 +- app/code/Magento/Customer/Helper/Address.php | 104 +++++++------ .../Customer/Model/AccountConfirmation.php | 10 +- .../Customer/Test/Unit/Helper/AddressTest.php | 8 +- .../Unit/Model/AccountConfirmationTest.php | 2 +- .../Component/DataProvider/DocumentTest.php | 2 +- .../Ui/Component/DataProvider/Document.php | 37 +++-- app/code/Magento/Directory/Helper/Data.php | 36 ++--- .../Directory/Test/Unit/Helper/DataTest.php | 1 + .../Model/DataProvider/Suggestions.php | 35 ++++- .../Model/GiftMessageConfigProvider.php | 29 ++-- .../Model/GiftMessageConfigProviderTest.php | 2 +- .../Magento/GoogleOptimizer/Helper/Data.php | 12 +- app/code/Magento/Msrp/Model/Config.php | 15 +- .../NewRelicReporting/Model/Config.php | 3 + .../Magento/Reports/Model/ReportStatus.php | 10 +- .../Model/ResourceModel/Catalog/Product.php | 67 +++++---- .../Magento/Store/Model/BaseUrlChecker.php | 8 +- .../Store/Model/HeaderProvider/Hsts.php | 12 +- .../Model/HeaderProvider/UpgradeInsecure.php | 12 +- app/code/Magento/Store/Model/StoreManager.php | 140 ++++++++++++------ .../Test/Unit/Model/BaseUrlCheckerTest.php | 21 +-- .../Magento/Wishlist/Model/Rss/Wishlist.php | 25 +++- .../Test/Unit/Model/Rss/WishlistTest.php | 2 +- .../Framework/View/Asset/Minification.php | 6 + 29 files changed, 456 insertions(+), 256 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php index 77df85e52003c..c1103e514e0f0 100644 --- a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php +++ b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php @@ -10,6 +10,9 @@ use Magento\Search\Model\QueryInterface; use Magento\AdvancedSearch\Model\SuggestedQueriesInterface; +/** + * Class DataProvider + */ class DataProvider implements SuggestedQueriesInterface { /** @@ -50,12 +53,14 @@ class DataProvider implements SuggestedQueriesInterface */ private $recommendationsFactory; - /** - * @param ScopeConfigInterface $scopeConfig - * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver - * @param \Magento\AdvancedSearch\Model\ResourceModel\RecommendationsFactory $recommendationsFactory - * @param \Magento\Search\Model\QueryResultFactory $queryResultFactory - */ + /** + * DataProvider constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver + * @param \Magento\AdvancedSearch\Model\ResourceModel\RecommendationsFactory $recommendationsFactory + * @param \Magento\Search\Model\QueryResultFactory $queryResultFactory + */ public function __construct( ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Layer\Resolver $layerResolver, @@ -69,6 +74,8 @@ public function __construct( } /** + * Is Results Count Enabled + * * @return bool */ public function isResultsCountEnabled() @@ -79,9 +86,13 @@ public function isResultsCountEnabled() ); } - /** - * {@inheritdoc} - */ + /** + * Get Items + * + * @param QueryInterface $query + * + * @return array|\Magento\Search\Model\QueryResult[] + */ public function getItems(QueryInterface $query) { $recommendations = []; @@ -102,6 +113,8 @@ public function getItems(QueryInterface $query) } /** + * Return Search Recommendations + * * @param QueryInterface $query * @return array */ @@ -126,6 +139,8 @@ private function getSearchRecommendations(\Magento\Search\Model\QueryInterface $ } /** + * Is Search Recommendations Enabled + * * @return bool */ private function isSearchRecommendationsEnabled() @@ -137,6 +152,8 @@ private function isSearchRecommendationsEnabled() } /** + * Return Search Recommendations Count + * * @return int */ private function getSearchRecommendationsCount() diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php index b0f8aebf1da26..a303b15d11a4e 100644 --- a/app/code/Magento/CatalogInventory/Model/Configuration.php +++ b/app/code/Magento/CatalogInventory/Model/Configuration.php @@ -131,12 +131,14 @@ class Configuration implements StockConfigurationInterface */ protected $storeManager; - /** - * @param ConfigInterface $config - * @param ScopeConfigInterface $scopeConfig - * @param MinsaleqtyHelper $minsaleqtyHelper - * @param StoreManagerInterface $storeManager - */ + /** + * Configuration constructor. + * + * @param ConfigInterface $config + * @param ScopeConfigInterface $scopeConfig + * @param MinsaleqtyHelper $minsaleqtyHelper + * @param StoreManagerInterface $storeManager + */ public function __construct( ConfigInterface $config, ScopeConfigInterface $scopeConfig, @@ -149,9 +151,11 @@ public function __construct( $this->storeManager = $storeManager; } - /** - * {@inheritdoc} - */ + /** + * Default Scope Id + * + * @return int + */ public function getDefaultScopeId() { // TODO: should be fixed in MAGETWO-46043 @@ -160,6 +164,8 @@ public function getDefaultScopeId() } /** + * Is Qty Type Ids + * * @param int|null $filter * @return array */ @@ -183,6 +189,8 @@ public function getIsQtyTypeIds($filter = null) } /** + * Is Qty + * * @param int $productTypeId * @return bool */ @@ -208,6 +216,8 @@ public function canSubtractQty($store = null) } /** + * Get Min Qty + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return float */ @@ -221,6 +231,8 @@ public function getMinQty($store = null) } /** + * Get Min Sale Qty + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @param int $customerGroupId * @return float @@ -231,6 +243,8 @@ public function getMinSaleQty($store = null, $customerGroupId = null) } /** + * Get Max Sale Qty + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return float|null */ @@ -244,6 +258,8 @@ public function getMaxSaleQty($store = null) } /** + * Get Notify Stock Qty + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return float */ @@ -273,6 +289,8 @@ public function getEnableQtyIncrements($store = null) } /** + * Get Qty Increments + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return float */ @@ -378,6 +396,8 @@ public function isDisplayProductStockStatus($store = null) } /** + * Get Default Config Value + * * @param string $field * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return string|null @@ -392,6 +412,8 @@ public function getDefaultConfigValue($field, $store = null) } /** + * Get Stock Threshold Qty + * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return string|null */ diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php index d2779b79b30d7..cefc4ada7d212 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php @@ -144,7 +144,7 @@ public function testGetEnableQtyIncrements() $store = 1; $this->scopeConfigMock->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with( Configuration::XML_PATH_ENABLE_QTY_INCREMENTS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, diff --git a/app/code/Magento/Checkout/Helper/Data.php b/app/code/Magento/Checkout/Helper/Data.php index 5a920ee2f5d8a..eb96913806f06 100644 --- a/app/code/Magento/Checkout/Helper/Data.php +++ b/app/code/Magento/Checkout/Helper/Data.php @@ -58,17 +58,19 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ private $paymentFailures; - /** - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder - * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation - * @param PriceCurrencyInterface $priceCurrency - * @param PaymentFailuresInterface|null $paymentFailures - * @codeCoverageIgnore - */ + /** + * Data constructor. + * + * @param \Magento\Framework\App\Helper\Context $context + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate + * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder + * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param PriceCurrencyInterface $priceCurrency + * @param PaymentFailuresInterface|null $paymentFailures + * @codeCoverageIgnore + */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -113,6 +115,7 @@ public function getQuote() } /** + * Format Price * @param float $price * @return string */ @@ -127,6 +130,8 @@ public function formatPrice($price) } /** + * Convert Price + * * @param float $price * @param bool $format * @return float @@ -184,6 +189,8 @@ public function getSubtotalInclTax($item) } /** + * Get Base Price Incl Tax + * * @param AbstractItem $item * @return float */ @@ -196,6 +203,8 @@ public function getBasePriceInclTax($item) } /** + * Get Base Subtotal Incl Tax + * * @param AbstractItem $item * @return float */ @@ -224,6 +233,8 @@ public function sendPaymentFailedEmail( } /** + * Get Emails + * * @param string $configPath * @param null|string|bool|int|Store $storeId * @return array|false @@ -302,6 +313,7 @@ public function isCustomerMustBeLogged() /** * Checks if display billing address on payment method is available, otherwise * billing address should be display on payment page + * * @return bool */ public function isDisplayBillingOnPaymentMethodAvailable() diff --git a/app/code/Magento/Checkout/Test/Unit/Helper/DataTest.php b/app/code/Magento/Checkout/Test/Unit/Helper/DataTest.php index 53132ffaa748b..089ea15726c68 100644 --- a/app/code/Magento/Checkout/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Helper/DataTest.php @@ -179,7 +179,7 @@ public function testConvertPrice() public function testCanOnepageCheckout() { - $this->scopeConfig->expects($this->once())->method('getValue')->with( + $this->scopeConfig->expects($this->once())->method('isSetFlag')->with( 'checkout/options/onepage_checkout_enabled', 'store' )->will($this->returnValue(true)); diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php index 8e867c891d932..a05a4845f4a4d 100644 --- a/app/code/Magento/Customer/Helper/Address.php +++ b/app/code/Magento/Customer/Helper/Address.php @@ -96,6 +96,8 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper protected $_addressConfig; /** + * Address constructor. + * * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\View\Element\BlockFactory $blockFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -129,6 +131,8 @@ public function getBookUrl() } /** + * Edit Url + * * @return void */ public function getEditUrl() @@ -136,6 +140,8 @@ public function getEditUrl() } /** + * Delete Url + * * @return void */ public function getDeleteUrl() @@ -143,6 +149,8 @@ public function getDeleteUrl() } /** + * Create Url + * * @return void */ public function getCreateUrl() @@ -150,6 +158,8 @@ public function getCreateUrl() } /** + * Get Renderer + * * @param BlockInterface|string $renderer * @return BlockInterface */ @@ -162,15 +172,15 @@ public function getRenderer($renderer) } } - /** - * Return customer address config value by key and store - * - * @param string $key - * @param \Magento\Store\Model\Store|int|string $store - * - * @return string|null - * @throws NoSuchEntityException - */ + /** + * Return customer address config value by key and store + * + * @param string $key + * @param \Magento\Store\Model\Store|int|string $store + * + * @return string|null + * @throws NoSuchEntityException + */ public function getConfig($key, $store = null) { $store = $this->_storeManager->getStore($store); @@ -185,15 +195,15 @@ public function getConfig($key, $store = null) return isset($this->_config[$websiteId][$key]) ? (string)$this->_config[$websiteId][$key] : null; } - /** - * Return Number of Lines in a Street Address for store - * - * @param \Magento\Store\Model\Store|int|string $store - * - * @return int - * @throws NoSuchEntityException - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Return Number of Lines in a Street Address for store + * + * @param \Magento\Store\Model\Store|int|string $store + * + * @return int + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getStreetLines($store = null) { $websiteId = $this->_storeManager->getStore($store)->getWebsiteId(); @@ -211,6 +221,8 @@ public function getStreetLines($store = null) } /** + * Get Format + * * @param string $code * @return Format|string */ @@ -235,29 +247,29 @@ public function getFormatTypeRenderer($code) return $formatType->getRenderer(); } - /** - * Determine if specified address config value can be shown - * - * @param string $key - * - * @return bool - * @throws NoSuchEntityException - */ + /** + * Determine if specified address config value can be shown + * + * @param string $key + * + * @return bool + * @throws NoSuchEntityException + */ public function canShowConfig($key) { return (bool)$this->getConfig($key); } - /** - * Get string with frontend validation classes for attribute - * - * @param string $attributeCode - * - * @return string - * - * @SuppressWarnings(PHPMD.NPathComplexity) - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Get string with frontend validation classes for attribute + * + * @param string $attributeCode + * + * @return string + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getAttributeValidationClass($attributeCode) { $class = ''; @@ -387,16 +399,16 @@ public function isVatAttributeVisible() ); } - /** - * Retrieve attribute visibility - * - * @param string $code - * - * @return bool - * @throws NoSuchEntityException - * @throws \Magento\Framework\Exception\LocalizedException - * @since 100.2.0 - */ + /** + * Retrieve attribute visibility + * + * @param string $code + * + * @return bool + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + * @since 100.2.0 + */ public function isAttributeVisible($code) { $attributeMetadata = $this->_addressMetadataService->getAttributeMetadata($code); diff --git a/app/code/Magento/Customer/Model/AccountConfirmation.php b/app/code/Magento/Customer/Model/AccountConfirmation.php index 3c473dec78400..cb35c16c7f3bf 100644 --- a/app/code/Magento/Customer/Model/AccountConfirmation.php +++ b/app/code/Magento/Customer/Model/AccountConfirmation.php @@ -30,10 +30,12 @@ class AccountConfirmation */ private $registry; - /** - * @param ScopeConfigInterface $scopeConfig - * @param Registry $registry - */ + /** + * AccountConfirmation constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param Registry $registry + */ public function __construct( ScopeConfigInterface $scopeConfig, Registry $registry diff --git a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php index 74af4ec57c77f..fe0c495e8c44a 100644 --- a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php +++ b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php @@ -212,7 +212,7 @@ public function getConvertStreetLinesDataProvider() public function testIsVatValidationEnabled($store, $result) { $this->scopeConfig->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with( \Magento\Customer\Helper\Address::XML_PATH_VAT_VALIDATION_ENABLED, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, @@ -242,7 +242,7 @@ public function getVatValidationEnabledDataProvider() public function testHasValidateOnEachTransaction($store, $result) { $this->scopeConfig->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with( \Magento\Customer\Helper\Address::XML_PATH_VIV_ON_EACH_TRANSACTION, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, @@ -297,7 +297,7 @@ public function getTaxCalculationAddressTypeDataProvider() public function testIsDisableAutoGroupAssignDefaultValue() { $this->scopeConfig->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with( \Magento\Customer\Helper\Address::XML_PATH_VIV_DISABLE_AUTO_ASSIGN_DEFAULT, \Magento\Store\Model\ScopeInterface::SCOPE_STORE @@ -309,7 +309,7 @@ public function testIsDisableAutoGroupAssignDefaultValue() public function testIsVatAttributeVisible() { $this->scopeConfig->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with( \Magento\Customer\Helper\Address::XML_PATH_VAT_FRONTEND_VISIBILITY, \Magento\Store\Model\ScopeInterface::SCOPE_STORE diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountConfirmationTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountConfirmationTest.php index ae246665b28ed..1ce80d9d1e99b 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountConfirmationTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountConfirmationTest.php @@ -59,7 +59,7 @@ public function testIsConfirmationRequired( $websiteId = 1; $this->scopeConfig->expects($this->any()) - ->method('getValue') + ->method('isSetFlag') ->with( $this->accountConfirmation::XML_PATH_IS_CONFIRM, ScopeInterface::SCOPE_WEBSITES, diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/DataProvider/DocumentTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/DataProvider/DocumentTest.php index 1d7905cca7941..a9c6de72acbef 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/DataProvider/DocumentTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/DataProvider/DocumentTest.php @@ -175,7 +175,7 @@ public function testGetConfirmationAttribute() $this->document->setData('original_website_id', $websiteId); $this->scopeConfig->expects(static::once()) - ->method('getValue') + ->method('isSetFlag') ->with() ->willReturn(true); diff --git a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php index 89a3c2e855f6f..ce77cec6788f5 100644 --- a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php +++ b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php @@ -72,6 +72,7 @@ class Document extends \Magento\Framework\View\Element\UiComponent\DataProvider\ /** * Document constructor. + * * @param AttributeValueFactory $attributeValueFactory * @param GroupRepositoryInterface $groupRepository * @param CustomerMetadataInterface $customerMetadata @@ -93,7 +94,12 @@ public function __construct( } /** - * @inheritdoc + * Get Custom Attribute + * + * @param string $attributeCode + * + * @return \Magento\Framework\Api\AttributeInterface|null + * @throws \Magento\Framework\Exception\LocalizedException */ public function getCustomAttribute($attributeCode) { @@ -117,12 +123,13 @@ public function getCustomAttribute($attributeCode) return parent::getCustomAttribute($attributeCode); } - /** - * Update customer gender value - * Method set gender label instead of id value - * @return void - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Update customer gender value + * Method set gender label instead of id value + * + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ private function setGenderValue() { $value = $this->getData(self::$genderAttributeCode); @@ -141,12 +148,13 @@ private function setGenderValue() } } - /** - * Update customer group value - * Method set group code instead id value - * @return void - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Update customer group value + * Method set group code instead id value + * + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ private function setCustomerGroupValue() { $value = $this->getData(self::$groupAttributeCode); @@ -161,6 +169,7 @@ private function setCustomerGroupValue() /** * Update website value * Method set website name instead id value + * * @return void */ private function setWebsiteValue() @@ -174,6 +183,7 @@ private function setWebsiteValue() /** * Update confirmation value * Method set confirmation text value to match what is shown in grid + * * @return void */ private function setConfirmationValue() @@ -197,6 +207,7 @@ private function setConfirmationValue() /** * Update lock expires value * Method set account lock text value to match what is shown in grid + * * @return void */ private function setAccountLockValue() diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php index 3f1e272345ed8..3617bf52d720f 100644 --- a/app/code/Magento/Directory/Helper/Data.php +++ b/app/code/Magento/Directory/Helper/Data.php @@ -112,6 +112,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper protected $_currencyFactory; /** + * Data constructor. + * * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\App\Cache\Type\Config $configCacheType * @param \Magento\Directory\Model\ResourceModel\Country\Collection $countryCollection @@ -166,12 +168,12 @@ public function getCountryCollection($store = null) return $this->_countryCollection; } - /** - * Retrieve regions data json - * - * @return string - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ + /** + * Retrieve regions data json + * + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ public function getRegionJson() { \Magento\Framework\Profiler::start('TEST: ' . __METHOD__, ['group' => 'TEST', 'method' => __METHOD__]); @@ -193,17 +195,17 @@ public function getRegionJson() return $this->_regionJson; } - /** - * Convert currency - * - * @param float $amount - * @param string $from - * @param string $to - * - * @return float - * @SuppressWarnings(PHPMD.ShortVariable) - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ + /** + * Convert currency + * + * @param float $amount + * @param string $from + * @param string $to + * + * @return float + * @SuppressWarnings(PHPMD.ShortVariable) + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ public function currencyConvert($amount, $from, $to = null) { if (empty($this->_currencyCache[$from])) { diff --git a/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php b/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php index 73e9f0f5fa1a5..5d1cf957df71a 100644 --- a/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php @@ -46,6 +46,7 @@ protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); $context = $this->createMock(\Magento\Framework\App\Helper\Context::class); $context->expects($this->any()) ->method('getScopeConfig') diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index 0ab1b626b074f..420300ebd7e87 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -15,6 +15,9 @@ use Magento\Elasticsearch\SearchAdapter\SearchIndexNameResolver; use Magento\Store\Model\StoreManagerInterface as StoreManager; +/** + * Class Suggestions + */ class Suggestions implements SuggestedQueriesInterface { /** @@ -66,6 +69,8 @@ class Suggestions implements SuggestedQueriesInterface private $storeManager; /** + * Suggestions constructor. + * * @param ScopeConfigInterface $scopeConfig * @param Config $config * @param QueryResultFactory $queryResultFactory @@ -90,8 +95,14 @@ public function __construct( } /** - * {@inheritdoc} + * Get Items + * + * @param QueryInterface $query + * @param null $limit + * @param null $additionalFilters * + * @return array|\Magento\Search\Model\QueryResult[] + * @throws \Magento\Framework\Exception\NoSuchEntityException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getItems(QueryInterface $query, $limit = null, $additionalFilters = null) @@ -118,7 +129,9 @@ public function getItems(QueryInterface $query, $limit = null, $additionalFilter } /** - * {@inheritdoc} + * Is Results Count Enabled + * + * @return bool */ public function isResultsCountEnabled() { @@ -128,12 +141,14 @@ public function isResultsCountEnabled() ); } - /** - * @param QueryInterface $query - * - * @return array - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ + /** + * Get Suggestions + * + * @param QueryInterface $query + * + * @return array + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ private function getSuggestions(QueryInterface $query) { $suggestions = []; @@ -180,6 +195,8 @@ private function getSuggestions(QueryInterface $query) } /** + * Fetch Query + * * @param array $query * @return array */ @@ -202,6 +219,8 @@ private function getSearchSuggestionsCount() } /** + * Is Suggestions Allowed + * * @return bool */ private function isSuggestionsAllowed() diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index 3001fa411655c..52d43943daf06 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -42,12 +42,12 @@ class GiftMessageConfigProvider implements ConfigProviderInterface */ protected $checkoutSession; - /** - * @var HttpContext - */ - protected $httpContext; + /** + * @var HttpContext + */ + protected $httpContext; - /** + /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; @@ -63,6 +63,8 @@ class GiftMessageConfigProvider implements ConfigProviderInterface protected $formKey; /** + * GiftMessageConfigProvider constructor. + * * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\GiftMessage\Api\CartRepositoryInterface $cartRepository * @param \Magento\GiftMessage\Api\ItemRepositoryInterface $itemRepository @@ -93,7 +95,10 @@ public function __construct( } /** - * {@inheritdoc} + * Get Config + * + * @return array + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function getConfig() { @@ -170,12 +175,12 @@ protected function getOrderLevelGiftMessages() return $this->cartRepository->get($cartId); } - /** - * Load already specified item level gift messages and related configuration. - * - * @return \Magento\GiftMessage\Api\Data\MessageInterface[]|null - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ + /** + * Load already specified item level gift messages and related configuration. + * + * @return \Magento\GiftMessage\Api\Data\MessageInterface[]|null + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ protected function getItemLevelGiftMessages() { $itemLevelConfig = []; diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/GiftMessageConfigProviderTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/GiftMessageConfigProviderTest.php index a5580606134b4..08ebefb68d724 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Model/GiftMessageConfigProviderTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Model/GiftMessageConfigProviderTest.php @@ -111,7 +111,7 @@ public function testGetConfig() ); $messageMock = $this->createMock(\Magento\GiftMessage\Model\Message::class); - $this->scopeConfigMock->expects($this->atLeastOnce())->method('getValue')->willReturnMap( + $this->scopeConfigMock->expects($this->atLeastOnce())->method('isSetFlag')->willReturnMap( [ [GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, Scope::SCOPE_STORE, null, $orderLevel], [GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, Scope::SCOPE_STORE, null, $itemLevel] diff --git a/app/code/Magento/GoogleOptimizer/Helper/Data.php b/app/code/Magento/GoogleOptimizer/Helper/Data.php index 4929e474949b3..d1e668cc9ec80 100644 --- a/app/code/Magento/GoogleOptimizer/Helper/Data.php +++ b/app/code/Magento/GoogleOptimizer/Helper/Data.php @@ -11,6 +11,8 @@ use \Magento\Store\Model\ScopeInterface; /** + * Class Data + * * @api * @since 100.0.2 */ @@ -31,10 +33,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ protected $_analyticsHelper; - /** - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\GoogleAnalytics\Helper\Data $analyticsHelper - */ + /** + * Data constructor. + * + * @param \Magento\Framework\App\Helper\Context $context + * @param \Magento\GoogleAnalytics\Helper\Data $analyticsHelper + */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\GoogleAnalytics\Helper\Data $analyticsHelper diff --git a/app/code/Magento/Msrp/Model/Config.php b/app/code/Magento/Msrp/Model/Config.php index 7a990e82cbdf7..71ac1b08fd575 100644 --- a/app/code/Magento/Msrp/Model/Config.php +++ b/app/code/Magento/Msrp/Model/Config.php @@ -10,6 +10,9 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Escaper; +/** + * Class Config + */ class Config { /**#@+ @@ -39,11 +42,13 @@ class Config */ protected $storeId; - /** - * @param ScopeConfigInterface $scopeConfig - * @param StoreManagerInterface $storeManager - * @param Escaper $escaper - */ + /** + * Config constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param StoreManagerInterface $storeManager + * @param Escaper $escaper + */ public function __construct( ScopeConfigInterface $scopeConfig, StoreManagerInterface $storeManager, diff --git a/app/code/Magento/NewRelicReporting/Model/Config.php b/app/code/Magento/NewRelicReporting/Model/Config.php index 7c0273334d7ce..b42007aed9da0 100644 --- a/app/code/Magento/NewRelicReporting/Model/Config.php +++ b/app/code/Magento/NewRelicReporting/Model/Config.php @@ -5,6 +5,9 @@ */ namespace Magento\NewRelicReporting\Model; +/** + * Class Config + */ class Config { /**#@+ diff --git a/app/code/Magento/Reports/Model/ReportStatus.php b/app/code/Magento/Reports/Model/ReportStatus.php index 112b9e9ccc45d..13f71c00c7330 100644 --- a/app/code/Magento/Reports/Model/ReportStatus.php +++ b/app/code/Magento/Reports/Model/ReportStatus.php @@ -20,9 +20,11 @@ class ReportStatus */ private $scopeConfig; - /** - * @param ScopeConfigInterface $scopeConfig - */ + /** + * ReportStatus constructor. + * + * @param ScopeConfigInterface $scopeConfig + */ public function __construct(ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; @@ -42,6 +44,8 @@ public function isReportEnabled(string $reportEventType): bool } /** + * Get Config Path By Event Type + * * @param string $reportEventType * @return string * @throws InputException diff --git a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php index 621206d9bbbb3..0d85648c18a1f 100644 --- a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php +++ b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php @@ -105,6 +105,8 @@ class Product extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb private $scopeConfig; /** + * Product constructor. + * * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Sitemap\Helper\Data $sitemapData * @param \Magento\Catalog\Model\ResourceModel\Product $productResource @@ -157,6 +159,8 @@ public function __construct( } /** + * Construct + * * @return void */ protected function _construct() @@ -167,11 +171,13 @@ protected function _construct() /** * Add attribute to filter * - * @param int $storeId + * @param int $storeId * @param string $attributeCode - * @param mixed $value + * @param mixed $value * @param string $type + * * @return \Magento\Framework\DB\Select|bool + * @throws \Magento\Framework\Exception\LocalizedException */ protected function _addFilter($storeId, $attributeCode, $value, $type = '=') { @@ -214,10 +220,12 @@ protected function _addFilter($storeId, $attributeCode, $value, $type = '=') /** * Join attribute by code * - * @param int $storeId + * @param int $storeId * @param string $attributeCode * @param string $column Add attribute value to given column + * * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ protected function _joinAttribute($storeId, $attributeCode, $column = null) { @@ -256,14 +264,14 @@ protected function _joinAttribute($storeId, $attributeCode, $column = null) } } - /** - * Get attribute data by attribute code - * - * @param string $attributeCode - * - * @return array - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Get attribute data by attribute code + * + * @param string $attributeCode + * + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ protected function _getAttribute($attributeCode) { if (!isset($this->_attributesCache[$attributeCode])) { @@ -281,15 +289,16 @@ protected function _getAttribute($attributeCode) return $this->_attributesCache[$attributeCode]; } - /** - * Get category collection array - * - * @param null|string|bool|int|Store $storeId - * - * @return array|bool - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ + /** + * Get category collection array + * + * @param null|string|bool|int|Store $storeId + * + * @return array|bool + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Zend_Db_Statement_Exception + */ public function getCollection($storeId) { $products = []; @@ -348,15 +357,15 @@ public function getCollection($storeId) return $products; } - /** - * Prepare product - * - * @param array $productRow - * @param int $storeId - * - * @return \Magento\Framework\DataObject - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Prepare product + * + * @param array $productRow + * @param int $storeId + * + * @return \Magento\Framework\DataObject + * @throws \Magento\Framework\Exception\LocalizedException + */ protected function _prepareProduct(array $productRow, $storeId) { $product = new \Magento\Framework\DataObject(); diff --git a/app/code/Magento/Store/Model/BaseUrlChecker.php b/app/code/Magento/Store/Model/BaseUrlChecker.php index 6e3defac9a1cd..ee108fe484be1 100644 --- a/app/code/Magento/Store/Model/BaseUrlChecker.php +++ b/app/code/Magento/Store/Model/BaseUrlChecker.php @@ -17,9 +17,11 @@ class BaseUrlChecker */ private $scopeConfig; - /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * BaseUrlChecker constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig ) { diff --git a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php index 63afa7ad1fc84..52fd66924b957 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php +++ b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php @@ -32,16 +32,20 @@ class Hsts extends \Magento\Framework\App\Response\HeaderProvider\AbstractHeader */ protected $scopeConfig; - /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * Hsts constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; } /** - * {@inheritdoc} + * Whether the header should be attached to the response + * + * @return bool */ public function canApply() { diff --git a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php index 5dbe65141f184..cb6b0045e6673 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php +++ b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php @@ -32,16 +32,20 @@ class UpgradeInsecure extends \Magento\Framework\App\Response\HeaderProvider\Abs */ protected $scopeConfig; - /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * UpgradeInsecure constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; } /** - * {@inheritdoc} + * Whether the header should be attached to the response + * + * @return bool */ public function canApply() { diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 0f2d0c90bd51a..b9ab168f68dc2 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -6,6 +6,7 @@ namespace Magento\Store\Model; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Api\StoreResolverInterface; use Magento\Store\Model\ResourceModel\StoreWebsiteRelation; @@ -86,15 +87,17 @@ class StoreManager implements */ protected $isSingleStoreAllowed; - /** - * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository - * @param \Magento\Store\Api\GroupRepositoryInterface $groupRepository - * @param \Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param StoreResolverInterface $storeResolver - * @param \Magento\Framework\Cache\FrontendInterface $cache - * @param bool $isSingleStoreAllowed - */ + /** + * StoreManager constructor. + * + * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository + * @param \Magento\Store\Api\GroupRepositoryInterface $groupRepository + * @param \Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param StoreResolverInterface $storeResolver + * @param \Magento\Framework\Cache\FrontendInterface $cache + * @param bool $isSingleStoreAllowed + */ public function __construct( \Magento\Store\Api\StoreRepositoryInterface $storeRepository, \Magento\Store\Api\GroupRepositoryInterface $groupRepository, @@ -113,42 +116,54 @@ public function __construct( $this->isSingleStoreAllowed = $isSingleStoreAllowed; } - /** - * {@inheritdoc} - */ + /** + * Set current default store + * + * @param string $store + */ public function setCurrentStore($store) { $this->currentStoreId = $store; } - /** - * {@inheritdoc} - */ + /** + * Allow or disallow single store mode + * + * @param bool $value + */ public function setIsSingleStoreModeAllowed($value) { $this->isSingleStoreAllowed = $value; } - /** - * {@inheritdoc} - */ + /** + * Check if store has only one store view + * + * @return bool + */ public function hasSingleStore() { // TODO: MAGETWO-39902 add cache, move value to consts return $this->isSingleStoreAllowed && count($this->getStores(true)) < 3; } - /** - * {@inheritdoc} - */ + /** + * Check if system is run in the single store mode + * + * @return bool + */ public function isSingleStoreMode() { return $this->isSingleStoreModeEnabled() && $this->hasSingleStore(); } - /** - * {@inheritdoc} - */ + /** + * Retrieve application store object + * + * @param null|string|bool|int|\Magento\Store\Api\Data\StoreInterface $storeId + * @return \Magento\Store\Api\Data\StoreInterface + * @throws NoSuchEntityException If given store doesn't exist. + */ public function getStore($storeId = null) { if (!isset($storeId) || '' === $storeId || $storeId === true) { @@ -170,9 +185,13 @@ public function getStore($storeId = null) return $store; } - /** - * {@inheritdoc} - */ + /** + * Retrieve stores array + * + * @param bool $withDefault + * @param bool $codeKey + * @return \Magento\Store\Api\Data\StoreInterface[] + */ public function getStores($withDefault = false, $codeKey = false) { $stores = []; @@ -189,9 +208,13 @@ public function getStores($withDefault = false, $codeKey = false) return $stores; } - /** - * {@inheritdoc} - */ + /** + * Retrieve application website object + * + * @param null|bool|int|string|\Magento\Store\Api\Data\WebsiteInterface $websiteId + * @return \Magento\Store\Api\Data\WebsiteInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getWebsite($websiteId = null) { if ($websiteId === null || $websiteId === '') { @@ -209,9 +232,13 @@ public function getWebsite($websiteId = null) return $website; } - /** - * {@inheritdoc} - */ + /** + * Get loaded websites + * + * @param bool $withDefault + * @param bool $codeKey + * @return \Magento\Store\Api\Data\WebsiteInterface[] + */ public function getWebsites($withDefault = false, $codeKey = false) { $websites = []; @@ -228,9 +255,11 @@ public function getWebsites($withDefault = false, $codeKey = false) return $websites; } - /** - * {@inheritdoc} - */ + /** + * Reinitialize store list + * + * @return void + */ public function reinitStores() { $this->currentStoreId = null; @@ -241,9 +270,12 @@ public function reinitStores() $this->groupRepository->clean(); } - /** - * {@inheritdoc} - */ + /** + * Retrieve default store for default group and website + * + * @return \Magento\Store\Api\Data\StoreInterface|null + * @throws NoSuchEntityException + */ public function getDefaultStoreView() { $defaultWebsite = $this->websiteRepository->getDefault(); @@ -251,9 +283,14 @@ public function getDefaultStoreView() return $defaultStore ?: null; } - /** - * {@inheritdoc} - */ + /** + * Retrieve application store group object + * + * @param null|\Magento\Store\Api\Data\GroupInterface|string $groupId + * + * @return \Magento\Store\Api\Data\GroupInterface + * @throws NoSuchEntityException + */ public function getGroup($groupId = null) { if (null === $groupId) { @@ -266,9 +303,12 @@ public function getGroup($groupId = null) return $group; } - /** - * {@inheritdoc} - */ + /** + * Prepare array of store groups + * + * @param bool $withDefault + * @return \Magento\Store\Api\Data\GroupInterface[] + */ public function getGroups($withDefault = false) { $groups = $this->groupRepository->getList(); @@ -306,9 +346,13 @@ private function getStoreWebsiteRelation() return ObjectManager::getInstance()->get(StoreWebsiteRelation::class); } - /** - * @inheritdoc - */ + /** + * Get assigned to website store + * + * @param int $websiteId + * + * @return array + */ public function getStoreByWebsiteId($websiteId) { return $this->getStoreWebsiteRelation()->getStoreByWebsiteId($websiteId); diff --git a/app/code/Magento/Store/Test/Unit/Model/BaseUrlCheckerTest.php b/app/code/Magento/Store/Test/Unit/Model/BaseUrlCheckerTest.php index 0eea86da61b3b..78a627c195f81 100644 --- a/app/code/Magento/Store/Test/Unit/Model/BaseUrlCheckerTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/BaseUrlCheckerTest.php @@ -78,9 +78,9 @@ public function testExecute() public function testIsEnabled() { $this->scopeConfig->expects($this->once()) - ->method('getValue') + ->method('isSetFlag') ->with('web/url/redirect_to_base', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) - ->willReturn(1); + ->willReturn(!!1); $this->assertTrue($this->baseUrlChecker->isEnabled()); } @@ -89,15 +89,16 @@ public function testIsEnabled() */ public function testIsFrontendSecure() { - $this->scopeConfig->expects($this->exactly(2)) + $this->scopeConfig->expects($this->once()) ->method('getValue') - ->withConsecutive( - ['web/unsecure/base_url', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], - ['web/secure/use_in_frontend', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] - )->will($this->onConsecutiveCalls( - $this->returnValue('https://localhost'), - 1 - )); + ->with('web/unsecure/base_url', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn('https://localhost'); + + $this->scopeConfig->expects($this->once()) + ->method('isSetFlag') + ->with('web/secure/use_in_frontend', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn(!!1); + $this->assertTrue($this->baseUrlChecker->isFrontendSecure()); } } diff --git a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php index 233b7a804d94d..d5beab83cdd2b 100644 --- a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php +++ b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php @@ -11,6 +11,7 @@ /** * Wishlist RSS model + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Wishlist implements DataProviderInterface @@ -71,6 +72,8 @@ class Wishlist implements DataProviderInterface protected $customerFactory; /** + * Wishlist constructor. + * * @param \Magento\Wishlist\Helper\Rss $wishlistHelper * @param \Magento\Wishlist\Block\Customer\Wishlist $wishlistBlock * @param \Magento\Catalog\Helper\Output $outputHelper @@ -121,12 +124,12 @@ public function isAllowed() ); } - /** - * Get RSS feed items - * - * @return array - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Get RSS feed items + * + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getRssData() { $wishlist = $this->getWishlist(); @@ -193,6 +196,8 @@ public function getRssData() } /** + * GetCacheKey + * * @return string */ public function getCacheKey() @@ -201,6 +206,8 @@ public function getCacheKey() } /** + * Get Cache Lifetime + * * @return int */ public function getCacheLifetime() @@ -266,6 +273,8 @@ public function getProductPriceHtml(\Magento\Catalog\Model\Product $product) } /** + * Get Feeds + * * @return array */ public function getFeeds() @@ -274,7 +283,9 @@ public function getFeeds() } /** - * {@inheritdoc} + * Is Auth Required + * + * @return bool */ public function isAuthRequired() { diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php index 98d36dea28a2a..85f6c504457d3 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php @@ -278,7 +278,7 @@ protected function processWishlistItemDescription($wishlistModelMock, $staticArg public function testIsAllowed() { - $this->scopeConfig->expects($this->once())->method('getValue') + $this->scopeConfig->expects($this->once())->method('isSetFlag') ->with('rss/wishlist/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) ->will($this->returnValue(true)); $this->assertTrue($this->model->isAllowed()); diff --git a/lib/internal/Magento/Framework/View/Asset/Minification.php b/lib/internal/Magento/Framework/View/Asset/Minification.php index ceee78469f090..087d57ffa4162 100644 --- a/lib/internal/Magento/Framework/View/Asset/Minification.php +++ b/lib/internal/Magento/Framework/View/Asset/Minification.php @@ -112,6 +112,8 @@ public function removeMinifiedSign($filename) } /** + * Is Minified Filename + * * @param string $filename * @return bool */ @@ -121,6 +123,8 @@ public function isMinifiedFilename($filename) } /** + * Is Excluded + * * @param string $filename * @return boolean */ @@ -135,6 +139,8 @@ public function isExcluded($filename) } /** + * Get Excludes + * * @param string $contentType * @return string[] */ From b33c4b2ccfb71a4ed126749698a530330fa8aab8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 18 Sep 2018 13:56:47 -0500 Subject: [PATCH 0136/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Adminhtml/Product/Attribute/Save.php | 16 +++--- .../Adminhtml/Product/Attribute/Validate.php | 16 +++--- .../Option/OptionsDataSerializer.php | 50 ----------------- .../Adminhtml/Product/Attribute/SaveTest.php | 16 +++--- .../Product/Attribute/ValidateTest.php | 16 +++--- .../Serialize/Serializer/FormData.php | 53 +++++++++++++++++++ 6 files changed, 85 insertions(+), 82 deletions(-) delete mode 100644 app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php create mode 100644 lib/internal/Magento/Framework/Serialize/Serializer/FormData.php diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index bf60381a8a4e7..435fdb0b41301 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -14,7 +14,7 @@ use Magento\Catalog\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Helper\Product; use Magento\Catalog\Model\Product\Attribute\Frontend\Inputtype\Presentation; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; +use Magento\Framework\Serialize\Serializer\FormData; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory; use Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator; @@ -80,9 +80,9 @@ class Save extends Attribute implements HttpPostActionInterface private $presentation; /** - * @var OptionsDataSerializer|null + * @var FormData|null */ - private $optionsDataSerializer; + private $dataSerializer; /** * @param Context $context @@ -97,7 +97,7 @@ class Save extends Attribute implements HttpPostActionInterface * @param Product $productHelper * @param LayoutFactory $layoutFactory * @param Presentation|null $presentation - * @param OptionsDataSerializer|null $optionsDataSerializer + * @param FormData|null $dataSerializer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -113,7 +113,7 @@ public function __construct( Product $productHelper, LayoutFactory $layoutFactory, Presentation $presentation = null, - OptionsDataSerializer $optionsDataSerializer = null + FormData $dataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->buildFactory = $buildFactory; @@ -124,8 +124,8 @@ public function __construct( $this->groupCollectionFactory = $groupCollectionFactory; $this->layoutFactory = $layoutFactory; $this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class); - $this->optionsDataSerializer = $optionsDataSerializer - ?: ObjectManager::getInstance()->get(OptionsDataSerializer::class); + $this->dataSerializer = $dataSerializer + ?: ObjectManager::getInstance()->get(FormData::class); } /** @@ -140,7 +140,7 @@ public function __construct( public function execute() { try { - $optionData = $this->optionsDataSerializer + $optionData = $this->dataSerializer ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index d9627ddd1476d..4e33fc737f0c4 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -7,7 +7,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; +use Magento\Framework\Serialize\Serializer\FormData; use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\ObjectManager; @@ -39,9 +39,9 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo private $multipleAttributeList; /** - * @var OptionsDataSerializer|null + * @var FormData|null */ - private $optionsDataSerializer; + private $dataSerializer; /** * Constructor @@ -53,7 +53,7 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param array $multipleAttributeList - * @param OptionsDataSerializer|null $optionsDataSerializer + * @param FormData|null $dataSerializer */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -63,14 +63,14 @@ public function __construct( \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, array $multipleAttributeList = [], - OptionsDataSerializer $optionsDataSerializer = null + FormData $dataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->multipleAttributeList = $multipleAttributeList; - $this->optionsDataSerializer = $optionsDataSerializer ?: ObjectManager::getInstance() - ->get(OptionsDataSerializer::class); + $this->dataSerializer = $dataSerializer ?: ObjectManager::getInstance() + ->get(FormData::class); } /** @@ -85,7 +85,7 @@ public function execute() $response = new DataObject(); $response->setError(false); try { - $optionsData = $this->optionsDataSerializer + $optionsData = $this->dataSerializer ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be validated due to an error. Verify your information and try again. " diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php b/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php deleted file mode 100644 index 8fe02a9123b18..0000000000000 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Option/OptionsDataSerializer.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\Catalog\Model\Product\Attribute\Option; - -use Magento\Framework\Serialize\SerializerInterface; - -/** - * Attribute options data serializer. - */ -class OptionsDataSerializer -{ - /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @param SerializerInterface $serializer - */ - public function __construct(SerializerInterface $serializer) - { - $this->serializer = $serializer; - } - - /** - * Provides attribute options data from the serialized data. - * - * @param string $serializedOptions - * @return array - */ - public function unserialize(string $serializedOptions): array - { - $optionsData = []; - $encodedOptions = $this->serializer->unserialize($serializedOptions); - - foreach ($encodedOptions as $encodedOption) { - $decodedOptionData = []; - parse_str($encodedOption, $decodedOptionData); - $optionsData = array_replace_recursive($optionsData, $decodedOptionData); - } - - return $optionsData; - } -} diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php index f34a70260a2e0..e73f3527517f8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php @@ -7,7 +7,7 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Save; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; +use Magento\Framework\Serialize\Serializer\FormData; use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Catalog\Model\Product\AttributeSet\BuildFactory; use Magento\Catalog\Model\Product\AttributeSet\Build; @@ -85,9 +85,9 @@ class SaveTest extends AttributeTest protected $inputTypeValidatorMock; /** - * @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject + * @var FormData|\PHPUnit_Framework_MockObject_MockObject */ - private $optionsDataSerializerMock; + private $dataSerializerMock; /** * @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject @@ -135,7 +135,7 @@ protected function setUp() $this->inputTypeValidatorMock = $this->getMockBuilder(InputTypeValidator::class) ->disableOriginalConstructor() ->getMock(); - $this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class) + $this->dataSerializerMock = $this->getMockBuilder(FormData::class) ->disableOriginalConstructor() ->getMock(); $this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class) @@ -170,7 +170,7 @@ protected function getModel() 'validatorFactory' => $this->validatorFactoryMock, 'groupCollectionFactory' => $this->groupCollectionFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, - 'optionsDataSerializer' => $this->optionsDataSerializerMock, + 'dataSerializer' => $this->dataSerializerMock, ]); } @@ -182,7 +182,7 @@ public function testExecuteWithEmptyData() ['isAjax', null, null], ['serialized_options', '[]', ''], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with('') @@ -213,7 +213,7 @@ public function testExecute() ['isAjax', null, null], ['serialized_options', '[]', ''], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with('') @@ -273,7 +273,7 @@ public function testExecuteWithOptionsDataError() ['isAjax', null, true], ['serialized_options', '[]', $serializedOptions], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index 17af610fed76c..666e6c1942c7a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -6,7 +6,7 @@ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Validate; -use Magento\Catalog\Model\Product\Attribute\Option\OptionsDataSerializer; +use Magento\Framework\Serialize\Serializer\FormData; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet; @@ -63,9 +63,9 @@ class ValidateTest extends AttributeTest protected $layoutMock; /** - * @var OptionsDataSerializer|\PHPUnit_Framework_MockObject_MockObject + * @var FormData|\PHPUnit_Framework_MockObject_MockObject */ - private $optionsDataSerializerMock; + private $dataSerializerMock; protected function setUp() { @@ -92,7 +92,7 @@ protected function setUp() ->getMock(); $this->layoutMock = $this->getMockBuilder(LayoutInterface::class) ->getMockForAbstractClass(); - $this->optionsDataSerializerMock = $this->getMockBuilder(OptionsDataSerializer::class) + $this->dataSerializerMock = $this->getMockBuilder(FormData::class) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +116,7 @@ protected function getModel() 'resultJsonFactory' => $this->resultJsonFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, 'multipleAttributeList' => ['select' => 'option'], - 'optionsDataSerializer' => $this->optionsDataSerializerMock, + 'dataSerializer' => $this->dataSerializerMock, ] ); } @@ -184,7 +184,7 @@ public function testUniqueValidation(array $options, $isError) ['serialized_options', '[]', $serializedOptions], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) @@ -319,7 +319,7 @@ public function testEmptyOption(array $options, $result) ['serialized_options', '[]', $serializedOptions], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) @@ -431,7 +431,7 @@ public function testExecuteWithOptionsDataError() ['serialized_options', '[]', $serializedOptions], ]); - $this->optionsDataSerializerMock + $this->dataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php new file mode 100644 index 0000000000000..a945822d92f97 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\Serialize\Serializer; + +/** + * Class for processing of serialized form data. + */ +class FormData +{ + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct(Json $serializer) + { + $this->serializer = $serializer; + } + + /** + * Provides form data from the serialized data. + * + * @param string $serializedData + * @return array + * @throws \InvalidArgumentException + */ + public function unserialize(string $serializedData): array + { + $encodedFields = $this->serializer->unserialize($serializedData); + + if (!is_array($encodedFields)) { + throw new \InvalidArgumentException('Unable to unserialize value.'); + } + + $formData = []; + foreach ($encodedFields as $item) { + $decodedFieldData = []; + parse_str($item, $decodedFieldData); + $formData = array_replace_recursive($formData, $decodedFieldData); + } + + return $formData; + } +} From 1407b93a6d450c22c96b5829dcb10809d78035e8 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 18 Sep 2018 14:53:02 -0500 Subject: [PATCH 0137/1415] MAGETWO-90540: MFTF Test failure - Advanced Reporting configuration permission --- app/code/Magento/Analytics/Test/Mftf/Data/UserData.xml | 4 ++-- .../{Analytics => User}/Test/Mftf/Metadata/user-meta.xml | 0 .../{Analytics => User}/Test/Mftf/Metadata/user_role-meta.xml | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename app/code/Magento/{Analytics => User}/Test/Mftf/Metadata/user-meta.xml (100%) rename app/code/Magento/{Analytics => User}/Test/Mftf/Metadata/user_role-meta.xml (100%) diff --git a/app/code/Magento/Analytics/Test/Mftf/Data/UserData.xml b/app/code/Magento/Analytics/Test/Mftf/Data/UserData.xml index f6e5b955816e2..83f27def4b4e8 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Data/UserData.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Data/UserData.xml @@ -7,7 +7,7 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> <entity name="adminNoReport" type="user"> <data key="username" unique="suffix">noreport</data> <data key="firstname">No</data> @@ -18,7 +18,7 @@ <data key="interface_local">en_US</data> <data key="is_active">true</data> <data key="current_password">123123q</data> -</entity> + </entity> <entity name="restrictedWebUser" type="user"> <data key="username" unique="suffix">restrictedWebUser</data> <data key="firstname">restricted</data> diff --git a/app/code/Magento/Analytics/Test/Mftf/Metadata/user-meta.xml b/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml similarity index 100% rename from app/code/Magento/Analytics/Test/Mftf/Metadata/user-meta.xml rename to app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml diff --git a/app/code/Magento/Analytics/Test/Mftf/Metadata/user_role-meta.xml b/app/code/Magento/User/Test/Mftf/Metadata/user_role-meta.xml similarity index 100% rename from app/code/Magento/Analytics/Test/Mftf/Metadata/user_role-meta.xml rename to app/code/Magento/User/Test/Mftf/Metadata/user_role-meta.xml From 77822528e599d014d1151e360ffa9f0a7cc94be4 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Tue, 18 Sep 2018 23:02:35 +0300 Subject: [PATCH 0138/1415] update variable name --- .../Magento/Customer/Ui/Component/DataProvider/Document.php | 4 ++-- .../Elasticsearch/Model/DataProvider/Suggestions.php | 6 +++--- .../Magento/GiftMessage/Model/GiftMessageConfigProvider.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php index ce77cec6788f5..714e2b11daead 100644 --- a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php +++ b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php @@ -190,14 +190,14 @@ private function setConfirmationValue() { $value = $this->getData(self::$confirmationAttributeCode); $websiteId = $this->getData(self::$websiteIdAttributeCode) ?: $this->getData(self::$websiteAttributeCode); - $isConfirmationRequired = $this->scopeConfig->isSetFlag( + $isConfirmRequired = $this->scopeConfig->isSetFlag( AccountManagement::XML_PATH_IS_CONFIRM, ScopeInterface::SCOPE_WEBSITES, $websiteId ); $valueText = __('Confirmation Not Required'); - if ($isConfirmationRequired) { + if ($isConfirmRequired) { $valueText = $value === null ? __('Confirmed') : __('Confirmation Required'); } diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index 420300ebd7e87..44c542d04d6cb 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -219,18 +219,18 @@ private function getSearchSuggestionsCount() } /** - * Is Suggestions Allowed + * Is Search Suggestions Allowed * * @return bool */ private function isSuggestionsAllowed() { - $isSearchSuggestionsEnabled = $this->scopeConfig->isSetFlag( + $isSuggestionsEnabled = $this->scopeConfig->isSetFlag( self::CONFIG_SUGGESTION_ENABLED, ScopeInterface::SCOPE_STORE ); $isEnabled = $this->config->isElasticsearchEnabled(); - $isSuggestionsAllowed = ($isEnabled && $isSearchSuggestionsEnabled); + $isSuggestionsAllowed = ($isEnabled && $isSuggestionsEnabled); return $isSuggestionsAllowed; } } diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index 52d43943daf06..3d184bf1a77b9 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -108,7 +108,7 @@ public function getConfig() GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, ScopeInterface::SCOPE_STORE ); - $itemLevelGiftMessageConfiguration = $this->scopeConfiguration->isSetFlag( + $itemLevelGiftMessage = $this->scopeConfiguration->isSetFlag( GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, ScopeInterface::SCOPE_STORE ); @@ -119,7 +119,7 @@ public function getConfig() } $itemMessages = $this->getItemLevelGiftMessages(); - $configuration['isItemLevelGiftOptionsEnabled'] = $itemLevelGiftMessageConfiguration; + $configuration['isItemLevelGiftOptionsEnabled'] = $itemLevelGiftMessage; $configuration['giftMessage']['itemLevel'] = $itemMessages === null ? true : $itemMessages; $configuration['priceFormat'] = $this->localeFormat->getPriceFormat( From a6369144904e0503e21d80ef96e14396c2a3308f Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Tue, 18 Sep 2018 23:23:10 +0300 Subject: [PATCH 0139/1415] Fixed tests --- .../testsuite/Magento/GraphQl/Catalog/CategoryTest.php | 6 +++--- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index 8841fab75790c..5f0be1bdb8a86 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -141,7 +141,7 @@ public function testCategoryProducts() available_sort_by level } - image + image { url, path } image_label meta_description meta_keyword @@ -225,13 +225,13 @@ public function testCategoryProducts() } short_description sku - small_image + small_image { url, path } small_image_label special_from_date special_price special_to_date swatch_image - thumbnail + thumbnail { url, path } thumbnail_label tier_price tier_prices { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 34cebde64d03a..fdf1bfc35408b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -53,7 +53,7 @@ public function testQueryAllFieldsSimpleProduct() available_sort_by level } - image + image { url, path } image_label meta_description meta_keyword @@ -205,13 +205,13 @@ public function testQueryAllFieldsSimpleProduct() } short_description sku - small_image + small_image { url, path } small_image_label special_from_date special_price special_to_date swatch_image - thumbnail + thumbnail { url, path } thumbnail_label tier_price tier_prices From 96092708fc5156ec967b3aa5d1704b86fcd65611 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Tue, 18 Sep 2018 15:41:25 -0500 Subject: [PATCH 0140/1415] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Extract config value to variable to resolve code style error --- .../Multishipping/Model/Checkout/Type/Multishipping.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index a30acdc3943ee..d1df064f57140 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -904,10 +904,12 @@ public function validateMinimumAmount() \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); - if ($this->_scopeConfig->isSetFlag( + $minimumOrderMultiFlag = $this->_scopeConfig->isSetFlag( 'sales/minimum_order/multi_address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE) - ) { + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + + if ($minimumOrderMultiFlag) { $result = !($minimumOrderActive && !$this->getQuote()->validateMinimumAmount()); } else { $result = !($minimumOrderActive && !$this->validateMinimumAmountForAddressItems()); From 8ed02153e5ef7053b95b8bc1a31e5b6ee501fc63 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Tue, 18 Sep 2018 23:45:58 +0300 Subject: [PATCH 0141/1415] update variable name --- .../Magento/GiftMessage/Model/GiftMessageConfigProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index 3d184bf1a77b9..25e728aab7d1b 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -104,7 +104,7 @@ public function getConfig() { $configuration = []; $configuration['giftMessage'] = []; - $orderLevelGiftMessageConfiguration = $this->scopeConfiguration->isSetFlag( + $orderLevelGiftMessage = $this->scopeConfiguration->isSetFlag( GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, ScopeInterface::SCOPE_STORE ); @@ -112,7 +112,7 @@ public function getConfig() GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, ScopeInterface::SCOPE_STORE ); - if ($orderLevelGiftMessageConfiguration) { + if ($orderLevelGiftMessage) { $orderMessages = $this->getOrderLevelGiftMessages(); $configuration['isOrderLevelGiftOptionsEnabled'] = (bool)$this->isQuoteVirtual() ? false : true; $configuration['giftMessage']['orderLevel'] = $orderMessages === null ? true : $orderMessages->getData(); From ace0bc51c37be9b1e04aa656068a742d6ed84a2a Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Wed, 19 Sep 2018 00:11:12 +0300 Subject: [PATCH 0142/1415] update variable name --- .../Magento/GiftMessage/Model/GiftMessageConfigProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index 25e728aab7d1b..82c2b52c97040 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -104,7 +104,7 @@ public function getConfig() { $configuration = []; $configuration['giftMessage'] = []; - $orderLevelGiftMessage = $this->scopeConfiguration->isSetFlag( + $orderLevelGiftMsg = $this->scopeConfiguration->isSetFlag( GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, ScopeInterface::SCOPE_STORE ); @@ -112,7 +112,7 @@ public function getConfig() GiftMessageHelper::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, ScopeInterface::SCOPE_STORE ); - if ($orderLevelGiftMessage) { + if ($orderLevelGiftMsg) { $orderMessages = $this->getOrderLevelGiftMessages(); $configuration['isOrderLevelGiftOptionsEnabled'] = (bool)$this->isQuoteVirtual() ? false : true; $configuration['giftMessage']['orderLevel'] = $orderMessages === null ? true : $orderMessages->getData(); From 9cc36ea63c739048e9e55513784bf3aabcba0a45 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 18 Sep 2018 16:33:23 -0500 Subject: [PATCH 0143/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Test/Mftf/Section/AdminCreateProductAttributeSection.xml | 1 + .../Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml | 5 +++++ .../Catalog/Controller/Adminhtml/Product/AttributeTest.php | 1 - .../Swatches/Controller/Adminhtml/Product/AttributeTest.php | 1 - 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index a497233afbd4e..17778c76da9b9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -24,6 +24,7 @@ <element name="useInLayeredNavigation" type="select" selector="#is_filterable"/> </section> <section name="StorefrontPropertiesSection"> + <element name="PageTitle" type="text" selector="//span[text()='Storefront Properties']" /> <element name="StoreFrontPropertiesTab" selector="#product_attribute_tabs_front" type="button"/> <element name="EnableWYSIWYG" type="select" selector="#enabled"/> <element name="useForPromoRuleConditions" type="select" selector="#is_used_for_promo_rules"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 1e9ce849db1be..50dcfbf3da090 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -66,6 +66,11 @@ <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('0')}}" userInput="red" stepKey="fillAdmin1"/> + <!-- Go to Storefront Properties tab --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="goToStorefrontPropertiesTab"/> + <waitForElementVisible selector="{{StorefrontPropertiesSection.PageTitle}}" stepKey="waitTabLoad"/> + <!-- Save the new product attribute --> <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave2"/> <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 5a1dcae6cb0c4..1f70ad0f7df6b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -392,7 +392,6 @@ protected function _getAttributeData() 'used_for_sort_by' => '0', 'apply_to' => ['simple'], 'frontend_label' => [\Magento\Store\Model\Store::DEFAULT_STORE_ID => 'string to translate'], - 'serialized_options' => '[]', ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 36e216ab4e57e..5b7a80bb38dfd 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -133,7 +133,6 @@ private function getAttributePreset() : array { return [ 'form_key' => 'XxtpPYjm2YPYUlAt', - 'serialized_options' => '[]', 'frontend_label' => [ 0 => 'asdasd', 1 => '', From b48171bfa9c5fdb5ce1101dff67b4e3e0e5189ff Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Wed, 19 Sep 2018 13:48:06 +0600 Subject: [PATCH 0144/1415] MAGETWO-71022: After return is complete in Admin, 'remaining quantity' in customer account shows incorrect value - Added automated test --- .../Mftf/ActionGroup/AdminInvoiceActionGroup.xml | 12 ++++++++++++ .../Mftf/ActionGroup/AdminShipmentActionGroup.xml | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml index 15aff7c751a11..905cb08a401e1 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml @@ -38,4 +38,16 @@ </arguments> <see selector="{{AdminInvoiceItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> + + <actionGroup name="goToInvoiceIntoOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage"/> + </actionGroup> + + <actionGroup name="submitInvoiceIntoOrder"> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageInvoice"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceCreateSuccess"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml index 85430aeaa4168..3d70a742b13eb 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml @@ -35,4 +35,16 @@ </arguments> <see selector="{{AdminShipmentItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> + + <actionGroup name="goToShipmentIntoOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> + <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="seeOrderShipmentUrl"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Shipment" stepKey="seePageNameNewInvoicePage"/> + </actionGroup> + + <actionGroup name="submitShipmentIntoOrder"> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageShipping"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="seeShipmentCreateSuccess"/> + </actionGroup> </actionGroups> \ No newline at end of file From 78327c1ab246fc20ed84ee54ed67e2d97a1c5131 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 19 Sep 2018 14:06:15 +0300 Subject: [PATCH 0145/1415] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Added validation for discount value field in Advanced Pricing section of product. --- .../Ui/DataProvider/Product/Form/Modifier/TierPrice.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 0eddca3322205..5f8d7fcf9049a 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -45,7 +45,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 101.1.0 */ public function modifyData(array $data) @@ -54,8 +54,11 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * Add tier price info to meta array. {@inheritdoc} + * * @since 101.1.0 + * @param array $meta + * @return array */ public function modifyMeta(array $meta) { @@ -150,7 +153,9 @@ private function getUpdatedTierPriceStructure(array $priceMeta) 'dataType' => Price::NAME, 'addbefore' => '%', 'validation' => [ + 'required-entry' => true, 'validate-number' => true, + 'validate-greater-than-zero' => true, 'less-than-equals-to' => 100 ], 'visible' => $firstOption From 9793fb17167618d4f86316a2110cbd0f52e8ce15 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 14:43:08 +0300 Subject: [PATCH 0146/1415] MAGETWO-92195: Wrong order request flow --- .../Sales/Controller/Adminhtml/Order/MassHold.php | 3 ++- .../Sales/Controller/Adminhtml/Order/MassUnhold.php | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php index 241255f68e39f..5c96fbbe9e247 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Controller\Adminhtml\Order; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; use Magento\Backend\App\Action\Context; use Magento\Ui\Component\MassAction\Filter; @@ -14,7 +15,7 @@ /** * Class MassHold */ -class MassHold extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction +class MassHold extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction implements HttpPostActionInterface { /** * Authorization level of a basic admin session diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php index 5e8ea9c4ad071..bd377e40f1849 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php @@ -5,13 +5,19 @@ */ namespace Magento\Sales\Controller\Adminhtml\Order; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; use Magento\Backend\App\Action\Context; use Magento\Ui\Component\MassAction\Filter; use Magento\Sales\Model\ResourceModel\Order\CollectionFactory; use Magento\Sales\Api\OrderManagementInterface; -class MassUnhold extends AbstractMassAction +/** + * Class MassUnhold + * + * @package Magento\Sales\Controller\Adminhtml\Order + */ +class MassUnhold extends AbstractMassAction implements HttpPostActionInterface { /** * Authorization level of a basic admin session @@ -24,6 +30,8 @@ class MassUnhold extends AbstractMassAction private $orderManagement; /** + * Class constructor + * * @param Context $context * @param Filter $filter * @param CollectionFactory $collectionFactory From f017676c873418b4e87b306e8666f9db39e82b99 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Wed, 19 Sep 2018 15:45:48 +0400 Subject: [PATCH 0147/1415] MAGETWO-91617: Ordered Products Report Error for restricted scope admin - Add fixed code --- .../ActionGroup/AdminOrderActionGroup.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index ffa6a2a5f2d99..aa6c10400d48b 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -259,16 +259,6 @@ <see selector="{{AdminOrderItemsOrderedSection.productSkuColumn}}" userInput="{{product.sku}}" stepKey="seeSkuInItemsOrdered"/> </actionGroup> - <!--Cancel order that is in pending status--> - <actionGroup name="cancelPendingOrder"> - <click selector="{{AdminOrderDetailsMainActionsSection.cancel}}" stepKey="clickCancelOrder"/> - <waitForElement selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForCancelConfirmation"/> - <see selector="{{AdminConfirmationModalSection.message}}" userInput="Are you sure you want to cancel this order?" stepKey="seeConfirmationMessage"/> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmOrderCancel"/> - <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> - <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> - </actionGroup> - <actionGroup name="CreateOrderInStoreActionGroup"> <arguments> <argument name="product"/> @@ -292,4 +282,14 @@ <click selector="{{OrdersGridSection.submitOrder}}" stepKey="submitOrder"/> <see stepKey="seeSuccessMessageForOrder" userInput="You created the order."/> </actionGroup> + + <!--Cancel order that is in pending status--> + <actionGroup name="cancelPendingOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.cancel}}" stepKey="clickCancelOrder"/> + <waitForElement selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForCancelConfirmation"/> + <see selector="{{AdminConfirmationModalSection.message}}" userInput="Are you sure you want to cancel this order?" stepKey="seeConfirmationMessage"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmOrderCancel"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> + </actionGroup> </actionGroups> From c450f44eeb530881115d63857f9d7e6af6f97158 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 14:46:20 +0300 Subject: [PATCH 0148/1415] MAGETWO-92195: Wrong order request flow --- .../Adminhtml/Order/MassCancelTest.php | 294 ------------------ .../Adminhtml/Order/MassHoldTest.php | 262 ---------------- .../Adminhtml/Order/MassUnholdTest.php | 261 ---------------- 3 files changed, 817 deletions(-) delete mode 100644 app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassCancelTest.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassHoldTest.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassUnholdTest.php diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassCancelTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassCancelTest.php deleted file mode 100644 index 38449c5686631..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassCancelTest.php +++ /dev/null @@ -1,294 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Test\Unit\Controller\Adminhtml\Order; - -use Magento\Framework\App\Action\Context; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -/** - * Class MassCancelTest - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class MassCancelTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Sales\Controller\Adminhtml\Order\MassCancel - */ - protected $massAction; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject - */ - protected $resultRedirectMock; - - /** - * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - - /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $responseMock; - - /** - * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $messageManagerMock; - - /** - * @var \Magento\Framework\ObjectManager\ObjectManager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectManagerMock; - - /** - * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $sessionMock; - - /** - * @var \Magento\Framework\App\ActionFlag|\PHPUnit_Framework_MockObject_MockObject - */ - protected $actionFlagMock; - - /** - * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject - */ - protected $helperMock; - - /** - * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\Collection|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionFactoryMock; - - /** - * @var \Magento\Ui\Component\MassAction\Filter|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filterMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $orderManagementMock; - - /** - * Test setup - */ - protected function setUp() - { - $objectManagerHelper = new ObjectManagerHelper($this); - $this->contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class); - $this->messageManagerMock = $this->createMock(\Magento\Framework\Message\Manager::class); - $this->responseMock = $this->createMock(\Magento\Framework\App\ResponseInterface::class); - $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManager\ObjectManager::class); - - $resultRedirectFactory = $this->createMock(\Magento\Backend\Model\View\Result\RedirectFactory::class); - - $this->orderCollectionMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Collection::class) - ->disableOriginalConstructor() - ->getMock(); - - $resourceCollection = \Magento\Sales\Model\ResourceModel\Order\CollectionFactory::class; - $this->orderCollectionFactoryMock = $this->getMockBuilder($resourceCollection) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->sessionMock = $this->createPartialMock(\Magento\Backend\Model\Session::class, ['setIsUrlNotice']); - $this->actionFlagMock = $this->createPartialMock(\Magento\Framework\App\ActionFlag::class, ['get', 'set']); - $this->helperMock = $this->createPartialMock(\Magento\Backend\Helper\Data::class, ['getUrl']); - $this->resultRedirectMock = $this->createMock(\Magento\Backend\Model\View\Result\Redirect::class); - $resultRedirectFactory->expects($this->any())->method('create')->willReturn($this->resultRedirectMock); - - $redirectMock = $this->getMockBuilder(\Magento\Backend\Model\View\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $resultFactoryMock->expects($this->any()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT) - ->willReturn($redirectMock); - - $this->contextMock->expects($this->once())->method('getMessageManager')->willReturn($this->messageManagerMock); - $this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock); - $this->contextMock->expects($this->once())->method('getResponse')->willReturn($this->responseMock); - $this->contextMock->expects($this->once())->method('getObjectManager')->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->once())->method('getSession')->willReturn($this->sessionMock); - $this->contextMock->expects($this->once())->method('getActionFlag')->willReturn($this->actionFlagMock); - $this->contextMock->expects($this->once())->method('getHelper')->willReturn($this->helperMock); - $this->contextMock->expects($this->once()) - ->method('getResultRedirectFactory') - ->willReturn($resultRedirectFactory); - $this->contextMock->expects($this->any()) - ->method('getResultFactory') - ->willReturn($resultFactoryMock); - $this->filterMock = $this->createMock(\Magento\Ui\Component\MassAction\Filter::class); - $this->filterMock->expects($this->once()) - ->method('getCollection') - ->with($this->orderCollectionMock) - ->willReturn($this->orderCollectionMock); - $this->orderCollectionFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->orderCollectionMock); - $this->orderManagementMock = $this->createMock(\Magento\Sales\Api\OrderManagementInterface::class); - - $this->massAction = $objectManagerHelper->getObject( - \Magento\Sales\Controller\Adminhtml\Order\MassCancel::class, - [ - 'context' => $this->contextMock, - 'filter' => $this->filterMock, - 'collectionFactory' => $this->orderCollectionFactoryMock, - 'orderManagement' => $this->orderManagementMock - ] - ); - } - - /** - * Test for selected orders - * Two orders, only $order1 can be canceled - */ - public function testExecuteCanCancelOneOrder() - { - $order1id = 100; - $order2id = 200; - - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $orders = [$order1, $order2]; - $countOrders = count($orders); - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn($orders); - - $order1->expects($this->once()) - ->method('getEntityId') - ->willReturn($order1id); - - $order2->expects($this->once()) - ->method('getEntityId') - ->willReturn($order2id); - - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn($countOrders); - - $this->orderManagementMock->expects($this->at(0))->method('cancel')->with($order1id)->willReturn(true); - $this->orderManagementMock->expects($this->at(1))->method('cancel')->with($order2id)->willReturn(false); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('1 order(s) cannot be canceled.'); - - $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') - ->with('We canceled 1 order(s).'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } - - /** - * Test for excluded orders - * Two orders could't be canceled - */ - public function testExcludedCannotCancelOrders() - { - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orders = [$order1, $order2]; - $countOrders = count($orders); - - $order1->expects($this->once()) - ->method('getEntityId') - ->willReturn(100); - - $order2->expects($this->once()) - ->method('getEntityId') - ->willReturn(200); - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn([$order1, $order2]); - - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn($countOrders); - - $this->orderManagementMock->expects($this->atLeastOnce())->method('cancel')->willReturn(false); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('You cannot cancel the order(s).'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } - - /** - * Order throws exception while canceling - */ - public function testException() - { - $exception = new \Exception('Can not cancel'); - - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn([$order1]); - - $order1->expects($this->once()) - ->method('getEntityId') - ->willReturn(100); - - $this->orderManagementMock->expects($this->atLeastOnce())->method('cancel')->willThrowException($exception); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('Can not cancel'); - - $this->massAction->execute(); - } -} diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassHoldTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassHoldTest.php deleted file mode 100644 index bfd1d1e825f89..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassHoldTest.php +++ /dev/null @@ -1,262 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Test\Unit\Controller\Adminhtml\Order; - -use Magento\Framework\App\Action\Context; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -/** - * Class MassHoldTest - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class MassHoldTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Sales\Controller\Adminhtml\Order\MassHold - */ - protected $massAction; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject - */ - protected $resultRedirectMock; - - /** - * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - - /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $responseMock; - - /** - * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $messageManagerMock; - - /** - * @var \Magento\Framework\ObjectManager\ObjectManager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectManagerMock; - - /** - * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $sessionMock; - - /** - * @var \Magento\Framework\App\ActionFlag|\PHPUnit_Framework_MockObject_MockObject - */ - protected $actionFlagMock; - - /** - * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject - */ - protected $helperMock; - - /** - * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\Collection|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionFactoryMock; - - /** - * @var \Magento\Ui\Component\MassAction\Filter|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filterMock; - - /** - * @var \Magento\Sales\Api\OrderManagementInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderManagementMock; - - /** - * Test setup - */ - protected function setUp() - { - $objectManagerHelper = new ObjectManagerHelper($this); - $this->orderManagementMock = $this->getMockBuilder(\Magento\Sales\Api\OrderManagementInterface::class) - ->getMockForAbstractClass(); - $this->contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class); - $resultRedirectFactory = $this->createMock(\Magento\Backend\Model\View\Result\RedirectFactory::class); - $this->responseMock = $this->createMock(\Magento\Framework\App\ResponseInterface::class); - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) - ->disableOriginalConstructor()->getMock(); - $this->objectManagerMock = $this->createPartialMock( - \Magento\Framework\ObjectManager\ObjectManager::class, - ['create'] - ); - $this->messageManagerMock = $this->createMock(\Magento\Framework\Message\Manager::class); - $this->orderCollectionMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Collection::class) - ->disableOriginalConstructor() - ->getMock(); - $orderCollection = \Magento\Sales\Model\ResourceModel\Order\CollectionFactory::class; - $this->orderCollectionFactoryMock = $this->getMockBuilder($orderCollection) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $redirectMock = $this->getMockBuilder(\Magento\Backend\Model\View\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $resultFactoryMock->expects($this->any()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT) - ->willReturn($redirectMock); - - $this->sessionMock = $this->createPartialMock(\Magento\Backend\Model\Session::class, ['setIsUrlNotice']); - $this->actionFlagMock = $this->createPartialMock(\Magento\Framework\App\ActionFlag::class, ['get', 'set']); - $this->helperMock = $this->createPartialMock(\Magento\Backend\Helper\Data::class, ['getUrl']); - $this->resultRedirectMock = $this->createMock(\Magento\Backend\Model\View\Result\Redirect::class); - $resultRedirectFactory->expects($this->any())->method('create')->willReturn($this->resultRedirectMock); - - $this->contextMock->expects($this->once())->method('getMessageManager')->willReturn($this->messageManagerMock); - $this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock); - $this->contextMock->expects($this->once())->method('getResponse')->willReturn($this->responseMock); - $this->contextMock->expects($this->once())->method('getObjectManager')->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->once())->method('getSession')->willReturn($this->sessionMock); - $this->contextMock->expects($this->once())->method('getActionFlag')->willReturn($this->actionFlagMock); - $this->contextMock->expects($this->once())->method('getHelper')->willReturn($this->helperMock); - $this->contextMock - ->expects($this->once()) - ->method('getResultRedirectFactory') - ->willReturn($resultRedirectFactory); - $this->contextMock->expects($this->any()) - ->method('getResultFactory') - ->willReturn($resultFactoryMock); - - $this->filterMock = $this->createMock(\Magento\Ui\Component\MassAction\Filter::class); - $this->filterMock->expects($this->once()) - ->method('getCollection') - ->with($this->orderCollectionMock) - ->willReturn($this->orderCollectionMock); - $this->orderCollectionFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->orderCollectionMock); - - $this->massAction = $objectManagerHelper->getObject( - \Magento\Sales\Controller\Adminhtml\Order\MassHold::class, - [ - 'context' => $this->contextMock, - 'filter' => $this->filterMock, - 'collectionFactory' => $this->orderCollectionFactoryMock, - 'orderManagement' => $this->orderManagementMock - ] - ); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testExecuteOneOrderPutOnHold() - { - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orders = [$order1, $order2]; - $countOrders = count($orders); - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn($orders); - - $order1->expects($this->once()) - ->method('canHold') - ->willReturn(true); - $this->orderManagementMock->expects($this->once()) - ->method('hold'); - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn($countOrders); - - $order2->expects($this->once()) - ->method('canHold') - ->willReturn(false); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('1 order(s) were not put on hold.'); - - $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') - ->with('You have put 1 order(s) on hold.'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testExecuteNoOrdersPutOnHold() - { - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orders = [$order1, $order2]; - $countOrders = count($orders); - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn($orders); - - $order1->expects($this->once()) - ->method('canHold') - ->willReturn(false); - - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn($countOrders); - - $order2->expects($this->once()) - ->method('canHold') - ->willReturn(false); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('No order(s) were put on hold.'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } -} diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassUnholdTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassUnholdTest.php deleted file mode 100644 index 56473ec948f27..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/MassUnholdTest.php +++ /dev/null @@ -1,261 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Test\Unit\Controller\Adminhtml\Order; - -use Magento\Framework\App\Action\Context; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -/** - * Class MassHoldTest - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class MassUnholdTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Sales\Controller\Adminhtml\Order\MassUnhold - */ - protected $massAction; - - /** - * @var Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject - */ - protected $resultRedirectMock; - - /** - * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - - /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $responseMock; - - /** - * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $messageManagerMock; - - /** - * @var \Magento\Framework\ObjectManager\ObjectManager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectManagerMock; - - /** - * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $sessionMock; - - /** - * @var \Magento\Framework\App\ActionFlag|\PHPUnit_Framework_MockObject_MockObject - */ - protected $actionFlagMock; - - /** - * @var \Magento\Backend\Helper\Data|\PHPUnit_Framework_MockObject_MockObject - */ - protected $helperMock; - - /** - * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\Collection|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionMock; - - /** - * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $orderCollectionFactoryMock; - - /** - * @var \Magento\Ui\Component\MassAction\Filter|\PHPUnit_Framework_MockObject_MockObject - */ - protected $filterMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $orderManagementMock; - - /** - * Test setup - */ - protected function setUp() - { - $objectManagerHelper = new ObjectManagerHelper($this); - $this->contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class); - $resultRedirectFactory = $this->createMock(\Magento\Backend\Model\View\Result\RedirectFactory::class); - $this->responseMock = $this->createMock(\Magento\Framework\App\ResponseInterface::class); - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) - ->disableOriginalConstructor()->getMock(); - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManager\ObjectManager::class); - $this->messageManagerMock = $this->createMock(\Magento\Framework\Message\Manager::class); - - $this->orderCollectionMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Collection::class) - ->disableOriginalConstructor() - ->getMock(); - $orderCollection = \Magento\Sales\Model\ResourceModel\Order\CollectionFactory::class; - $this->orderCollectionFactoryMock = $this->getMockBuilder($orderCollection) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->sessionMock = $this->createPartialMock(\Magento\Backend\Model\Session::class, ['setIsUrlNotice']); - $this->actionFlagMock = $this->createPartialMock(\Magento\Framework\App\ActionFlag::class, ['get', 'set']); - $this->helperMock = $this->createPartialMock(\Magento\Backend\Helper\Data::class, ['getUrl']); - $this->resultRedirectMock = $this->createMock(\Magento\Backend\Model\View\Result\Redirect::class); - $resultRedirectFactory->expects($this->any())->method('create')->willReturn($this->resultRedirectMock); - - $redirectMock = $this->getMockBuilder(\Magento\Backend\Model\View\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $resultFactoryMock->expects($this->any()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT) - ->willReturn($redirectMock); - - $this->contextMock->expects($this->once())->method('getMessageManager')->willReturn($this->messageManagerMock); - $this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock); - $this->contextMock->expects($this->once())->method('getResponse')->willReturn($this->responseMock); - $this->contextMock->expects($this->once())->method('getObjectManager')->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->once())->method('getSession')->willReturn($this->sessionMock); - $this->contextMock->expects($this->once())->method('getActionFlag')->willReturn($this->actionFlagMock); - $this->contextMock->expects($this->once())->method('getHelper')->willReturn($this->helperMock); - $this->contextMock - ->expects($this->once()) - ->method('getResultRedirectFactory') - ->willReturn($resultRedirectFactory); - $this->contextMock->expects($this->any()) - ->method('getResultFactory') - ->willReturn($resultFactoryMock); - - $this->filterMock = $this->createMock(\Magento\Ui\Component\MassAction\Filter::class); - $this->filterMock->expects($this->once()) - ->method('getCollection') - ->with($this->orderCollectionMock) - ->willReturn($this->orderCollectionMock); - $this->orderCollectionFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->orderCollectionMock); - - $this->orderManagementMock = $this->createMock(\Magento\Sales\Api\OrderManagementInterface::class); - - $this->massAction = $objectManagerHelper->getObject( - \Magento\Sales\Controller\Adminhtml\Order\MassUnhold::class, - [ - 'context' => $this->contextMock, - 'filter' => $this->filterMock, - 'collectionFactory' => $this->orderCollectionFactoryMock, - 'orderManagement' => $this->orderManagementMock - ] - ); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testExecuteOneOrdersReleasedFromHold() - { - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orders = [$order1, $order2]; - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn($orders); - - $order1->expects($this->once()) - ->method('canUnhold') - ->willReturn(true); - $order1->expects($this->once()) - ->method('getEntityId'); - - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn(count($orders)); - - $order2->expects($this->once()) - ->method('canUnhold') - ->willReturn(false); - - $this->orderManagementMock->expects($this->atLeastOnce())->method('unHold')->willReturn(true); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('1 order(s) were not released from on hold status.'); - - $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') - ->with('1 order(s) have been released from on hold status.'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testExecuteNoReleasedOrderFromHold() - { - $order1 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $order2 = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orders = [$order1, $order2]; - - $this->orderCollectionMock->expects($this->any()) - ->method('getItems') - ->willReturn($orders); - - $order1->expects($this->once()) - ->method('canUnhold') - ->willReturn(false); - - $this->orderCollectionMock->expects($this->once()) - ->method('count') - ->willReturn(count($orders)); - - $order2->expects($this->once()) - ->method('canUnhold') - ->willReturn(false); - - $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') - ->with('No order(s) were released from on hold status.'); - - $this->resultRedirectMock->expects($this->once()) - ->method('setPath') - ->with('sales/*/') - ->willReturnSelf(); - - $this->massAction->execute(); - } -} From 5333ca582fcc97c6926df798c96eba3378b7c3e2 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 19 Sep 2018 15:13:26 +0300 Subject: [PATCH 0149/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixed statics. --- .../Test/Unit/Block/Product/ProductList/ToolbarTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php index 8282ffa409f9c..884f4c543c8b8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php @@ -67,13 +67,16 @@ protected function setUp() 'getLimit', 'getCurrentPage' ]); - $this->memorizer = $this->createPartialMock(\Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, [ + $this->memorizer = $this->createPartialMock( + \Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, + [ 'getDirection', 'getOrder', 'getMode', 'getLimit', 'isMemorizingAllowed' - ]); + ] + ); $this->layout = $this->createPartialMock(\Magento\Framework\View\Layout::class, ['getChildName', 'getBlock']); $this->pagerBlock = $this->createPartialMock(\Magento\Theme\Block\Html\Pager::class, [ 'setUseContainer', From 949aa6b9ae92153fa7cd0d0453742259c33ee54c Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 19 Sep 2018 16:17:22 +0300 Subject: [PATCH 0150/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Fixes according to code review. --- app/code/Magento/GiftMessage/Block/Message/Inline.php | 7 ++----- .../GiftMessage/view/frontend/templates/inline.phtml | 8 +++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index 1a874cb5ea4ae..f44f967cefdc6 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -330,14 +330,11 @@ public function getEscaped($value, $defaultValue = '') * * @return bool */ - public function isOrderLevelAvailable() + public function isMessagesOrderAvailable() { $entity = $this->getEntity(); if (!$entity->hasIsGiftOptionsAvailable()) { $this->_eventManager->dispatch('gift_options_prepare', ['entity' => $entity]); - if (!$entity->getIsGiftOptionsAvailable()) { - $entity->setIsGiftOptionsAvailable($this->isMessagesAvailable()); - } } return $entity->getIsGiftOptionsAvailable(); } @@ -372,7 +369,7 @@ public function isItemMessagesAvailable($item) protected function _toHtml() { // render HTML when messages are allowed for order or for items only - if ($this->isItemsAvailable() || $this->isOrderLevelAvailable()) { + if ($this->isItemsAvailable() || $this->isMessagesAvailable() || $this->isMessagesOrderAvailable()) { return parent::_toHtml(); } return ''; diff --git a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml index 8c58959be15b7..640ef1ba16486 100644 --- a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml +++ b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml @@ -18,7 +18,7 @@ </div> <dl class="options-items" id="allow-gift-options-container"> - <?php if ($block->isOrderLevelAvailable()): ?> + <?php if ($block->isMessagesAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_messages_for_order" id="allow_gift_options_for_order" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> @@ -28,7 +28,6 @@ <dd id="allow-gift-options-for-order-container" class="order-options"> <div class="options-order-container" id="options-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"></div> - <?php if ($block->isMessagesAvailable()): ?> <button class="action action-gift" data-mage-init='{"toggleAdvanced": {"selectorsToggleClass":"hidden", "toggleContainers":"#allow-gift-messages-for-order-container"}}'> <span><?= /* @escapeNotVerified */ __('Gift Message') ?></span> @@ -63,9 +62,8 @@ }); </script> </div> - <?php endif; ?> </dd> - <?php endif; ?> + <?php endif ?> <?php if ($block->isItemsAvailable()): ?> <dt id="add-gift-options-for-items-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title individual"> <div class="field choice"> @@ -154,7 +152,7 @@ </div> <dl class="options-items" id="allow-gift-options-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"> - <?php if ($block->isOrderLevelAvailable()): ?> + <?php if ($block->isMessagesOrderAvailable() || $block->isMessagesAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" id="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> From 2f3d3f65c16453df6d7d8bf372fa10032d7866fd Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 16:43:18 +0300 Subject: [PATCH 0151/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- .../Sales/Controller/AbstractController/Reorder.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index a96892978c7fb..a03456d4c1f5f 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -7,15 +7,15 @@ namespace Magento\Sales\Controller\AbstractController; use Magento\Framework\App\Action; -use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Registry; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Class Reorder * * @package Magento\Sales\Controller\AbstractController */ -abstract class Reorder extends Action\Action +abstract class Reorder extends Action\Action implements HttpPostActionInterface { /** * @var \Magento\Sales\Controller\AbstractController\OrderLoaderInterface @@ -50,10 +50,6 @@ public function __construct( */ public function execute() { - if (!$this->getRequest()->isPost()) { - throw new NotFoundException(__('Page not Found')); - } - $result = $this->orderLoader->load($this->_request); if ($result instanceof \Magento\Framework\Controller\ResultInterface) { return $result; From 9302a4f3f22217c6a71002ce009ba3d8ae4897b4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 19 Sep 2018 15:45:28 +0200 Subject: [PATCH 0152/1415] Increased limiter values for passing the tests --- app/code/Magento/GraphQl/etc/di.xml | 4 +- .../Framework/QueryComplexityLimiterTest.php | 133 +++++++++++++++++- .../GraphQl/Query/QueryComplexityLimiter.php | 4 +- 3 files changed, 134 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index b1d24ce6c4a55..622888f697b84 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,8 +99,8 @@ </type> <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> - <argument name="queryDepth" xsi:type="number">15</argument> - <argument name="queryComplexity" xsi:type="number">50</argument> + <argument name="queryDepth" xsi:type="number">20</argument> + <argument name="queryComplexity" xsi:type="number">160</argument> </arguments> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 4616c450786ed..3304d9e6198f4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -90,6 +90,127 @@ public function testQueryComplexityIsLimited() id types } + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + thumbnail + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + thumbnail + canonical_url + updated_at + created_at + categories { + id + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + level + url_key + url_path + product_count + default_sort_by + breadcrumbs { + category_id + category_name + category_url_key + } + } + } + } + } + } + } + } + } + } + } } } } @@ -102,7 +223,7 @@ public function testQueryComplexityIsLimited() } QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 50 but got 62/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 160 but got 169/'); $this->graphQlQuery($query); } @@ -139,7 +260,13 @@ public function testQueryDepthIsLimited() categories { products { items { - name + categories { + products { + items { + name + } + } + } } } } @@ -163,7 +290,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 15 but got 20/'); + self::expectExceptionMessageRegExp('/Max query depth should be 20 but got 23/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index b302f4272527a..3936da21fc56a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -38,8 +38,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 15, - int $queryComplexity = 50 + int $queryDepth = 20, + int $queryComplexity = 160 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From cfcde56d19116889ef6e20f4e56e5b2a250674ec Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 16:45:48 +0300 Subject: [PATCH 0153/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- app/code/Magento/Sales/Controller/AbstractController/Reorder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index a03456d4c1f5f..2cd031c9f1f6e 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -46,7 +46,6 @@ public function __construct( * Action for reorder * * @return \Magento\Framework\Controller\ResultInterface - * @throws NotFoundException */ public function execute() { From cd9c5547af003c58ae8343a52fa8abb0e973323d Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 19 Sep 2018 17:51:56 +0300 Subject: [PATCH 0154/1415] MAGETWO-91495: 'Invalid data provided for linked products' error on 'Save & Duplicate' product action - CR fix --- .../Model/Product/AnchorUrlRewriteGenerator.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php index b3e8b0e2b0df5..a7cc894c9a022 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php @@ -62,9 +62,6 @@ public function generate($storeId, Product $product, ObjectRegistry $productCate if ($anchorCategoryIds) { foreach ($anchorCategoryIds as $anchorCategoryId) { $anchorCategory = $this->categoryRepository->get($anchorCategoryId); - if ($anchorCategory->getParentId() == \Magento\Catalog\Model\Category::TREE_ROOT_ID) { - continue; - } $urls[] = $this->urlRewriteFactory->create() ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE) ->setEntityId($product->getId()) From 8024b4c1c2a5c3a28c42805c3d52edea536f7501 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Thu, 20 Sep 2018 11:24:47 +0400 Subject: [PATCH 0155/1415] MAGETWO-91704: Can't cancel/change payment method after chosen Store Credit - Update automated test according to review --- .../Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index 8aaf626edab33..24ff30071830f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -9,7 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderFormPaymentSection"> - <element name="useCustomerBalance" type="checkbox" selector="#p_method_use_customerbalance"/> <element name="header" type="text" selector="#order-methods span.title"/> <element name="getShippingMethods" type="text" selector="#order-shipping_method a.action-default" timeout="30"/> <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> From a43f6603f2114ddaaebc5e76616d0c315e86203b Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 19 Sep 2018 02:50:20 +0300 Subject: [PATCH 0156/1415] MAGETWO-91537: Search synonyms results missing for words including hyphen and numbers - Removing hyphen from SPECIAL_CHARACTERS constant --- .../Search/Adapter/Mysql/Query/Builder/Match.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php index 8e3758817adf0..28e321d4c5d47 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php @@ -15,11 +15,16 @@ use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; /** + * Class for building select where condition. + * * @api */ class Match implements QueryInterface { - const SPECIAL_CHARACTERS = '-+~/\\<>\'":*$#@()!,.?`=%&^'; + /** + * @var string + */ + const SPECIAL_CHARACTERS = '+~/\\<>\'":*$#@()!,.?`=%&^'; const MINIMAL_CHARACTER_LENGTH = 3; @@ -69,7 +74,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( ScoreBuilder $scoreBuilder, @@ -113,6 +118,8 @@ public function build( } /** + * Prepare query value for build function. + * * @param string $queryValue * @param string $conditionType * @return string From 0d191b7ad858f0c4ef0e468b0a288861e5d2d5f2 Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Thu, 20 Sep 2018 11:57:51 +0300 Subject: [PATCH 0157/1415] Add label param to the image. --- .../Model/Resolver/Product/ProductImage.php | 10 ++++++---- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 6 ++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 3cf961c0f4225..9dc0dd68ee457 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -64,15 +64,17 @@ public function resolve( /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ $catalogImageHelper = $this->catalogImageHelperFactory->create(); - $imageUrl = $catalogImageHelper->init( + /** @var \Magento\Catalog\Helper\Image $image */ + $image = $catalogImageHelper->init( $product, 'product_' . $imageType, ['type' => $imageType] - )->getUrl(); + ); $imageData = [ - 'url' => $imageUrl, - 'path' => $product->getData($imageType) + 'url' => $image->getUrl(), + 'path' => $product->getData($imageType), + 'label' => $image->getLabel() ]; return $imageData; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 683dfb8de1f26..4a382e16447a4 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -264,9 +264,6 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ new_to_date: String @doc(description: "The end date for new product listings") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached") options_container: String @doc(description: "If the product has multiple options, determines where they appear on the product page") - image_label: String @doc(description: "The label assigned to a product image") - small_image_label: String @doc(description: "The label assigned to a product's small image") - thumbnail_label: String @doc(description: "The label assigned to a product's thumbnail image") created_at: String @doc(description: "Timestamp indicating when the product was created") updated_at: String @doc(description: "Timestamp indicating when the product was updated") country_of_manufacture: String @doc(description: "The product's country of origin") @@ -352,9 +349,10 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the image_size_y: Int @doc(description: "The maximum height of an image") } -type ProductImage @doc(description: "Product image information. Contains image relative path and URL") { +type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { url: String path: String + label: String } interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { From d3df40b11e75968eb78acee4cae47d27a3a5716c Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 20 Sep 2018 12:52:22 +0300 Subject: [PATCH 0158/1415] MAGETWO-94429: [2.3] Files and folders symlinked in pub/media cannot be deleted from media gallery browser --- .../Framework/Filesystem/Driver/FileTest.php | 75 ++++++++++++++++--- .../Framework/Filesystem/Driver/File.php | 15 +++- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php b/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php index 26401c782efc4..5f53e62165502 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php @@ -7,22 +7,27 @@ */ namespace Magento\Framework\Filesystem\Driver; -use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\Exception\FileSystemException; class FileTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\Filesystem\Driver\File + * @var File */ - protected $driver; + private $driver; /** - * @var string + * @var String */ - protected $absolutePath; + private $absolutePath; /** - * get relative path for test + * @var String + */ + private $generatedPath; + + /** + * Returns relative path for the test. * * @param $relativePath * @return string @@ -33,16 +38,26 @@ protected function getTestPath($relativePath) } /** - * Set up + * @inheritdoc */ public function setUp() { - $this->driver = new \Magento\Framework\Filesystem\Driver\File(); + $this->driver = new File(); $this->absolutePath = dirname(__DIR__) . '/_files/'; + $this->generatedPath = $this->getTestPath('generated'); + $this->removeGeneratedDirectory(); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->removeGeneratedDirectory(); } /** - * test read recursively read + * Tests directory recursive read. */ public function testReadDirectoryRecursively() { @@ -60,7 +75,7 @@ public function testReadDirectoryRecursively() } /** - * test exception + * Tests directory reading exception. * * @expectedException \Magento\Framework\Exception\FileSystemException */ @@ -69,6 +84,11 @@ public function testReadDirectoryRecursivelyFailure() $this->driver->readDirectoryRecursively($this->getTestPath('not-existing-directory')); } + /** + * Tests of directory creating. + * + * @throws FileSystemException + */ public function testCreateDirectory() { $generatedPath = $this->getTestPath('generated/roo/bar/baz/foo'); @@ -80,4 +100,39 @@ public function testCreateDirectory() $this->assertTrue($this->driver->createDirectory($generatedPath)); $this->assertTrue(is_dir($generatedPath)); } + + /** + * Tests creation and removing of symlinks. + * + * @throws FileSystemException + * @return void + */ + public function testSymlinks(): void + { + $sourceDirectory = $this->generatedPath . '/source'; + $destinationDirectory = $this->generatedPath . '/destination'; + + $this->driver->createDirectory($sourceDirectory); + $this->driver->createDirectory($destinationDirectory); + + $linkName = $destinationDirectory . '/link'; + + self::assertTrue($this->driver->isWritable($destinationDirectory)); + self::assertTrue($this->driver->symlink($sourceDirectory, $linkName)); + self::assertTrue($this->driver->isExists($linkName)); + self::assertTrue($this->driver->deleteDirectory($linkName)); + } + + /** + * Remove generated directories. + * + * @throws FileSystemException + * @return void + */ + private function removeGeneratedDirectory(): void + { + if (is_dir($this->generatedPath)) { + $this->driver->deleteDirectory($this->generatedPath); + } + } } diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index b54b02bd6de98..499d1f5adc9f3 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -14,6 +14,7 @@ /** * Class File + * * @package Magento\Framework\Filesystem\Driver * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -409,7 +410,14 @@ public function deleteDirectory($path) $this->deleteFile($entity->getPathname()); } } - $result = @rmdir($this->getScheme() . $path); + + $fullPath = $this->getScheme() . $path; + if (is_link($fullPath)) { + $result = @unlink($fullPath); + } else { + $result = @rmdir($fullPath); + } + if (!$result) { throw new FileSystemException( new \Magento\Framework\Phrase( @@ -843,6 +851,8 @@ public function fileUnlock($resource) } /** + * Returns an absolute path for the given one. + * * @param string $basePath * @param string $path * @param string|null $scheme @@ -879,7 +889,8 @@ public function getRelativePath($basePath, $path = null) } /** - * Fixes path separator + * Fixes path separator. + * * Utility method. * * @param string $path From 6e20bdd2d7e4bc3b177980620eac2161281f10ae Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Thu, 20 Sep 2018 16:55:49 +0600 Subject: [PATCH 0159/1415] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Added automated test --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 8 ++ .../Test/Mftf/Data/CheckoutConfigData.xml | 25 ++++++ .../Mftf/Metadata/checkout_config-meta.xml | 86 +++++++++++++++++++ .../Section/CheckoutCartSummarySection.xml | 1 + .../CheckoutTotalsSortOrderInCartTest.xml | 53 ++++++++++++ .../Test/Mftf/Data/SalesRuleData.xml | 29 +++++++ 6 files changed, 202 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 41be15d0ca410..01a7d8ead9132 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -86,6 +86,14 @@ <see userInput="${{total}}" selector="{{CheckoutPaymentSection.orderSummaryTotal}}" stepKey="assertTotal"/> </actionGroup> + <actionGroup name="CheckTotalsSortOrderInSummarySection"> + <arguments> + <argument name="elementName" type="string"/> + <argument name="positionNumber" type="integer"/> + </arguments> + <see userInput="{{elementName}}" selector="{{CheckoutCartSummarySection.elementPosition(positionNumber)}}" stepKey="assertElementPosition"/> + </actionGroup> + <!-- Check ship to information in checkout --> <actionGroup name="CheckShipToInformationInCheckoutActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml new file mode 100644 index 0000000000000..bf2ae28009011 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CheckoutShippingTotalsSortOrder" type="checkout_totals_sort_order"> + <requiredEntity type="shipping">ShippingTotalsSortOrder</requiredEntity> + </entity> + + <entity name="ShippingTotalsSortOrder" type="shipping"> + <data key="value">27</data> + </entity> + + <entity name="DefaultCheckoutTotalsSortOrder" type="default_checkout_totals_sort_order"> + <requiredEntity type="checkoutTotalFlagZero">DefaultTotalFlagZero</requiredEntity> + </entity> + <entity name="DefaultTotalFlagZero" type="checkoutTotalFlagZero"> + <data key="value">0</data> + </entity> +</entities> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml new file mode 100644 index 0000000000000..55572ee73ac46 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="SetCheckoutTotalsSortOrder" dataType="checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="checkout_totals_sort_order"> + <object key="totals_sort" dataType="checkout_totals_sort_order"> + <object key="fields" dataType="checkout_totals_sort_order"> + <object key="subtotal" dataType="subtotal"> + <field key="value">integer</field> + </object> + <object key="discount" dataType="discount"> + <field key="value">integer</field> + </object> + <object key="shipping" dataType="shipping"> + <field key="value">integer</field> + </object> + <object key="tax" dataType="tax"> + <field key="value">integer</field> + </object> + <object key="weee" dataType="weee"> + <field key="value">integer</field> + </object> + <object key="grand_total" dataType="grand_total"> + <field key="value">integer</field> + </object> + <object key="giftcardaccount" dataType="giftcardaccount"> + <field key="value">integer</field> + </object> + <object key="customerbalance" dataType="customerbalance"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> + + <operation name="DefaultCheckoutTotalsSortOrder" dataType="default_checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="default_checkout_totals_sort_order"> + <object key="totals_sort" dataType="default_checkout_totals_sort_order"> + <object key="fields" dataType="default_checkout_totals_sort_order"> + <object key="subtotal" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="discount" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="shipping" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="tax" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="weee" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grand_total" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="giftcardaccount" dataType="giftcardaccount"> + <field key="value">integer</field> + </object> + <object key="customerbalance" dataType="customerbalance"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> +</operations> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index a1a8d2ba3eade..b1547f2ef4d92 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -9,6 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CheckoutCartSummarySection"> + <element name="elementPosition" type="text" selector=".data.table.totals > tbody tr:nth-of-type({{value}}) > th" parameterized="true"/> <element name="subtotal" type="text" selector="//*[@id='cart-totals']//tr[@class='totals sub']//td//span[@class='price']"/> <element name="shippingMethod" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//th//span[@class='value']"/> <element name="shipping" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//td//span[@class='price']"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml new file mode 100644 index 0000000000000..e1ec9032e072a --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="CheckoutTotalsSortOrderInCartTest"> + <annotations> + <title value="Checkout Totals Sort Order configuration and displaying in cart"/> + <stories value="MAGETWO-91658: Wrong Checkout Totals Sort Order in cart"/> + <description value="Checkout Totals Sort Order configuration and displaying in cart"/> + <features value="Checkout"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-94944"/> + <group value="Checkout"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="defaultCategory"/> + <createData entity="SimpleProduct" stepKey="simpleProduct"> + <requiredEntity createDataKey="defaultCategory"/> + </createData> + + <createData entity="ApiCartRule" stepKey="cartRule"/> + + <createData entity="CheckoutShippingTotalsSortOrder" stepKey="setConfigShippingTotalsSortOrder"/> + </before> + + <actionGroup ref="VerifyDiscountAmount" stepKey="verifyStorefront"> + <argument name="productUrl" value="$$simpleProduct.sku$$.html"/> + <argument name="quantity" value="1"/> + <argument name="expectedDiscount" value="-$61.50"/> + </actionGroup> + + <actionGroup ref="CheckTotalsSortOrderInSummarySection" stepKey="checkTotalsSortOrderInSummarySection"> + <argument name="elementName" value="Shipping (Flat Rate - Fixed)"/> + <argument name="positionNumber" value="3"/> + </actionGroup> + + <after> + <createData entity="DefaultCheckoutTotalsSortOrder" stepKey="setDefaultTotalsSortOrder"/> + + <deleteData createDataKey="cartRule" stepKey="deleteCartRule"/> + <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="defaultCategory" stepKey="deleteCategory"/> + + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </after> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml index 5b7585b8b2a3f..2ac4917683450 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml @@ -39,6 +39,35 @@ <requiredEntity type="SalesRuleLabel">SalesRuleLabelStore1</requiredEntity> </entity> + <entity name="ApiCartRule" type="SalesRule"> + <data key="name" unique="suffix">salesRule</data> + <data key="description">Sales Rule Descritpion</data> + <array key="website_ids"> + <item>1</item> + </array> + <array key="customer_group_ids"> + <item>0</item> + <item>1</item> + <item>3</item> + </array> + <data key="uses_per_customer">0</data> + <data key="is_active">true</data> + <data key="stop_rules_processing">true</data> + <data key="is_advanced">true</data> + <data key="sort_order">0</data> + <data key="simple_action">by_percent</data> + <data key="discount_amount">50</data> + <data key="discount_qty">0</data> + <data key="discount_step">0</data> + <data key="apply_to_shipping">false</data> + <data key="times_used">0</data> + <data key="is_rss">true</data> + <data key="coupon_type">NO_COUPON</data> + <data key="use_auto_generation">false</data> + <data key="uses_per_coupon">0</data> + <data key="simple_free_shipping">0</data> + </entity> + <entity name="SimpleSalesRule" type="SalesRule"> <data key="name" unique="suffix">SimpleSalesRule</data> <data key="is_active">true</data> From 6a1feedebb45fb54fd496db44dc9a280835c0203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Brada?= <jir.brada@gmail.com> Date: Thu, 20 Sep 2018 13:31:52 +0200 Subject: [PATCH 0160/1415] Added $fieldId parameter into Config::getFieldPath method for fix of "clone_field" system config feature. --- app/code/Magento/Config/Model/Config.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php index c6e2412f7e58f..7ea979df30a41 100644 --- a/app/code/Magento/Config/Model/Config.php +++ b/app/code/Magento/Config/Model/Config.php @@ -237,13 +237,14 @@ private function getField(string $sectionId, string $groupId, string $fieldId): * Get field path * * @param Field $field + * @param string $fieldId Need for support of clone_field feature * @param array &$oldConfig Need for compatibility with _processGroup() * @param array &$extraOldGroups Need for compatibility with _processGroup() * @return string */ - private function getFieldPath(Field $field, array &$oldConfig, array &$extraOldGroups): string + private function getFieldPath(Field $field, string $fieldId, array &$oldConfig, array &$extraOldGroups): string { - $path = $field->getGroupPath() . '/' . $field->getId(); + $path = $field->getGroupPath() . '/' . $fieldId; /** * Look for custom defined field path @@ -303,7 +304,7 @@ private function getChangedPaths( if (isset($groupData['fields'])) { foreach ($groupData['fields'] as $fieldId => $fieldData) { $field = $this->getField($sectionId, $groupId, $fieldId); - $path = $this->getFieldPath($field, $oldConfig, $extraOldGroups); + $path = $this->getFieldPath($field, $fieldId, $oldConfig, $extraOldGroups); if ($this->isValueChanged($oldConfig, $path, $fieldData)) { $changedPaths[] = $path; } @@ -398,7 +399,7 @@ protected function _processGroup( $backendModel->addData($data); $this->_checkSingleStoreMode($field, $backendModel); - $path = $this->getFieldPath($field, $extraOldGroups, $oldConfig); + $path = $this->getFieldPath($field, $fieldId, $extraOldGroups, $oldConfig); $backendModel->setPath($path)->setValue($fieldData['value']); $inherit = !empty($fieldData['inherit']); @@ -604,4 +605,4 @@ public function getConfigDataValue($path, &$inherit = null, $configData = null) return $data; } -} +} \ No newline at end of file From 75ff41384df389d1996f0770d603c7abe0bc9a93 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 20 Sep 2018 17:29:50 +0300 Subject: [PATCH 0161/1415] MAGETWO-91532: Copy tier price for copied products - Fix unit test --- .../Attribute/Backend/TierPrice/UpdateHandlerTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Attribute/Backend/TierPrice/UpdateHandlerTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Attribute/Backend/TierPrice/UpdateHandlerTest.php index 3572cb9d87f0c..cce00c50d37af 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Attribute/Backend/TierPrice/UpdateHandlerTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Attribute/Backend/TierPrice/UpdateHandlerTest.php @@ -120,8 +120,13 @@ public function testExecute(): void ['entity_id', $productId] ] ); - $product->expects($this->atLeastOnce())->method('getOrigData')->with('tier_price') - ->willReturn($originalTierPrices); + $product->expects($this->atLeastOnce())->method('getOrigData') + ->willReturnMap( + [ + ['tier_price', $originalTierPrices], + ['entity_id', $productId] + ] + ); $product->expects($this->atLeastOnce())->method('getStoreId')->willReturn(0); $product->expects($this->atLeastOnce())->method('setData')->with('tier_price_changed', 1); $store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class) From 10c08ae5c26307668964bf03ad7ef124ffddde5a Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 20 Sep 2018 19:36:02 +0300 Subject: [PATCH 0162/1415] MAGETWO-91733: Unusual behavior with the persistent shopping cart after the session is expired - Added observer to pass customer data from persistent session to checkout session --- ...tCheckoutSessionPersistentDataObserver.php | 90 +++++++++++ .../SetLoadPersistentQuoteObserver.php | 78 --------- ...ckoutSessionPersistentDataObserverTest.php | 149 ++++++++++++++++++ .../SetLoadPersistentQuoteObserverTest.php | 73 --------- .../Persistent/etc/frontend/events.xml | 2 +- .../Persistent/etc/webapi_rest/events.xml | 2 +- .../Persistent/etc/webapi_soap/events.xml | 2 +- 7 files changed, 242 insertions(+), 154 deletions(-) create mode 100644 app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php delete mode 100644 app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php create mode 100644 app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php delete mode 100644 app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php diff --git a/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php b/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php new file mode 100644 index 0000000000000..e89a09c0d2a9c --- /dev/null +++ b/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php @@ -0,0 +1,90 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Persistent\Observer; + +use Magento\Framework\Event\ObserverInterface; + +/** + * Class SetCheckoutSessionPersistentDataObserver + */ +class SetCheckoutSessionPersistentDataObserver implements ObserverInterface +{ + /** + * Persistent session + * + * @var \Magento\Persistent\Helper\Session + */ + private $persistentSession = null; + + /** + * Customer session + * + * @var \Magento\Customer\Model\Session + */ + private $customerSession; + + /** + * Persistent data + * + * @var \Magento\Persistent\Helper\Data + */ + private $persistentData = null; + + /** + * Customer Repository + * + * @var \Magento\Customer\Api\CustomerRepositoryInterface + */ + private $customerRepository = null; + + /** + * @param \Magento\Persistent\Helper\Session $persistentSession + * @param \Magento\Customer\Model\Session $customerSession + * @param \Magento\Persistent\Helper\Data $persistentData + * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + */ + public function __construct( + \Magento\Persistent\Helper\Session $persistentSession, + \Magento\Customer\Model\Session $customerSession, + \Magento\Persistent\Helper\Data $persistentData, + \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + ) { + $this->persistentSession = $persistentSession; + $this->customerSession = $customerSession; + $this->persistentData = $persistentData; + $this->customerRepository = $customerRepository; + } + + /** + * Pass customer data from persistent session to checkout session and set quote to be loaded even if not active + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(\Magento\Framework\Event\Observer $observer) + { + /** @var $checkoutSession \Magento\Checkout\Model\Session */ + $checkoutSession = $observer->getEvent()->getData('checkout_session'); + if ($this->persistentData->isShoppingCartPersist() && $this->persistentSession->isPersistent()) { + $checkoutSession->setCustomerData( + $this->customerRepository->getById($this->persistentSession->getSession()->getCustomerId()) + ); + } + if (!(($this->persistentSession->isPersistent() && !$this->customerSession->isLoggedIn()) + && !$this->persistentData->isShoppingCartPersist() + )) { + return; + } + if ($checkoutSession) { + $checkoutSession->setLoadInactive(); + } + } +} diff --git a/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php deleted file mode 100644 index 6eeab94a91cca..0000000000000 --- a/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php -/** - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Persistent\Observer; - -use Magento\Framework\Event\ObserverInterface; - -class SetLoadPersistentQuoteObserver implements ObserverInterface -{ - /** - * Customer session - * - * @var \Magento\Customer\Model\Session - */ - protected $_customerSession; - - /** - * Checkout session - * - * @var \Magento\Checkout\Model\Session - */ - protected $_checkoutSession; - - /** - * Persistent session - * - * @var \Magento\Persistent\Helper\Session - */ - protected $_persistentSession = null; - - /** - * Persistent data - * - * @var \Magento\Persistent\Helper\Data - */ - protected $_persistentData = null; - - /** - * @param \Magento\Persistent\Helper\Session $persistentSession - * @param \Magento\Persistent\Helper\Data $persistentData - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Checkout\Model\Session $checkoutSession - */ - public function __construct( - \Magento\Persistent\Helper\Session $persistentSession, - \Magento\Persistent\Helper\Data $persistentData, - \Magento\Customer\Model\Session $customerSession, - \Magento\Checkout\Model\Session $checkoutSession - ) { - $this->_persistentSession = $persistentSession; - $this->_customerSession = $customerSession; - $this->_checkoutSession = $checkoutSession; - $this->_persistentData = $persistentData; - } - - /** - * Set quote to be loaded even if not active - * - * @param \Magento\Framework\Event\Observer $observer - * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - if (!(($this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn()) - && !$this->_persistentData->isShoppingCartPersist() - )) { - return; - } - - if ($this->_checkoutSession) { - $this->_checkoutSession->setLoadInactive(); - } - } -} diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php new file mode 100644 index 0000000000000..01c217c1c5cd4 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php @@ -0,0 +1,149 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Persistent\Test\Unit\Observer; + +/** + * Class SetCheckoutSessionPersistentDataObserverTest + */ +class SetCheckoutSessionPersistentDataObserverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver + */ + private $model; + + /** + * @var \Magento\Persistent\Helper\Data| \PHPUnit_Framework_MockObject_MockObject + */ + private $helperMock; + + /** + * @var \Magento\Persistent\Helper\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $sessionHelperMock; + + /** + * @var \Magento\Checkout\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $checkoutSessionMock; + + /** + * @var \Magento\Customer\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $customerSessionMock; + + /** + * @var \Magento\Persistent\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $persistentSessionMock; + + /** + * @var \Magento\Customer\Api\CustomerRepositoryInterface| \PHPUnit_Framework_MockObject_MockObject + */ + private $customerRepositoryMock; + + /** + * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject + */ + private $eventMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->helperMock = $this->createMock(\Magento\Persistent\Helper\Data::class); + $this->sessionHelperMock = $this->createMock(\Magento\Persistent\Helper\Session::class); + $this->checkoutSessionMock = $this->createMock(\Magento\Checkout\Model\Session::class); + $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); + $this->observerMock = $this->createMock(\Magento\Framework\Event\Observer::class); + $this->eventMock = $this->createPartialMock(\Magento\Framework\Event::class, ['getData']); + $this->persistentSessionMock = $this->createPartialMock( + \Magento\Persistent\Model\Session::class, + ['getCustomerId'] + ); + $this->customerRepositoryMock = $this->createMock( + \Magento\Customer\Api\CustomerRepositoryInterface::class + ); + $this->model = new \Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver( + $this->sessionHelperMock, + $this->customerSessionMock, + $this->helperMock, + $this->customerRepositoryMock + ); + } + + /** + * Test execute method when session is not persistent + * + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testExecuteWhenSessionIsNotPersistent() + { + $this->observerMock->expects($this->once()) + ->method('getEvent') + ->will($this->returnValue($this->eventMock)); + $this->eventMock->expects($this->once()) + ->method('getData') + ->will($this->returnValue($this->checkoutSessionMock)); + $this->sessionHelperMock->expects($this->once()) + ->method('isPersistent') + ->will($this->returnValue(false)); + $this->checkoutSessionMock->expects($this->never()) + ->method('setLoadInactive'); + $this->checkoutSessionMock->expects($this->never()) + ->method('setCustomerData'); + $this->model->execute($this->observerMock); + } + + /** + * Test execute method when session is persistent + * + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testExecute() + { + $this->observerMock->expects($this->once()) + ->method('getEvent') + ->will($this->returnValue($this->eventMock)); + $this->eventMock->expects($this->once()) + ->method('getData') + ->will($this->returnValue($this->checkoutSessionMock)); + $this->sessionHelperMock->expects($this->exactly(2)) + ->method('isPersistent') + ->will($this->returnValue(true)); + $this->customerSessionMock->expects($this->once()) + ->method('isLoggedIn') + ->will($this->returnValue(false)); + $this->helperMock->expects($this->exactly(2)) + ->method('isShoppingCartPersist') + ->will($this->returnValue(true)); + $this->persistentSessionMock->expects($this->once()) + ->method('getCustomerId') + ->will($this->returnValue(123)); + $this->sessionHelperMock->expects($this->once()) + ->method('getSession') + ->will($this->returnValue($this->persistentSessionMock)); + $this->customerRepositoryMock->expects($this->once()) + ->method('getById') + ->will($this->returnValue(true)); //? + $this->checkoutSessionMock->expects($this->never()) + ->method('setLoadInactive'); + $this->checkoutSessionMock->expects($this->once()) + ->method('setCustomerData'); + $this->model->execute($this->observerMock); + } +} diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php deleted file mode 100644 index fd78a6852ea59..0000000000000 --- a/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Persistent\Test\Unit\Observer; - -class SetLoadPersistentQuoteObserverTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Persistent\Observer\SetLoadPersistentQuoteObserver - */ - protected $model; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $helperMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $sessionHelperMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $checkoutSessionMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSessionMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $observerMock; - - protected function setUp() - { - $this->helperMock = $this->createMock(\Magento\Persistent\Helper\Data::class); - $this->sessionHelperMock = $this->createMock(\Magento\Persistent\Helper\Session::class); - $this->checkoutSessionMock = $this->createMock(\Magento\Checkout\Model\Session::class); - $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); - $this->observerMock = $this->createMock(\Magento\Framework\Event\Observer::class); - - $this->model = new \Magento\Persistent\Observer\SetLoadPersistentQuoteObserver( - $this->sessionHelperMock, - $this->helperMock, - $this->customerSessionMock, - $this->checkoutSessionMock - ); - } - - public function testExecuteWhenSessionIsNotPersistent() - { - $this->sessionHelperMock->expects($this->once())->method('isPersistent')->will($this->returnValue(false)); - $this->checkoutSessionMock->expects($this->never())->method('setLoadInactive'); - $this->model->execute($this->observerMock); - } - - public function testExecute() - { - $this->sessionHelperMock->expects($this->once())->method('isPersistent')->will($this->returnValue(true)); - $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->will($this->returnValue(false)); - $this->helperMock->expects($this->once())->method('isShoppingCartPersist')->will($this->returnValue(true)); - $this->checkoutSessionMock->expects($this->never())->method('setLoadInactive'); - $this->model->execute($this->observerMock); - } -} diff --git a/app/code/Magento/Persistent/etc/frontend/events.xml b/app/code/Magento/Persistent/etc/frontend/events.xml index 193b9a10818e4..79720695ea6f6 100644 --- a/app/code/Magento/Persistent/etc/frontend/events.xml +++ b/app/code/Magento/Persistent/etc/frontend/events.xml @@ -49,7 +49,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> diff --git a/app/code/Magento/Persistent/etc/webapi_rest/events.xml b/app/code/Magento/Persistent/etc/webapi_rest/events.xml index 1eff845386bf4..79dffa1834563 100644 --- a/app/code/Magento/Persistent/etc/webapi_rest/events.xml +++ b/app/code/Magento/Persistent/etc/webapi_rest/events.xml @@ -22,7 +22,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> diff --git a/app/code/Magento/Persistent/etc/webapi_soap/events.xml b/app/code/Magento/Persistent/etc/webapi_soap/events.xml index 1eff845386bf4..79dffa1834563 100644 --- a/app/code/Magento/Persistent/etc/webapi_soap/events.xml +++ b/app/code/Magento/Persistent/etc/webapi_soap/events.xml @@ -22,7 +22,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> From c20f29f64d188c84edc157a64c772e29ea7d357c Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 18 Sep 2018 11:51:55 -0500 Subject: [PATCH 0163/1415] MAGETWO-87454: Catalog Products List widget doesn't work with 'contains/not contains' operator --- .../Rule/Model/Condition/Sql/Builder.php | 38 +++++++++++++----- .../Block/Product/ProductListTest.php | 39 +++++++++++++++++++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 0b824ca94ca3e..995999c3a0cde 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -41,6 +41,14 @@ class Builder '!()' => ':field NOT IN (?)', ]; + /** + * @var array + */ + private $stringConditionOperatorMap = [ + '{}' => ':field LIKE ?', + '!{}' => ':field NOT LIKE ?', + ]; + /** * @var \Magento\Rule\Model\Condition\Sql\ExpressionFactory */ @@ -152,15 +160,27 @@ protected function _getMappedSqlCondition( } $defaultValue = 0; - $sql = str_replace( - ':field', - $this->_connection->getIfNullSql($this->_connection->quoteIdentifier($argument), $defaultValue), - $this->_conditionOperatorMap[$conditionOperator] - ); - - $bindValue = $condition->getBindArgumentValue(); - $expression = $value . $this->_connection->quoteInto($sql, $bindValue); - + //operator 'contains {}' is mapped to 'IN()' query that cannot work with substrings + // adding mapping to 'LIKE %%' + if ($condition->getInputType() === 'string' + && in_array($conditionOperator, array_keys($this->stringConditionOperatorMap), true) + ) { + $sql = str_replace( + ':field', + $this->_connection->getIfNullSql($this->_connection->quoteIdentifier($argument), $defaultValue), + $this->stringConditionOperatorMap[$conditionOperator] + ); + $bindValue = $condition->getBindArgumentValue(); + $expression = $value . $this->_connection->quoteInto($sql, "%$bindValue%"); + } else { + $sql = str_replace( + ':field', + $this->_connection->getIfNullSql($this->_connection->quoteIdentifier($argument), $defaultValue), + $this->_conditionOperatorMap[$conditionOperator] + ); + $bindValue = $condition->getBindArgumentValue(); + $expression = $value . $this->_connection->quoteInto($sql, $bindValue); + } // values for multiselect attributes can be saved in comma-separated format // below is a solution for matching such conditions with selected values if (is_array($bindValue) && \in_array($conditionOperator, ['()', '{}'], true)) { diff --git a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php index ba428dd00ddb4..2f2029d2f13e1 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php @@ -131,4 +131,43 @@ private function performAssertions(int $count) "Product collection was not filtered according to the widget condition." ); } + + /** + * Check that collection returns correct result if use not contains operator for string attribute + * + * @magentoDbIsolation disabled + * @magentoDataFixture Magento/Catalog/_files/product_special_price.php + * @magentoDataFixture Magento/Catalog/_files/product_virtual.php + * @dataProvider createCollectionForSkuDataProvider + * @return void + */ + public function testCreateCollectionForSku($encodedConditions) + { + $this->block->setData('conditions_encoded', $encodedConditions); + $productCollection = $this->block->createCollection(); + $productCollection->load(); + $this->assertEquals( + 1, + $productCollection->count(), + "Product collection was not filtered according to the widget condition." + ); + $this->assertEquals('virtual-product', $productCollection->getFirstItem()->getSku()); + } + + /** + * @return array + */ + public function createCollectionForSkuDataProvider() + { + return [ + 'contains' => ['^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' + . '`aggregator`:`all`,`value`:`1`,`new_child`:``^],' + . '`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,' + . '`attribute`:`sku`,`operator`:`^[^]`,`value`:`virtual`^]^]'], + 'not contains' => ['^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' + . '`aggregator`:`all`,`value`:`1`,`new_child`:``^],' + . '`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,' + . '`attribute`:`sku`,`operator`:`!^[^]`,`value`:`simple`^]^]'] + ]; + } } From 25b15e5feb8b764b538b92d551eaea79541c851b Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Thu, 20 Sep 2018 21:47:55 +0300 Subject: [PATCH 0164/1415] Update Tests --- .../Model/Recommendations/DataProvider.php | 30 +-- .../CatalogInventory/Model/Configuration.php | 29 ++- app/code/Magento/Checkout/Helper/Data.php | 33 ++-- app/code/Magento/Customer/Helper/Address.php | 2 +- .../Customer/Model/AccountConfirmation.php | 15 +- .../Ui/Component/DataProvider/Document.php | 15 +- app/code/Magento/Directory/Helper/Data.php | 56 +++--- .../Directory/Test/Unit/Helper/DataTest.php | 2 +- .../Model/DataProvider/Suggestions.php | 4 +- .../Magento/GoogleOptimizer/Helper/Data.php | 12 +- app/code/Magento/Msrp/Model/Config.php | 14 +- .../Magento/Reports/Model/ReportStatus.php | 10 +- .../Model/ResourceModel/Catalog/Product.php | 10 +- .../Magento/Store/Model/BaseUrlChecker.php | 10 +- .../Store/Model/HeaderProvider/Hsts.php | 10 +- .../Model/HeaderProvider/UpgradeInsecure.php | 10 +- app/code/Magento/Store/Model/StoreManager.php | 184 +++++++++--------- .../Magento/Wishlist/Model/Rss/Wishlist.php | 2 +- .../Magento/Framework/Session/SidResolver.php | 17 +- 19 files changed, 236 insertions(+), 229 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php index c1103e514e0f0..f0d998e19d7f1 100644 --- a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php +++ b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php @@ -53,14 +53,14 @@ class DataProvider implements SuggestedQueriesInterface */ private $recommendationsFactory; - /** - * DataProvider constructor. - * - * @param ScopeConfigInterface $scopeConfig - * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver - * @param \Magento\AdvancedSearch\Model\ResourceModel\RecommendationsFactory $recommendationsFactory - * @param \Magento\Search\Model\QueryResultFactory $queryResultFactory - */ + /** + * DataProvider constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver + * @param \Magento\AdvancedSearch\Model\ResourceModel\RecommendationsFactory $recommendationsFactory + * @param \Magento\Search\Model\QueryResultFactory $queryResultFactory + */ public function __construct( ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Layer\Resolver $layerResolver, @@ -86,13 +86,13 @@ public function isResultsCountEnabled() ); } - /** - * Get Items - * - * @param QueryInterface $query - * - * @return array|\Magento\Search\Model\QueryResult[] - */ + /** + * Get Items + * + * @param QueryInterface $query + * + * @return array|\Magento\Search\Model\QueryResult[] + */ public function getItems(QueryInterface $query) { $recommendations = []; diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php index a303b15d11a4e..a18fe053d5cef 100644 --- a/app/code/Magento/CatalogInventory/Model/Configuration.php +++ b/app/code/Magento/CatalogInventory/Model/Configuration.php @@ -131,14 +131,14 @@ class Configuration implements StockConfigurationInterface */ protected $storeManager; - /** - * Configuration constructor. - * - * @param ConfigInterface $config - * @param ScopeConfigInterface $scopeConfig - * @param MinsaleqtyHelper $minsaleqtyHelper - * @param StoreManagerInterface $storeManager - */ + /** + * Configuration constructor. + * + * @param ConfigInterface $config + * @param ScopeConfigInterface $scopeConfig + * @param MinsaleqtyHelper $minsaleqtyHelper + * @param StoreManagerInterface $storeManager + */ public function __construct( ConfigInterface $config, ScopeConfigInterface $scopeConfig, @@ -151,11 +151,11 @@ public function __construct( $this->storeManager = $storeManager; } - /** - * Default Scope Id - * - * @return int - */ + /** + * Default Scope Id + * + * @return int + */ public function getDefaultScopeId() { // TODO: should be fixed in MAGETWO-46043 @@ -380,8 +380,7 @@ public function isAutoReturnEnabled($store = null) } /** - * Get 'Display product stock status' option value - * Shows if it is necessary to show product stock status ('in stock'/'out of stock') + * Display product stock status. Shows if it is necessary to show product stock status in stock/out of stock. * * @param null|string|bool|int|\Magento\Store\Model\Store $store * @return bool diff --git a/app/code/Magento/Checkout/Helper/Data.php b/app/code/Magento/Checkout/Helper/Data.php index eb96913806f06..40bdf93d161ed 100644 --- a/app/code/Magento/Checkout/Helper/Data.php +++ b/app/code/Magento/Checkout/Helper/Data.php @@ -58,19 +58,19 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ private $paymentFailures; - /** - * Data constructor. - * - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder - * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation - * @param PriceCurrencyInterface $priceCurrency - * @param PaymentFailuresInterface|null $paymentFailures - * @codeCoverageIgnore - */ + /** + * Data constructor. + * + * @param \Magento\Framework\App\Helper\Context $context + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate + * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder + * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation + * @param PriceCurrencyInterface $priceCurrency + * @param PaymentFailuresInterface|null $paymentFailures + * @codeCoverageIgnore + */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -116,6 +116,7 @@ public function getQuote() /** * Format Price + * * @param float $price * @return string */ @@ -253,8 +254,7 @@ protected function _getEmails($configPath, $storeId) } /** - * Check is allowed Guest Checkout - * Use config settings and observer + * Check is allowed Guest Checkout. Use config settings and observer * * @param \Magento\Quote\Model\Quote $quote * @param int|Store $store @@ -311,8 +311,7 @@ public function isCustomerMustBeLogged() } /** - * Checks if display billing address on payment method is available, otherwise - * billing address should be display on payment page + * If display billing address on payment method is available, otherwise should be display on payment page * * @return bool */ diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php index a05a4845f4a4d..cae8ea16c6348 100644 --- a/app/code/Magento/Customer/Helper/Address.php +++ b/app/code/Magento/Customer/Helper/Address.php @@ -175,7 +175,7 @@ public function getRenderer($renderer) /** * Return customer address config value by key and store * - * @param string $key + * @param string $key * @param \Magento\Store\Model\Store|int|string $store * * @return string|null diff --git a/app/code/Magento/Customer/Model/AccountConfirmation.php b/app/code/Magento/Customer/Model/AccountConfirmation.php index cb35c16c7f3bf..f29330af25874 100644 --- a/app/code/Magento/Customer/Model/AccountConfirmation.php +++ b/app/code/Magento/Customer/Model/AccountConfirmation.php @@ -10,8 +10,7 @@ use Magento\Framework\Registry; /** - * Class AccountConfirmation. - * Checks if email confirmation required for customer. + * Class AccountConfirmation. Checks if email confirmation required for customer. */ class AccountConfirmation { @@ -30,12 +29,12 @@ class AccountConfirmation */ private $registry; - /** - * AccountConfirmation constructor. - * - * @param ScopeConfigInterface $scopeConfig - * @param Registry $registry - */ + /** + * AccountConfirmation constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param Registry $registry + */ public function __construct( ScopeConfigInterface $scopeConfig, Registry $registry diff --git a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php index 714e2b11daead..9180268ac5cc6 100644 --- a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php +++ b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php @@ -124,8 +124,7 @@ public function getCustomAttribute($attributeCode) } /** - * Update customer gender value - * Method set gender label instead of id value + * Update customer gender value. Method set gender label instead of id value * * @return void * @throws \Magento\Framework\Exception\LocalizedException @@ -149,8 +148,7 @@ private function setGenderValue() } /** - * Update customer group value - * Method set group code instead id value + * Update customer group value. Method set group code instead id value * * @return void * @throws \Magento\Framework\Exception\LocalizedException @@ -167,8 +165,7 @@ private function setCustomerGroupValue() } /** - * Update website value - * Method set website name instead id value + * Update website value. Method set website name instead id value * * @return void */ @@ -181,8 +178,7 @@ private function setWebsiteValue() } /** - * Update confirmation value - * Method set confirmation text value to match what is shown in grid + * Update confirmation value. Method set confirmation text value to match what is shown in grid * * @return void */ @@ -205,8 +201,7 @@ private function setConfirmationValue() } /** - * Update lock expires value - * Method set account lock text value to match what is shown in grid + * Update lock expires value. Method set account lock text value to match what is shown in grid * * @return void */ diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php index 3617bf52d720f..14619ce9bfc50 100644 --- a/app/code/Magento/Directory/Helper/Data.php +++ b/app/code/Magento/Directory/Helper/Data.php @@ -7,7 +7,14 @@ namespace Magento\Directory\Helper; use Magento\Directory\Model\Currency; +use Magento\Directory\Model\CurrencyFactory; +use Magento\Directory\Model\ResourceModel\Country\Collection; +use Magento\Directory\Model\ResourceModel\Region\CollectionFactory; +use Magento\Framework\App\Cache\Type\Config; +use Magento\Framework\App\Helper\Context; +use Magento\Framework\Json\Helper\Data as JsonData; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; /** * Directory data helper @@ -54,7 +61,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * Country collection * - * @var \Magento\Directory\Model\ResourceModel\Country\Collection + * @var Collection */ protected $_countryCollection; @@ -87,49 +94,49 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper protected $_optZipCountries = null; /** - * @var \Magento\Framework\App\Cache\Type\Config + * @var Config */ protected $_configCacheType; /** - * @var \Magento\Directory\Model\ResourceModel\Region\CollectionFactory + * @var CollectionFactory */ protected $_regCollectionFactory; /** - * @var \Magento\Framework\Json\Helper\Data + * @var JsonData */ protected $jsonHelper; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $_storeManager; /** - * @var \Magento\Directory\Model\CurrencyFactory + * @var CurrencyFactory */ protected $_currencyFactory; /** * Data constructor. * - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\Framework\App\Cache\Type\Config $configCacheType - * @param \Magento\Directory\Model\ResourceModel\Country\Collection $countryCollection - * @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regCollectionFactory, - * @param \Magento\Framework\Json\Helper\Data $jsonHelper - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory + * @param Context $context + * @param Config $configCacheType + * @param Collection $countryCollection + * @param CollectionFactory $regCollectionFactory, + * @param JsonData $jsonHelper + * @param StoreManagerInterface $storeManager + * @param CurrencyFactory currencyFactory */ public function __construct( - \Magento\Framework\App\Helper\Context $context, - \Magento\Framework\App\Cache\Type\Config $configCacheType, - \Magento\Directory\Model\ResourceModel\Country\Collection $countryCollection, - \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regCollectionFactory, - \Magento\Framework\Json\Helper\Data $jsonHelper, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Directory\Model\CurrencyFactory $currencyFactory + Context $context, + Config $configCacheType, + Collection $countryCollection, + CollectionFactory $regCollectionFactory, + JsonData $jsonHelper, + StoreManagerInterface $storeManager, + CurrencyFactory $currencyFactory ) { parent::__construct($context); $this->_configCacheType = $configCacheType; @@ -158,7 +165,7 @@ public function getRegionCollection() * Retrieve country collection * * @param null|int|string|\Magento\Store\Model\Store $store - * @return \Magento\Directory\Model\ResourceModel\Country\Collection + * @return Collection */ public function getCountryCollection($store = null) { @@ -198,7 +205,7 @@ public function getRegionJson() /** * Convert currency * - * @param float $amount + * @param float $amount * @param string $from * @param string $to * @@ -309,7 +316,10 @@ public function isRegionRequired($countryId) */ public function getBaseCurrencyCode() { - return $this->scopeConfig->getValue( Currency::XML_PATH_CURRENCY_BASE, 'default'); + return $this->scopeConfig->getValue( + Currency::XML_PATH_CURRENCY_BASE, + 'default' + ); } /** diff --git a/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php b/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php index 5d1cf957df71a..6ff0f8ea0f30b 100644 --- a/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Directory/Test/Unit/Helper/DataTest.php @@ -46,7 +46,7 @@ protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); + $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(false); $context = $this->createMock(\Magento\Framework\App\Helper\Context::class); $context->expects($this->any()) ->method('getScopeConfig') diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index 44c542d04d6cb..6338851bd2ff4 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -98,14 +98,12 @@ public function __construct( * Get Items * * @param QueryInterface $query - * @param null $limit - * @param null $additionalFilters * * @return array|\Magento\Search\Model\QueryResult[] * @throws \Magento\Framework\Exception\NoSuchEntityException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function getItems(QueryInterface $query, $limit = null, $additionalFilters = null) + public function getItems(QueryInterface $query) { $result = []; if ($this->isSuggestionsAllowed()) { diff --git a/app/code/Magento/GoogleOptimizer/Helper/Data.php b/app/code/Magento/GoogleOptimizer/Helper/Data.php index d1e668cc9ec80..7138a7729fe0e 100644 --- a/app/code/Magento/GoogleOptimizer/Helper/Data.php +++ b/app/code/Magento/GoogleOptimizer/Helper/Data.php @@ -33,12 +33,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper */ protected $_analyticsHelper; - /** - * Data constructor. - * - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\GoogleAnalytics\Helper\Data $analyticsHelper - */ + /** + * Data constructor. + * + * @param \Magento\Framework\App\Helper\Context $context + * @param \Magento\GoogleAnalytics\Helper\Data $analyticsHelper + */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\GoogleAnalytics\Helper\Data $analyticsHelper diff --git a/app/code/Magento/Msrp/Model/Config.php b/app/code/Magento/Msrp/Model/Config.php index 71ac1b08fd575..3662a2cef8d20 100644 --- a/app/code/Magento/Msrp/Model/Config.php +++ b/app/code/Magento/Msrp/Model/Config.php @@ -42,13 +42,13 @@ class Config */ protected $storeId; - /** - * Config constructor. - * - * @param ScopeConfigInterface $scopeConfig - * @param StoreManagerInterface $storeManager - * @param Escaper $escaper - */ + /** + * Config constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param StoreManagerInterface $storeManager + * @param Escaper $escaper + */ public function __construct( ScopeConfigInterface $scopeConfig, StoreManagerInterface $storeManager, diff --git a/app/code/Magento/Reports/Model/ReportStatus.php b/app/code/Magento/Reports/Model/ReportStatus.php index 13f71c00c7330..d5d4611682090 100644 --- a/app/code/Magento/Reports/Model/ReportStatus.php +++ b/app/code/Magento/Reports/Model/ReportStatus.php @@ -20,11 +20,11 @@ class ReportStatus */ private $scopeConfig; - /** - * ReportStatus constructor. - * - * @param ScopeConfigInterface $scopeConfig - */ + /** + * ReportStatus constructor. + * + * @param ScopeConfigInterface $scopeConfig + */ public function __construct(ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; diff --git a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php index 0d85648c18a1f..82024b3b015e5 100644 --- a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php +++ b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Product.php @@ -171,9 +171,9 @@ protected function _construct() /** * Add attribute to filter * - * @param int $storeId + * @param int $storeId * @param string $attributeCode - * @param mixed $value + * @param mixed $value * @param string $type * * @return \Magento\Framework\DB\Select|bool @@ -220,7 +220,7 @@ protected function _addFilter($storeId, $attributeCode, $value, $type = '=') /** * Join attribute by code * - * @param int $storeId + * @param int $storeId * @param string $attributeCode * @param string $column Add attribute value to given column * @@ -361,7 +361,7 @@ public function getCollection($storeId) * Prepare product * * @param array $productRow - * @param int $storeId + * @param int $storeId * * @return \Magento\Framework\DataObject * @throws \Magento\Framework\Exception\LocalizedException @@ -492,7 +492,7 @@ private function getProductImageUrl($image) /** * Return Use Categories Path for Product URLs config value * - * @param $storeId + * @param null|string $storeId * * @return bool */ diff --git a/app/code/Magento/Store/Model/BaseUrlChecker.php b/app/code/Magento/Store/Model/BaseUrlChecker.php index ee108fe484be1..dbdcd9ff17bf9 100644 --- a/app/code/Magento/Store/Model/BaseUrlChecker.php +++ b/app/code/Magento/Store/Model/BaseUrlChecker.php @@ -17,11 +17,11 @@ class BaseUrlChecker */ private $scopeConfig; - /** - * BaseUrlChecker constructor. - * - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * BaseUrlChecker constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig ) { diff --git a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php index 52fd66924b957..3f6cb41ce3939 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php +++ b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php @@ -32,11 +32,11 @@ class Hsts extends \Magento\Framework\App\Response\HeaderProvider\AbstractHeader */ protected $scopeConfig; - /** - * Hsts constructor. - * - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * Hsts constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; diff --git a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php index cb6b0045e6673..265e9dbeb33da 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php +++ b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php @@ -32,11 +32,11 @@ class UpgradeInsecure extends \Magento\Framework\App\Response\HeaderProvider\Abs */ protected $scopeConfig; - /** - * UpgradeInsecure constructor. - * - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ + /** + * UpgradeInsecure constructor. + * + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + */ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) { $this->scopeConfig = $scopeConfig; diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index b9ab168f68dc2..b86e386c847ab 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -87,17 +87,17 @@ class StoreManager implements */ protected $isSingleStoreAllowed; - /** - * StoreManager constructor. - * - * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository - * @param \Magento\Store\Api\GroupRepositoryInterface $groupRepository - * @param \Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param StoreResolverInterface $storeResolver - * @param \Magento\Framework\Cache\FrontendInterface $cache - * @param bool $isSingleStoreAllowed - */ + /** + * StoreManager constructor. + * + * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository + * @param \Magento\Store\Api\GroupRepositoryInterface $groupRepository + * @param \Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param StoreResolverInterface $storeResolver + * @param \Magento\Framework\Cache\FrontendInterface $cache + * @param bool $isSingleStoreAllowed + */ public function __construct( \Magento\Store\Api\StoreRepositoryInterface $storeRepository, \Magento\Store\Api\GroupRepositoryInterface $groupRepository, @@ -116,54 +116,54 @@ public function __construct( $this->isSingleStoreAllowed = $isSingleStoreAllowed; } - /** - * Set current default store - * - * @param string $store - */ + /** + * Set current default store + * + * @param string $store + */ public function setCurrentStore($store) { $this->currentStoreId = $store; } - /** - * Allow or disallow single store mode - * - * @param bool $value - */ + /** + * Allow or disallow single store mode + * + * @param bool $value + */ public function setIsSingleStoreModeAllowed($value) { $this->isSingleStoreAllowed = $value; } - /** - * Check if store has only one store view - * - * @return bool - */ + /** + * Check if store has only one store view + * + * @return bool + */ public function hasSingleStore() { // TODO: MAGETWO-39902 add cache, move value to consts return $this->isSingleStoreAllowed && count($this->getStores(true)) < 3; } - /** - * Check if system is run in the single store mode - * - * @return bool - */ + /** + * Check if system is run in the single store mode + * + * @return bool + */ public function isSingleStoreMode() { return $this->isSingleStoreModeEnabled() && $this->hasSingleStore(); } - /** - * Retrieve application store object - * - * @param null|string|bool|int|\Magento\Store\Api\Data\StoreInterface $storeId - * @return \Magento\Store\Api\Data\StoreInterface - * @throws NoSuchEntityException If given store doesn't exist. - */ + /** + * Retrieve application store object + * + * @param null|string|bool|int|\Magento\Store\Api\Data\StoreInterface $storeId + * @return \Magento\Store\Api\Data\StoreInterface + * @throws NoSuchEntityException If given store doesn't exist. + */ public function getStore($storeId = null) { if (!isset($storeId) || '' === $storeId || $storeId === true) { @@ -185,13 +185,13 @@ public function getStore($storeId = null) return $store; } - /** - * Retrieve stores array - * - * @param bool $withDefault - * @param bool $codeKey - * @return \Magento\Store\Api\Data\StoreInterface[] - */ + /** + * Retrieve stores array + * + * @param bool $withDefault + * @param bool $codeKey + * @return \Magento\Store\Api\Data\StoreInterface[] + */ public function getStores($withDefault = false, $codeKey = false) { $stores = []; @@ -208,13 +208,13 @@ public function getStores($withDefault = false, $codeKey = false) return $stores; } - /** - * Retrieve application website object - * - * @param null|bool|int|string|\Magento\Store\Api\Data\WebsiteInterface $websiteId - * @return \Magento\Store\Api\Data\WebsiteInterface - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Retrieve application website object + * + * @param null|bool|int|string|\Magento\Store\Api\Data\WebsiteInterface $websiteId + * @return \Magento\Store\Api\Data\WebsiteInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getWebsite($websiteId = null) { if ($websiteId === null || $websiteId === '') { @@ -232,13 +232,13 @@ public function getWebsite($websiteId = null) return $website; } - /** - * Get loaded websites - * - * @param bool $withDefault - * @param bool $codeKey - * @return \Magento\Store\Api\Data\WebsiteInterface[] - */ + /** + * Get loaded websites + * + * @param bool $withDefault + * @param bool $codeKey + * @return \Magento\Store\Api\Data\WebsiteInterface[] + */ public function getWebsites($withDefault = false, $codeKey = false) { $websites = []; @@ -255,11 +255,11 @@ public function getWebsites($withDefault = false, $codeKey = false) return $websites; } - /** - * Reinitialize store list - * - * @return void - */ + /** + * Reinitialize store list + * + * @return void + */ public function reinitStores() { $this->currentStoreId = null; @@ -270,12 +270,12 @@ public function reinitStores() $this->groupRepository->clean(); } - /** - * Retrieve default store for default group and website - * - * @return \Magento\Store\Api\Data\StoreInterface|null - * @throws NoSuchEntityException - */ + /** + * Retrieve default store for default group and website + * + * @return \Magento\Store\Api\Data\StoreInterface|null + * @throws NoSuchEntityException + */ public function getDefaultStoreView() { $defaultWebsite = $this->websiteRepository->getDefault(); @@ -283,14 +283,14 @@ public function getDefaultStoreView() return $defaultStore ?: null; } - /** - * Retrieve application store group object - * - * @param null|\Magento\Store\Api\Data\GroupInterface|string $groupId - * - * @return \Magento\Store\Api\Data\GroupInterface - * @throws NoSuchEntityException - */ + /** + * Retrieve application store group object + * + * @param null|\Magento\Store\Api\Data\GroupInterface|string $groupId + * + * @return \Magento\Store\Api\Data\GroupInterface + * @throws NoSuchEntityException + */ public function getGroup($groupId = null) { if (null === $groupId) { @@ -303,12 +303,12 @@ public function getGroup($groupId = null) return $group; } - /** - * Prepare array of store groups - * - * @param bool $withDefault - * @return \Magento\Store\Api\Data\GroupInterface[] - */ + /** + * Prepare array of store groups + * + * @param bool $withDefault + * @return \Magento\Store\Api\Data\GroupInterface[] + */ public function getGroups($withDefault = false) { $groups = $this->groupRepository->getList(); @@ -338,6 +338,8 @@ protected function isSingleStoreModeEnabled() } /** + * Get Store Website Relation + * * @deprecated 100.2.0 * @return StoreWebsiteRelation */ @@ -346,13 +348,13 @@ private function getStoreWebsiteRelation() return ObjectManager::getInstance()->get(StoreWebsiteRelation::class); } - /** - * Get assigned to website store - * - * @param int $websiteId - * - * @return array - */ + /** + * Get assigned to website store + * + * @param int $websiteId + * + * @return array + */ public function getStoreByWebsiteId($websiteId) { return $this->getStoreWebsiteRelation()->getStoreByWebsiteId($websiteId); diff --git a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php index d5beab83cdd2b..2a8b3d4152703 100644 --- a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php +++ b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php @@ -11,7 +11,7 @@ /** * Wishlist RSS model - * + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Wishlist implements DataProviderInterface diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 90ee7541a5d6a..30d1a96ea4236 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -9,6 +9,9 @@ use Magento\Framework\App\State; +/** + * Class SidResolver + */ class SidResolver implements SidResolverInterface { /** @@ -85,12 +88,14 @@ public function __construct( $this->appState = $appState ?: \Magento\Framework\App\ObjectManager::getInstance()->get(State::class); } - /** - * @param SessionManagerInterface $session - * - * @return string|null - * @throws \Magento\Framework\Exception\LocalizedException - */ + /** + * Get Sid + * + * @param SessionManagerInterface $session + * + * @return string|null + * @throws \Magento\Framework\Exception\LocalizedException + */ public function getSid(SessionManagerInterface $session) { if ($this->appState->getAreaCode() !== \Magento\Framework\App\Area::AREA_FRONTEND) { From 493239c74c66e5e05226996a576b938665b0c224 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Fri, 21 Sep 2018 00:14:19 +0300 Subject: [PATCH 0165/1415] Update Tests --- app/code/Magento/Directory/Helper/Data.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php index 14619ce9bfc50..3a5558e6d6f3d 100644 --- a/app/code/Magento/Directory/Helper/Data.php +++ b/app/code/Magento/Directory/Helper/Data.php @@ -124,10 +124,10 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper * @param Context $context * @param Config $configCacheType * @param Collection $countryCollection - * @param CollectionFactory $regCollectionFactory, + * @param CollectionFactory $regCollectionFactory * @param JsonData $jsonHelper * @param StoreManagerInterface $storeManager - * @param CurrencyFactory currencyFactory + * @param CurrencyFactory $currencyFactory */ public function __construct( Context $context, @@ -317,8 +317,8 @@ public function isRegionRequired($countryId) public function getBaseCurrencyCode() { return $this->scopeConfig->getValue( - Currency::XML_PATH_CURRENCY_BASE, - 'default' + Currency::XML_PATH_CURRENCY_BASE, + 'default' ); } From eff16a418d41b7cda59c37065b8829ab5b6ce0f5 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Thu, 20 Sep 2018 16:51:44 -0500 Subject: [PATCH 0166/1415] MAGETWO-92898: Bundle Product enable/disable refresh issue on products page. - Unskip Bundle test that no longer encounters bug with enable/disable flow --- .../Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml index 0fb8a7b88250c..5b2b771434b73 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MC-217"/> <group value="Bundle"/> - <skip> - <issueId value="MAGETWO-92898"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From c8f3f1751656d930517188edf7c2117e951046d9 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 20 Sep 2018 16:53:25 -0500 Subject: [PATCH 0167/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form --- .../Controller/Adminhtml/Product/Attribute/Save.php | 12 ++++++------ .../Adminhtml/Product/Attribute/Validate.php | 10 +++++----- .../Adminhtml/Product/Attribute/SaveTest.php | 12 ++++++------ .../Adminhtml/Product/Attribute/ValidateTest.php | 12 ++++++------ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index 435fdb0b41301..985d812fc742b 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -82,7 +82,7 @@ class Save extends Attribute implements HttpPostActionInterface /** * @var FormData|null */ - private $dataSerializer; + private $formDataSerializer; /** * @param Context $context @@ -97,7 +97,7 @@ class Save extends Attribute implements HttpPostActionInterface * @param Product $productHelper * @param LayoutFactory $layoutFactory * @param Presentation|null $presentation - * @param FormData|null $dataSerializer + * @param FormData|null $formDataSerializer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -113,7 +113,7 @@ public function __construct( Product $productHelper, LayoutFactory $layoutFactory, Presentation $presentation = null, - FormData $dataSerializer = null + FormData $formDataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->buildFactory = $buildFactory; @@ -124,7 +124,7 @@ public function __construct( $this->groupCollectionFactory = $groupCollectionFactory; $this->layoutFactory = $layoutFactory; $this->presentation = $presentation ?: ObjectManager::getInstance()->get(Presentation::class); - $this->dataSerializer = $dataSerializer + $this->formDataSerializer = $formDataSerializer ?: ObjectManager::getInstance()->get(FormData::class); } @@ -140,7 +140,7 @@ public function __construct( public function execute() { try { - $optionData = $this->dataSerializer + $optionData = $this->formDataSerializer ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be saved due to an error. Verify your information and try again. " @@ -150,7 +150,7 @@ public function execute() } $data = $this->getRequest()->getPostValue(); - $data = array_merge_recursive( + $data = array_replace_recursive( $data, $optionData ); diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 4e33fc737f0c4..8a9d0c9b612cb 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -41,7 +41,7 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo /** * @var FormData|null */ - private $dataSerializer; + private $formDataSerializer; /** * Constructor @@ -53,7 +53,7 @@ class Validate extends AttributeAction implements HttpGetActionInterface, HttpPo * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory * @param array $multipleAttributeList - * @param FormData|null $dataSerializer + * @param FormData|null $formDataSerializer */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -63,13 +63,13 @@ public function __construct( \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, \Magento\Framework\View\LayoutFactory $layoutFactory, array $multipleAttributeList = [], - FormData $dataSerializer = null + FormData $formDataSerializer = null ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; $this->multipleAttributeList = $multipleAttributeList; - $this->dataSerializer = $dataSerializer ?: ObjectManager::getInstance() + $this->formDataSerializer = $formDataSerializer ?: ObjectManager::getInstance() ->get(FormData::class); } @@ -85,7 +85,7 @@ public function execute() $response = new DataObject(); $response->setError(false); try { - $optionsData = $this->dataSerializer + $optionsData = $this->formDataSerializer ->unserialize($this->getRequest()->getParam('serialized_options', '[]')); } catch (\InvalidArgumentException $e) { $message = __("The attribute couldn't be validated due to an error. Verify your information and try again. " diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php index e73f3527517f8..ced65b2d2e15d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/SaveTest.php @@ -87,7 +87,7 @@ class SaveTest extends AttributeTest /** * @var FormData|\PHPUnit_Framework_MockObject_MockObject */ - private $dataSerializerMock; + private $formDataSerializerMock; /** * @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject @@ -135,7 +135,7 @@ protected function setUp() $this->inputTypeValidatorMock = $this->getMockBuilder(InputTypeValidator::class) ->disableOriginalConstructor() ->getMock(); - $this->dataSerializerMock = $this->getMockBuilder(FormData::class) + $this->formDataSerializerMock = $this->getMockBuilder(FormData::class) ->disableOriginalConstructor() ->getMock(); $this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class) @@ -170,7 +170,7 @@ protected function getModel() 'validatorFactory' => $this->validatorFactoryMock, 'groupCollectionFactory' => $this->groupCollectionFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, - 'dataSerializer' => $this->dataSerializerMock, + 'formDataSerializer' => $this->formDataSerializerMock, ]); } @@ -182,7 +182,7 @@ public function testExecuteWithEmptyData() ['isAjax', null, null], ['serialized_options', '[]', ''], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with('') @@ -213,7 +213,7 @@ public function testExecute() ['isAjax', null, null], ['serialized_options', '[]', ''], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with('') @@ -273,7 +273,7 @@ public function testExecuteWithOptionsDataError() ['isAjax', null, true], ['serialized_options', '[]', $serializedOptions], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index 666e6c1942c7a..c6210f93e1290 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -65,7 +65,7 @@ class ValidateTest extends AttributeTest /** * @var FormData|\PHPUnit_Framework_MockObject_MockObject */ - private $dataSerializerMock; + private $formDataSerializerMock; protected function setUp() { @@ -92,7 +92,7 @@ protected function setUp() ->getMock(); $this->layoutMock = $this->getMockBuilder(LayoutInterface::class) ->getMockForAbstractClass(); - $this->dataSerializerMock = $this->getMockBuilder(FormData::class) + $this->formDataSerializerMock = $this->getMockBuilder(FormData::class) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +116,7 @@ protected function getModel() 'resultJsonFactory' => $this->resultJsonFactoryMock, 'layoutFactory' => $this->layoutFactoryMock, 'multipleAttributeList' => ['select' => 'option'], - 'dataSerializer' => $this->dataSerializerMock, + 'formDataSerializer' => $this->formDataSerializerMock, ] ); } @@ -184,7 +184,7 @@ public function testUniqueValidation(array $options, $isError) ['serialized_options', '[]', $serializedOptions], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) @@ -319,7 +319,7 @@ public function testEmptyOption(array $options, $result) ['serialized_options', '[]', $serializedOptions], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) @@ -431,7 +431,7 @@ public function testExecuteWithOptionsDataError() ['serialized_options', '[]', $serializedOptions], ]); - $this->dataSerializerMock + $this->formDataSerializerMock ->expects($this->once()) ->method('unserialize') ->with($serializedOptions) From 441a98190a29baa239b419fdb2f492ef3a82431d Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 09:08:55 +0200 Subject: [PATCH 0168/1415] Added correct path to the phpunit file --- .travis.yml | 3 ++- dev/tests/api-functional/phpunit_graphql.xml.dist | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e909bb1980752..a80460095ce01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,5 +62,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ] && [ $TEST_SUITE != "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi diff --git a/dev/tests/api-functional/phpunit_graphql.xml.dist b/dev/tests/api-functional/phpunit_graphql.xml.dist index 4a57c338ca3a2..955a3a8953fa8 100644 --- a/dev/tests/api-functional/phpunit_graphql.xml.dist +++ b/dev/tests/api-functional/phpunit_graphql.xml.dist @@ -27,7 +27,7 @@ <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento.url"/> + <const name="TESTS_BASE_URL" value="http://magento2.travis"/> <!-- Webserver API user --> <const name="TESTS_WEBSERVICE_USER" value="admin"/> <!-- Webserver API key --> From 757f79c1b8a8c78e7012d443a841237eb596479f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 21 Sep 2018 10:20:19 +0300 Subject: [PATCH 0169/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned #8009 - Fix tests. --- .../Model/Indexer/Stock/CacheCleaner.php | 6 +++++ .../Model/Indexer/Stock/CacheCleanerTest.php | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php index 9712d129bcd65..b3fa07479a712 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php @@ -75,6 +75,8 @@ public function __construct( } /** + * Clean cache by product ids. + * * @param array $productIds * @param callable $reindex * @return void @@ -92,6 +94,8 @@ public function clean(array $productIds, callable $reindex) } /** + * Get current stock statuses for product ids. + * * @param array $productIds * @return array */ @@ -158,6 +162,8 @@ private function getProductIdsForCacheClean(array $productStatusesBefore, array } /** + * Get database connection. + * * @return AdapterInterface */ private function getConnection() diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php index 5e4249685f8d3..755e54a919b63 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php @@ -12,6 +12,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Select; use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Indexer\CacheContext; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Catalog\Model\Product; @@ -43,6 +44,11 @@ class CacheCleanerTest extends \PHPUnit\Framework\TestCase */ private $cacheContextMock; + /** + * @var MetadataPool |\PHPUnit_Framework_MockObject_MockObject + */ + private $metadataPoolMock; + /** * @var StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -61,6 +67,8 @@ protected function setUp() ->setMethods(['getStockThresholdQty'])->getMockForAbstractClass(); $this->cacheContextMock = $this->getMockBuilder(CacheContext::class)->disableOriginalConstructor()->getMock(); $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class)->getMock(); + $this->metadataPoolMock = $this->getMockBuilder(MetadataPool::class) + ->setMethods(['getMetadata', 'getLinkField'])->disableOriginalConstructor()->getMock(); $this->selectMock = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock(); $this->resourceMock->expects($this->any()) @@ -73,7 +81,8 @@ protected function setUp() 'resource' => $this->resourceMock, 'stockConfiguration' => $this->stockConfigurationMock, 'cacheContext' => $this->cacheContextMock, - 'eventManager' => $this->eventManagerMock + 'eventManager' => $this->eventManagerMock, + 'metadataPool' => $this->metadataPoolMock ] ); } @@ -90,6 +99,7 @@ public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $sto $productId = 123; $this->selectMock->expects($this->any())->method('from')->willReturnSelf(); $this->selectMock->expects($this->any())->method('where')->willReturnSelf(); + $this->selectMock->expects($this->any())->method('joinLeft')->willReturnSelf(); $this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock); $this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls( [ @@ -105,7 +115,10 @@ public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $sto ->with(Product::CACHE_TAG, [$productId]); $this->eventManagerMock->expects($this->once())->method('dispatch') ->with('clean_cache_by_tags', ['object' => $this->cacheContextMock]); - + $this->metadataPoolMock->expects($this->exactly(2))->method('getMetadata') + ->willReturnSelf(); + $this->metadataPoolMock->expects($this->exactly(2))->method('getLinkField') + ->willReturn('row_id'); $callback = function () { }; $this->unit->clean([], $callback); @@ -136,6 +149,7 @@ public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAft $productId = 123; $this->selectMock->expects($this->any())->method('from')->willReturnSelf(); $this->selectMock->expects($this->any())->method('where')->willReturnSelf(); + $this->selectMock->expects($this->any())->method('joinLeft')->willReturnSelf(); $this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock); $this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls( [ @@ -149,6 +163,10 @@ public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAft ->willReturn($stockThresholdQty); $this->cacheContextMock->expects($this->never())->method('registerEntities'); $this->eventManagerMock->expects($this->never())->method('dispatch'); + $this->metadataPoolMock->expects($this->exactly(2))->method('getMetadata') + ->willReturnSelf(); + $this->metadataPoolMock->expects($this->exactly(2))->method('getLinkField') + ->willReturn('row_id'); $callback = function () { }; From df755861a85c2087ba71e7adfa0884fdf46c2544 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 10:55:42 +0200 Subject: [PATCH 0170/1415] Test api-functional execution with phpunit.xml.dist --- .travis.yml | 4 +- dev/tests/api-functional/phpunit.xml.dist | 56 +++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/.travis.yml b/.travis.yml index a80460095ce01..c6077564b923d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ] && [ $TEST_SUITE != "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + #- if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist new file mode 100644 index 0000000000000..955a3a8953fa8 --- /dev/null +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * PHPUnit configuration for GraphQL web API functional tests. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" + colors="true" + columns="max" + beStrictAboutTestsThatDoNotTestAnything="false" + bootstrap="./framework/bootstrap.php" +> + <!-- Test suites definition --> + <testsuites> + <testsuite name="Magento GraphQL web API functional tests"> + <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> + </testsuite> + </testsuites> + + <!-- PHP INI settings and constants definition --> + <php> + <includePath>./testsuite</includePath> + <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> + <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> + <!-- Webserver URL --> + <const name="TESTS_BASE_URL" value="http://magento2.travis"/> + <!-- Webserver API user --> + <const name="TESTS_WEBSERVICE_USER" value="admin"/> + <!-- Webserver API key --> + <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> + <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> + <const name="TESTS_XDEBUG_ENABLED" value="false"/> + <!-- Define XDEBUG_SESSION cookie value--> + <const name="TESTS_XDEBUG_SESSION" value="phpstorm" /> + + <ini name="date.timezone" value="America/Los_Angeles"/> + + <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> + <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> + <!-- Whether to cleanup the application before running tests or not --> + <const name="TESTS_CLEANUP" value="enabled"/> + <!--Defines if Magento should be installed before tests execution--> + <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> + <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> + <const name="TESTS_MAGENTO_MODE" value="default"/> + </php> + + <!-- Test listeners --> + <listeners> + <listener class="Magento\TestFramework\Event\PhpUnit"/> + </listeners> +</phpunit> From 636142edf17227f7d72ccf0d13555971276aa6f7 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 11:16:01 +0200 Subject: [PATCH 0171/1415] Test api-functional execution with production mode enabled --- dev/tests/api-functional/phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist index 955a3a8953fa8..a55531aba87e2 100644 --- a/dev/tests/api-functional/phpunit.xml.dist +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -46,7 +46,7 @@ <!--Defines if Magento should be installed before tests execution--> <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="default"/> + <const name="TESTS_MAGENTO_MODE" value="production"/> </php> <!-- Test listeners --> From 60f33baab9a476c4320f17b80e1e1df74543ac9f Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 14:54:58 +0300 Subject: [PATCH 0172/1415] MAGETWO-92195: Wrong order request flow --- .../Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php index bd377e40f1849..e862710379a04 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php @@ -13,7 +13,7 @@ use Magento\Sales\Api\OrderManagementInterface; /** - * Class MassUnhold + * Class MassUnhold, change status for select orders * * @package Magento\Sales\Controller\Adminhtml\Order */ From 1148f85e42022e77817e33a901bef5153a7cf108 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Fri, 21 Sep 2018 15:11:30 +0300 Subject: [PATCH 0173/1415] MAGETWO-59265: Import doesn't allow to set default value per store view (dropdown fields) - Changed logic of setting default value of attributes by store view during import --- .../Model/Import/Product/Type/AbstractType.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php index 8b04b7ec3532f..3b6caef66ce6c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php @@ -543,10 +543,9 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe } else { $resultAttrs[$attrCode] = $rowData[$attrCode]; } - } elseif (array_key_exists($attrCode, $rowData)) { + } elseif (array_key_exists($attrCode, $rowData) && empty($rowData['_store'])) { $resultAttrs[$attrCode] = $rowData[$attrCode]; - } elseif ($withDefaultValue && null !== $attrParams['default_value'] - && 'select' == $attrParams['type'] && null === $rowData['_store']) { + } elseif ($withDefaultValue && null !== $attrParams['default_value'] && empty($rowData['_store'])) { $resultAttrs[$attrCode] = $attrParams['default_value']; } } From cdc0fd39bac4218fe16eecb34ee7ffa407ac94ca Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 15:58:18 +0300 Subject: [PATCH 0174/1415] MAGETWO-70943: Incorrect reset password flow --- .../Api/AccountManagementInterface.php | 11 ++- .../Controller/Account/CreatePassword.php | 21 +++-- .../Controller/Account/ResetPasswordPost.php | 39 +++++---- .../Customer/Model/AccountManagement.php | 83 +++++++++++++++++-- .../email/password_reset_confirmation.html | 3 +- .../form/resetforgottenpassword.phtml | 2 +- .../Customer/Controller/AccountTest.php | 12 +-- .../Customer/Model/AccountManagementTest.php | 58 ++++++++++++- .../Magento/Framework/Math/Random.php | 68 +++++---------- 9 files changed, 202 insertions(+), 95 deletions(-) diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php index d2f9fb7ebc420..10fc2349968ea 100644 --- a/app/code/Magento/Customer/Api/AccountManagementInterface.php +++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php @@ -7,6 +7,8 @@ namespace Magento\Customer\Api; +use Magento\Framework\Exception\InputException; + /** * Interface for managing customers accounts. * @api @@ -144,19 +146,24 @@ public function initiatePasswordReset($email, $template, $websiteId = null); /** * Reset customer password. * - * @param string $email + * @param string $email If empty value given then the customer + * will be matched by the RP token. * @param string $resetToken * @param string $newPassword + * * @return bool true on success * @throws \Magento\Framework\Exception\LocalizedException + * @throws InputException */ public function resetPassword($email, $resetToken, $newPassword); /** * Check if password reset token is valid. * - * @param int $customerId + * @param int $customerId If null is given then a customer + * will be matched by the RP token. * @param string $resetPasswordLinkToken + * * @return bool True if the token is valid * @throws \Magento\Framework\Exception\State\InputMismatchException If token is mismatched * @throws \Magento\Framework\Exception\State\ExpiredException If token is expired diff --git a/app/code/Magento/Customer/Controller/Account/CreatePassword.php b/app/code/Magento/Customer/Controller/Account/CreatePassword.php index fb2e3dd42908b..124ac912a7ccf 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePassword.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePassword.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,10 +7,16 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Model\Session; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\View\Result\PageFactory; use Magento\Framework\App\Action\Context; -class CreatePassword extends \Magento\Customer\Controller\AbstractAccount +/** + * Class CreatePassword + * + * @package Magento\Customer\Controller\Account + */ +class CreatePassword extends \Magento\Customer\Controller\AbstractAccount implements HttpGetActionInterface { /** * @var \Magento\Customer\Api\AccountManagementInterface @@ -54,27 +59,27 @@ public function __construct( public function execute() { $resetPasswordToken = (string)$this->getRequest()->getParam('token'); - $customerId = (int)$this->getRequest()->getParam('id'); - $isDirectLink = $resetPasswordToken != '' && $customerId != 0; + $isDirectLink = $resetPasswordToken != ''; if (!$isDirectLink) { $resetPasswordToken = (string)$this->session->getRpToken(); - $customerId = (int)$this->session->getRpCustomerId(); } try { - $this->accountManagement->validateResetPasswordLinkToken($customerId, $resetPasswordToken); + $this->accountManagement->validateResetPasswordLinkToken(null, $resetPasswordToken); if ($isDirectLink) { $this->session->setRpToken($resetPasswordToken); - $this->session->setRpCustomerId($customerId); $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/createpassword'); + return $resultRedirect; } else { /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); - $resultPage->getLayout()->getBlock('resetPassword')->setCustomerId($customerId) + $resultPage->getLayout() + ->getBlock('resetPassword') ->setResetPasswordLinkToken($resetPasswordToken); + return $resultPage; } } catch (\Exception $exception) { diff --git a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php index 3de44e35d2447..27a00f86dd95d 100644 --- a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php +++ b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -10,11 +9,16 @@ use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Model\Session; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Exception\InputException; use Magento\Customer\Model\Customer\CredentialsValidator; -use Magento\Framework\App\ObjectManager; -class ResetPasswordPost extends \Magento\Customer\Controller\AbstractAccount +/** + * Class ResetPasswordPost + * + * @package Magento\Customer\Controller\Account + */ +class ResetPasswordPost extends \Magento\Customer\Controller\AbstractAccount implements HttpPostActionInterface { /** * @var \Magento\Customer\Api\AccountManagementInterface @@ -31,17 +35,14 @@ class ResetPasswordPost extends \Magento\Customer\Controller\AbstractAccount */ protected $session; - /** - * @var CredentialsValidator - */ - private $credentialsValidator; - /** * @param Context $context * @param Session $customerSession * @param AccountManagementInterface $accountManagement * @param CustomerRepositoryInterface $customerRepository * @param CredentialsValidator|null $credentialsValidator + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( Context $context, @@ -53,8 +54,6 @@ public function __construct( $this->session = $customerSession; $this->accountManagement = $accountManagement; $this->customerRepository = $customerRepository; - $this->credentialsValidator = $credentialsValidator ?: ObjectManager::getInstance() - ->get(CredentialsValidator::class); parent::__construct($context); } @@ -70,29 +69,32 @@ public function execute() /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $resetPasswordToken = (string)$this->getRequest()->getQuery('token'); - $customerId = (int)$this->getRequest()->getQuery('id'); $password = (string)$this->getRequest()->getPost('password'); $passwordConfirmation = (string)$this->getRequest()->getPost('password_confirmation'); if ($password !== $passwordConfirmation) { $this->messageManager->addError(__("New Password and Confirm New Password values didn't match.")); - $resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]); + $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); + return $resultRedirect; } if (iconv_strlen($password) <= 0) { $this->messageManager->addError(__('Please enter a new password.')); - $resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]); + $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); + return $resultRedirect; } try { - $customerEmail = $this->customerRepository->getById($customerId)->getEmail(); - $this->credentialsValidator->checkPasswordDifferentFromEmail($customerEmail, $password); - $this->accountManagement->resetPassword($customerEmail, $resetPasswordToken, $password); + $this->accountManagement->resetPassword( + null, + $resetPasswordToken, + $password + ); $this->session->unsRpToken(); - $this->session->unsRpCustomerId(); $this->messageManager->addSuccess(__('You updated your password.')); $resultRedirect->setPath('*/*/login'); + return $resultRedirect; } catch (InputException $e) { $this->messageManager->addError($e->getMessage()); @@ -102,7 +104,8 @@ public function execute() } catch (\Exception $exception) { $this->messageManager->addError(__('Something went wrong while saving the new password.')); } - $resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]); + $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); + return $resultRedirect; } } diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index fe17adcb09c0d..52264c78b7717 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -20,6 +20,7 @@ use Magento\Customer\Model\Metadata\Validator; use Magento\Eav\Model\Validator\Attribute\Backend; use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\App\Area; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; @@ -41,6 +42,7 @@ use Magento\Framework\Intl\DateTimeFactory; use Magento\Framework\Mail\Template\TransportBuilder; use Magento\Framework\Math\Random; +use Magento\Framework\Phrase; use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime; @@ -326,6 +328,11 @@ class AccountManagement implements AccountManagementInterface */ private $accountConfirmation; + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + /** * @param CustomerFactory $customerFactory * @param ManagerInterface $eventManager @@ -356,6 +363,7 @@ class AccountManagement implements AccountManagementInterface * @param SessionManagerInterface|null $sessionManager * @param SaveHandlerInterface|null $saveHandler * @param CollectionFactory|null $visitorCollectionFactory + * @param SearchCriteriaBuilder|null $searchCriteriaBuilder * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -387,7 +395,8 @@ public function __construct( AccountConfirmation $accountConfirmation = null, SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, - CollectionFactory $visitorCollectionFactory = null + CollectionFactory $visitorCollectionFactory = null, + SearchCriteriaBuilder $searchCriteriaBuilder = null ) { $this->customerFactory = $customerFactory; $this->eventManager = $eventManager; @@ -423,6 +432,8 @@ public function __construct( ?: ObjectManager::getInstance()->get(SaveHandlerInterface::class); $this->visitorCollectionFactory = $visitorCollectionFactory ?: ObjectManager::getInstance()->get(CollectionFactory::class); + $this->searchCriteriaBuilder = $searchCriteriaBuilder + ?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class); } /** @@ -591,6 +602,43 @@ public function initiatePasswordReset($email, $template, $websiteId = null) return false; } + /** + * Match a customer by their RP token. + * + * @param string $rpToken + * @throws ExpiredException + * @throws NoSuchEntityException + * + * @return CustomerInterface + * @throws LocalizedException + */ + private function matchCustomerByRpToken(string $rpToken): CustomerInterface + { + $this->searchCriteriaBuilder->addFilter( + 'rp_token', + $rpToken + ); + $this->searchCriteriaBuilder->setPageSize(1); + $found = $this->customerRepository->getList( + $this->searchCriteriaBuilder->create() + ); + if ($found->getTotalCount() > 1) { + //Failed to generated unique RP token + throw new ExpiredException( + new Phrase('Reset password token expired.') + ); + } + if ($found->getTotalCount() === 0) { + //Customer with such token not found. + throw NoSuchEntityException::singleField( + 'rp_token', + $rpToken + ); + } + //Unique customer found. + return $found->getItems()[0]; + } + /** * Handle not supported template * @@ -613,18 +661,26 @@ private function handleUnknownTemplate($template) /** * @inheritdoc */ - public function resetPassword($email, $resetToken, $newPassword) + public function resetPassword(?string $email, string $resetToken, string $newPassword): bool { - $customer = $this->customerRepository->get($email); + if (!$email) { + $customer = $this->matchCustomerByRpToken($resetToken); + $email = $customer->getEmail(); + } else { + $customer = $this->customerRepository->get($email); + } //Validate Token and new password strength $this->validateResetPasswordToken($customer->getId(), $resetToken); + $this->credentialsValidator->checkPasswordDifferentFromEmail( + $email, + $newPassword + ); $this->checkPasswordStrength($newPassword); //Update secure data $customerSecure = $this->customerRegistry->retrieveSecureData($customer->getId()); $customerSecure->setRpToken(null); $customerSecure->setRpTokenCreatedAt(null); $customerSecure->setPasswordHash($this->createPasswordHash($newPassword)); - $this->getAuthentication()->unlock($customer->getId()); $this->sessionManager->destroy(); $this->destroyCustomerSessions($customer->getId()); $this->customerRepository->save($customer); @@ -955,6 +1011,8 @@ protected function createPasswordHash($password) } /** + * Returns eval validator + * * @return Backend */ private function getEavValidator() @@ -1033,10 +1091,11 @@ public function isCustomerInStore($customerWebsiteId, $storeId) * @throws \Magento\Framework\Exception\State\ExpiredException If token is expired * @throws \Magento\Framework\Exception\InputException If token or customer id is invalid * @throws \Magento\Framework\Exception\NoSuchEntityException If customer doesn't exist + * @throws LocalizedException */ - private function validateResetPasswordToken($customerId, $resetPasswordLinkToken) + private function validateResetPasswordToken(?int $customerId, ?string $resetPasswordLinkToken) : bool { - if (empty($customerId) || $customerId < 0) { + if ($customerId !== null && $customerId <= 0) { throw new InputException( __( 'Invalid value of "%value" provided for the %fieldName field.', @@ -1044,21 +1103,24 @@ private function validateResetPasswordToken($customerId, $resetPasswordLinkToken ) ); } + + if ($customerId === null) { + //Looking for the customer. + $customerId = $this->matchCustomerByRpToken($resetPasswordLinkToken) + ->getId(); + } if (!is_string($resetPasswordLinkToken) || empty($resetPasswordLinkToken)) { $params = ['fieldName' => 'resetPasswordLinkToken']; throw new InputException(__('"%fieldName" is required. Enter and try again.', $params)); } - $customerSecureData = $this->customerRegistry->retrieveSecureData($customerId); $rpToken = $customerSecureData->getRpToken(); $rpTokenCreatedAt = $customerSecureData->getRpTokenCreatedAt(); - if (!Security::compareStrings($rpToken, $resetPasswordLinkToken)) { throw new InputMismatchException(__('The password token is mismatched. Reset and try again.')); } elseif ($this->isResetPasswordLinkTokenExpired($rpToken, $rpTokenCreatedAt)) { throw new ExpiredException(__('The password token is expired. Reset and try again.')); } - return true; } @@ -1141,6 +1203,7 @@ protected function sendPasswordResetNotificationEmail($customer) * @param int|string|null $defaultStoreId * @return int * @deprecated 100.1.0 + * @throws LocalizedException */ protected function getWebsiteStoreId($customer, $defaultStoreId = null) { @@ -1153,6 +1216,8 @@ protected function getWebsiteStoreId($customer, $defaultStoreId = null) } /** + * Return array with template types + * * @return array * @deprecated 100.1.0 */ diff --git a/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html b/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html index 6c17762a88227..f33350ea48241 100644 --- a/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html +++ b/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html @@ -21,7 +21,8 @@ <table class="inner-wrapper" border="0" cellspacing="0" cellpadding="0" align="center"> <tr> <td align="center"> - <a href="{{var this.getUrl($store,'customer/account/createPassword/',[_query:[id:$customer.id,token:$customer.rp_token],_nosid:1])}}" target="_blank">{{trans "Set a New Password"}}</a> + <a href="{{var this.getUrl($store,'customer/account/createPassword/',[_query:[token:$customer.rp_token],_nosid:1])}}" target="_blank">{{trans "Set a New Password"}}</a> + </td> </tr> </table> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml index 15e570da04beb..e79cea80ac838 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml @@ -8,7 +8,7 @@ /** @var \Magento\Customer\Block\Account\Resetpassword $block */ ?> -<form action="<?= $block->escapeUrl($block->getUrl('*/*/resetpasswordpost', ['_query' => ['id' => $block->getCustomerId(), 'token' => $block->getResetPasswordLinkToken()]])) ?>" +<form action="<?= $block->escapeUrl($block->getUrl('*/*/resetpasswordpost', ['_query' => ['token' => $block->getResetPasswordLinkToken()]])) ?>" method="post" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> id="form-validate" diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 921fa81fa6f23..12855e457effd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -130,7 +130,6 @@ public function testCreatepasswordActionWithDirectLink() $customer->save(); $this->getRequest()->setParam('token', $token); - $this->getRequest()->setParam('id', $customer->getId()); $this->dispatch('customer/account/createPassword'); @@ -138,12 +137,13 @@ public function testCreatepasswordActionWithDirectLink() $this->assertEquals(302, $response->getHttpResponseCode()); $text = $response->getBody(); $this->assertFalse((bool)preg_match('/' . $token . '/m', $text)); - $this->assertRedirect($this->stringContains('customer/account/createpassword')); + $this->assertRedirect( + $this->stringContains('customer/account/createpassword') + ); - /** @var \Magento\Customer\Model\Session $customer */ - $session = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Session::class); + /** @var Session $customer */ + $session = Bootstrap::getObjectManager()->get(Session::class); $this->assertEquals($token, $session->getRpToken()); - $this->assertEquals($customer->getId(), $session->getRpCustomerId()); $this->assertNotContains($token, $response->getHeader('Location')->getFieldValue()); } @@ -419,6 +419,7 @@ public function testResetPasswordPostNoTokenAction() $this->getRequest() ->setParam('id', 1) ->setParam('token', '8ed8677e6c79e68b94e61658bd756ea5') + ->setMethod('POST') ->setPostValue([ 'password' => 'new-password', 'password_confirmation' => 'new-password', @@ -441,6 +442,7 @@ public function testResetPasswordPostAction() $this->getRequest() ->setQueryValue('id', 1) ->setQueryValue('token', '8ed8677e6c79e68b94e61658bd756ea5') + ->setMethod('POST') ->setPostValue([ 'password' => 'new-Password1', 'password_confirmation' => 'new-Password1', diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php index f5b6fdc93d32f..4810b6c28caef 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php @@ -357,6 +357,29 @@ public function testValidateResetPasswordLinkTokenNull() } } + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testValidateResetPasswordLinkTokenWithoutId() + { + $token = 'randomStr123'; + $this->setResetPasswordData($token, 'Y-m-d H:i:s'); + $this->assertTrue( + $this->accountManagement->validateResetPasswordLinkToken(null, $token) + ); + } + /** + * @magentoDataFixture Magento/Customer/_files/two_customers.php + * @expectedException \Magento\Framework\Exception\State\ExpiredException + */ + public function testValidateResetPasswordLinkTokenAmbiguous() + { + $token = 'randomStr123'; + $this->setResetPasswordData($token, 'Y-m-d H:i:s', 1); + $this->setResetPasswordData($token, 'Y-m-d H:i:s', 2); + $this->accountManagement->validateResetPasswordLinkToken(null, $token); + } + /** * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php @@ -512,6 +535,31 @@ public function testResetPasswordTokenInvalidUserEmail() } } + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testResetPasswordWithoutEmail() + { + $resetToken = 'lsdj579slkj5987slkj595lkj'; + $password = 'new_Password123'; + $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s'); + $this->assertTrue( + $this->accountManagement->resetPassword(null, $resetToken, $password) + ); + } + /** + * @magentoDataFixture Magento/Customer/_files/two_customers.php + * @expectedException \Magento\Framework\Exception\State\ExpiredException + */ + public function testResetPasswordAmbiguousToken() + { + $resetToken = 'lsdj579slkj5987slkj595lkj'; + $password = 'new_Password123'; + $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s', 1); + $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s', 2); + $this->accountManagement->resetPassword(null, $resetToken, $password); + } + /** * @magentoAppArea frontend * @magentoAppIsolation enabled @@ -960,10 +1008,14 @@ public function testGetDefaultAddressesForNonExistentAddress() * * @param $resetToken * @param $date + * @param int $customerIdFromFixture Which customer to use. + * @throws \Exception */ - protected function setResetPasswordData($resetToken, $date) - { - $customerIdFromFixture = 1; + protected function setResetPasswordData( + $resetToken, + $date, + int $customerIdFromFixture = 1 + ) { /** @var \Magento\Customer\Model\Customer $customerModel */ $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class); $customerModel->load($customerIdFromFixture); diff --git a/lib/internal/Magento/Framework/Math/Random.php b/lib/internal/Magento/Framework/Math/Random.php index 7cb70c9a822cc..c2059e1935a80 100644 --- a/lib/internal/Magento/Framework/Math/Random.php +++ b/lib/internal/Magento/Framework/Math/Random.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Math; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Phrase; + /** * Random data generator * @@ -24,41 +27,24 @@ class Random /**#@-*/ /** - * Get random string + * Get random string. * * @param int $length * @param null|string $chars + * * @return string - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function getRandomString($length, $chars = null) { $str = ''; if (null === $chars) { - $chars = self::CHARS_LOWERS . self::CHARS_UPPERS . self::CHARS_DIGITS; + $chars = self::CHARS_LOWERS.self::CHARS_UPPERS.self::CHARS_DIGITS; } - if (function_exists('openssl_random_pseudo_bytes')) { - // use openssl lib if it is installed - for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { - $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); - $hex = bin2hex($bytes); // hex() doubles the length of the string - $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc - $str .= $chars[$rand]; // random character in $chars - } - } elseif ($fp = @fopen('/dev/urandom', 'rb')) { - // attempt to use /dev/urandom if it exists but openssl isn't available - for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) { - $bytes = @fread($fp, PHP_INT_SIZE); - $hex = bin2hex($bytes); // hex() doubles the length of the string - $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc - $str .= $chars[$rand]; // random character in $chars - } - fclose($fp); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("Please make sure you have 'openssl' extension installed") - ); + $charsMaxKey = mb_strlen($chars) - 1; + for ($i = 0; $i < $length; $i++) { + $str .= $chars[self::getRandomNumber(0, $charsMaxKey)]; } return $str; @@ -67,47 +53,33 @@ public function getRandomString($length, $chars = null) /** * Return a random number in the specified range * - * @param $min [optional] - * @param $max [optional] - * @return int A random integer value between min (or 0) and max - * @throws \Magento\Framework\Exception\LocalizedException + * @param int $min + * @param int $max + * @return int A random integer value between min (or 0) and max + * @throws LocalizedException */ public static function getRandomNumber($min = 0, $max = null) { if (null === $max) { $max = mt_getrandmax(); } - $range = $max - $min + 1; - $offset = 0; - if (function_exists('openssl_random_pseudo_bytes')) { - // use openssl lib if it is installed - $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE); - $hex = bin2hex($bytes); // hex() doubles the length of the string - $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range - } elseif ($fp = @fopen('/dev/urandom', 'rb')) { - // attempt to use /dev/urandom if it exists but openssl isn't available - $bytes = @fread($fp, PHP_INT_SIZE); - $hex = bin2hex($bytes); // hex() doubles the length of the string - $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range - fclose($fp); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("Please make sure you have 'openssl' extension installed") - ); + if ($max < $min) { + throw new LocalizedException(new Phrase('Invalid range given.')); } - return $min + $offset; // random integer from $min to $max + return random_int($min, $max); } /** - * Generate a hash from unique ID + * Generate a hash from unique ID. * * @param string $prefix * @return string + * @throws LocalizedException */ public function getUniqueHash($prefix = '') { - return $prefix . md5(uniqid(microtime() . self::getRandomNumber(), true)); + return $prefix . $this->getRandomString(32); } } From 822de9dfbd4683ae7591779ac19a495b92118167 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 15:59:25 +0300 Subject: [PATCH 0175/1415] MAGETWO-70943: Incorrect reset password flow --- .../Controller/Account/CreatePasswordTest.php | 233 -- .../Account/ResetPasswordPostTest.php | 379 --- .../Test/Unit/Model/AccountManagementTest.php | 2057 ----------------- 3 files changed, 2669 deletions(-) delete mode 100644 app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePasswordTest.php delete mode 100644 app/code/Magento/Customer/Test/Unit/Controller/Account/ResetPasswordPostTest.php delete mode 100644 app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePasswordTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePasswordTest.php deleted file mode 100644 index 77f41024ba02f..0000000000000 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePasswordTest.php +++ /dev/null @@ -1,233 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Customer\Test\Unit\Controller\Account; - -use Magento\Framework\Controller\Result\Redirect; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class CreatePasswordTest extends \PHPUnit\Framework\TestCase -{ - /** @var \Magento\Customer\Controller\Account\CreatePassword */ - protected $model; - - /** @var ObjectManagerHelper */ - protected $objectManagerHelper; - - /** @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ - protected $sessionMock; - - /** @var \Magento\Framework\View\Result\PageFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $pageFactoryMock; - - /** @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $accountManagementMock; - - /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $requestMock; - - /** @var \Magento\Framework\Controller\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $redirectFactoryMock; - - /** @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $messageManagerMock; - - protected function setUp() - { - $this->sessionMock = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['setRpToken', 'setRpCustomerId', 'getRpToken', 'getRpCustomerId']) - ->getMock(); - $this->pageFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Result\PageFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->accountManagementMock = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) - ->getMockForAbstractClass(); - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->getMockForAbstractClass(); - $this->redirectFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\RedirectFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->messageManagerMock = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class) - ->getMockForAbstractClass(); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $this->objectManagerHelper->getObject( - \Magento\Customer\Controller\Account\CreatePassword::class, - [ - 'customerSession' => $this->sessionMock, - 'resultPageFactory' => $this->pageFactoryMock, - 'accountManagement' => $this->accountManagementMock, - 'request' => $this->requestMock, - 'resultRedirectFactory' => $this->redirectFactoryMock, - 'messageManager' => $this->messageManagerMock, - ] - ); - } - - public function testExecuteWithLink() - { - $token = 'token'; - $customerId = '11'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['token', null, $token], - ['id', null, $customerId], - ] - ); - - $this->accountManagementMock->expects($this->once()) - ->method('validateResetPasswordLinkToken') - ->with($customerId, $token) - ->willReturn(true); - - $this->sessionMock->expects($this->once()) - ->method('setRpToken') - ->with($token); - $this->sessionMock->expects($this->once()) - ->method('setRpCustomerId') - ->with($customerId); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/createpassword', []) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - public function testExecuteWithSession() - { - $token = 'token'; - $customerId = '11'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['token', null, null], - ['id', null, $customerId], - ] - ); - - $this->sessionMock->expects($this->once()) - ->method('getRpToken') - ->willReturn($token); - $this->sessionMock->expects($this->once()) - ->method('getRpCustomerId') - ->willReturn($customerId); - - $this->accountManagementMock->expects($this->once()) - ->method('validateResetPasswordLinkToken') - ->with($customerId, $token) - ->willReturn(true); - - /** @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject $pageMock */ - $pageMock = $this->getMockBuilder(\Magento\Framework\View\Result\Page::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->pageFactoryMock->expects($this->once()) - ->method('create') - ->with(false, []) - ->willReturn($pageMock); - - /** @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject $layoutMock */ - $layoutMock = $this->getMockBuilder(\Magento\Framework\View\Layout::class) - ->disableOriginalConstructor() - ->getMock(); - - $pageMock->expects($this->once()) - ->method('getLayout') - ->willReturn($layoutMock); - - /** @var \Magento\Customer\Block\Account\Resetpassword|\PHPUnit_Framework_MockObject_MockObject $layoutMock */ - $blockMock = $this->getMockBuilder(\Magento\Customer\Block\Account\Resetpassword::class) - ->disableOriginalConstructor() - ->setMethods(['setCustomerId', 'setResetPasswordLinkToken']) - ->getMock(); - - $layoutMock->expects($this->once()) - ->method('getBlock') - ->with('resetPassword') - ->willReturn($blockMock); - - $blockMock->expects($this->once()) - ->method('setCustomerId') - ->with($customerId) - ->willReturnSelf(); - $blockMock->expects($this->once()) - ->method('setResetPasswordLinkToken') - ->with($token) - ->willReturnSelf(); - - $this->assertEquals($pageMock, $this->model->execute()); - } - - public function testExecuteWithException() - { - $token = 'token'; - $customerId = '11'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['token', null, $token], - ['id', null, null], - ] - ); - - $this->sessionMock->expects($this->once()) - ->method('getRpToken') - ->willReturn($token); - $this->sessionMock->expects($this->once()) - ->method('getRpCustomerId') - ->willReturn($customerId); - - $this->accountManagementMock->expects($this->once()) - ->method('validateResetPasswordLinkToken') - ->with($customerId, $token) - ->willThrowException(new \Exception('Exception.')); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('Your password reset link has expired.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/forgotpassword', []) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } -} diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ResetPasswordPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ResetPasswordPostTest.php deleted file mode 100644 index b79ad008e5e44..0000000000000 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ResetPasswordPostTest.php +++ /dev/null @@ -1,379 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Customer\Test\Unit\Controller\Account; - -use Magento\Framework\Controller\Result\Redirect; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class ResetPasswordPostTest extends \PHPUnit\Framework\TestCase -{ - /** @var \Magento\Customer\Controller\Account\ResetPasswordPost */ - protected $model; - - /** @var ObjectManagerHelper */ - protected $objectManagerHelper; - - /** @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ - protected $sessionMock; - - /** @var \Magento\Framework\View\Result\PageFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $pageFactoryMock; - - /** @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $accountManagementMock; - - /** @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerRepositoryMock; - - /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $requestMock; - - /** @var \Magento\Framework\Controller\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $redirectFactoryMock; - - /** @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $messageManagerMock; - - protected function setUp() - { - $this->sessionMock = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['unsRpToken', 'unsRpCustomerId']) - ->getMock(); - $this->pageFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Result\PageFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->accountManagementMock = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) - ->getMockForAbstractClass(); - $this->customerRepositoryMock = $this->getMockBuilder(\Magento\Customer\Api\CustomerRepositoryInterface::class) - ->getMockForAbstractClass(); - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->setMethods(['getQuery', 'getPost']) - ->getMockForAbstractClass(); - $this->redirectFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\RedirectFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->messageManagerMock = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class) - ->getMockForAbstractClass(); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $this->objectManagerHelper->getObject( - \Magento\Customer\Controller\Account\ResetPasswordPost::class, - [ - 'customerSession' => $this->sessionMock, - 'resultPageFactory' => $this->pageFactoryMock, - 'accountManagement' => $this->accountManagementMock, - 'customerRepository' => $this->customerRepositoryMock, - 'request' => $this->requestMock, - 'resultRedirectFactory' => $this->redirectFactoryMock, - 'messageManager' => $this->messageManagerMock, - ] - ); - } - - public function testExecute() - { - $token = 'token'; - $customerId = '11'; - $password = 'password'; - $passwordConfirmation = 'password'; - $email = 'email@email.com'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getQuery') - ->willReturnMap( - [ - ['token', $token], - ['id', $customerId], - ] - ); - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['password', $password], - ['password_confirmation', $passwordConfirmation], - ] - ); - - /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customerMock */ - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - - $this->customerRepositoryMock->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customerMock); - - $customerMock->expects($this->once()) - ->method('getEmail') - ->willReturn($email); - - $this->accountManagementMock->expects($this->once()) - ->method('resetPassword') - ->with($email, $token, $password) - ->willReturn(true); - - $this->sessionMock->expects($this->once()) - ->method('unsRpToken'); - $this->sessionMock->expects($this->once()) - ->method('unsRpCustomerId'); - - $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') - ->with(__('You updated your password.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/login', []) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - public function testExecuteWithException() - { - $token = 'token'; - $customerId = '11'; - $password = 'password'; - $passwordConfirmation = 'password'; - $email = 'email@email.com'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getQuery') - ->willReturnMap( - [ - ['token', $token], - ['id', $customerId], - ] - ); - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['password', $password], - ['password_confirmation', $passwordConfirmation], - ] - ); - - /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customerMock */ - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - - $this->customerRepositoryMock->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customerMock); - - $customerMock->expects($this->once()) - ->method('getEmail') - ->willReturn($email); - - $this->accountManagementMock->expects($this->once()) - ->method('resetPassword') - ->with($email, $token, $password) - ->willThrowException(new \Exception('Exception.')); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('Something went wrong while saving the new password.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/createPassword', ['id' => $customerId, 'token' => $token]) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * Test for InputException - */ - public function testExecuteWithInputException() - { - $token = 'token'; - $customerId = '11'; - $password = 'password'; - $passwordConfirmation = 'password'; - $email = 'email@email.com'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getQuery') - ->willReturnMap( - [ - ['token', $token], - ['id', $customerId], - ] - ); - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['password', $password], - ['password_confirmation', $passwordConfirmation], - ] - ); - - /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customerMock */ - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - - $this->customerRepositoryMock->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customerMock); - - $customerMock->expects($this->once()) - ->method('getEmail') - ->willReturn($email); - - $this->accountManagementMock->expects($this->once()) - ->method('resetPassword') - ->with($email, $token, $password) - ->willThrowException(new \Magento\Framework\Exception\InputException(__('InputException.'))); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('InputException.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/createPassword', ['id' => $customerId, 'token' => $token]) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - public function testExecuteWithWrongConfirmation() - { - $token = 'token'; - $customerId = '11'; - $password = 'password'; - $passwordConfirmation = 'wrong_password'; - - $this->requestMock->expects($this->exactly(2)) - ->method('getQuery') - ->willReturnMap( - [ - ['token', $token], - ['id', $customerId], - ] - ); - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['password', $password], - ['password_confirmation', $passwordConfirmation], - ] - ); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('New Password and Confirm New Password values didn\'t match.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/createPassword', ['id' => $customerId, 'token' => $token]) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - public function testExecuteWithEmptyPassword() - { - $token = 'token'; - $customerId = '11'; - $password = ''; - $passwordConfirmation = ''; - - $this->requestMock->expects($this->exactly(2)) - ->method('getQuery') - ->willReturnMap( - [ - ['token', $token], - ['id', $customerId], - ] - ); - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['password', $password], - ['password_confirmation', $passwordConfirmation], - ] - ); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('Please enter a new password.')) - ->willReturnSelf(); - - /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->redirectFactoryMock->expects($this->once()) - ->method('create') - ->with([]) - ->willReturn($redirectMock); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('*/*/createPassword', ['id' => $customerId, 'token' => $token]) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } -} diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php deleted file mode 100644 index aad20f757e91e..0000000000000 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ /dev/null @@ -1,2057 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Customer\Test\Unit\Model; - -use Magento\Customer\Model\AccountManagement; -use Magento\Customer\Model\AccountConfirmation; -use Magento\Customer\Model\AuthenticationInterface; -use Magento\Customer\Model\EmailNotificationInterface; -use Magento\Framework\App\Area; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Intl\DateTimeFactory; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Magento\Store\Model\ScopeInterface; - -/** - * @SuppressWarnings(PHPMD.TooManyFields) - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class AccountManagementTest extends \PHPUnit\Framework\TestCase -{ - /** @var AccountManagement */ - protected $accountManagement; - - /** @var ObjectManagerHelper */ - protected $objectManagerHelper; - - /** @var \Magento\Customer\Model\CustomerFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerFactory; - - /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $manager; - - /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $storeManager; - - /** @var \Magento\Framework\Math\Random|\PHPUnit_Framework_MockObject_MockObject */ - protected $random; - - /** @var \Magento\Customer\Model\Metadata\Validator|\PHPUnit_Framework_MockObject_MockObject */ - protected $validator; - - /** @var \Magento\Customer\Api\Data\ValidationResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $validationResultsInterfaceFactory; - - /** @var \Magento\Customer\Api\AddressRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $addressRepository; - - /** @var \Magento\Customer\Api\CustomerMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerMetadata; - - /** @var \Magento\Customer\Model\CustomerRegistry|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerRegistry; - - /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $logger; - - /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $encryptor; - - /** @var \Magento\Customer\Model\Config\Share|\PHPUnit_Framework_MockObject_MockObject */ - protected $share; - - /** @var \Magento\Framework\Stdlib\StringUtils|\PHPUnit_Framework_MockObject_MockObject */ - protected $string; - - /** @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerRepository; - - /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $scopeConfig; - - /** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */ - protected $transportBuilder; - - /** @var \Magento\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject */ - protected $dataObjectProcessor; - - /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */ - protected $registry; - - /** @var \Magento\Customer\Helper\View|\PHPUnit_Framework_MockObject_MockObject */ - protected $customerViewHelper; - - /** @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject */ - protected $dateTime; - - /** @var \Magento\Customer\Model\Customer|\PHPUnit_Framework_MockObject_MockObject */ - protected $customer; - - /** @var \Magento\Framework\DataObjectFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $objectFactory; - - /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter|\PHPUnit_Framework_MockObject_MockObject */ - protected $extensibleDataObjectConverter; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Store\Model\Store - */ - protected $store; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\Data\CustomerSecure - */ - protected $customerSecure; - - /** - * @var AuthenticationInterface |\PHPUnit_Framework_MockObject_MockObject - */ - protected $authenticationMock; - - /** - * @var EmailNotificationInterface |\PHPUnit_Framework_MockObject_MockObject - */ - protected $emailNotificationMock; - - /** - * @var DateTimeFactory|\PHPUnit_Framework_MockObject_MockObject - */ - private $dateTimeFactory; - - /** - * @var AccountConfirmation|\PHPUnit_Framework_MockObject_MockObject - */ - private $accountConfirmation; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Session\SessionManagerInterface - */ - private $sessionManager; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory - */ - private $visitorCollectionFactory; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Session\SaveHandlerInterface - */ - private $saveHandler; - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - protected function setUp() - { - $this->customerFactory = $this->createPartialMock(\Magento\Customer\Model\CustomerFactory::class, ['create']); - $this->manager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $this->store = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); - $this->random = $this->createMock(\Magento\Framework\Math\Random::class); - $this->validator = $this->createMock(\Magento\Customer\Model\Metadata\Validator::class); - $this->validationResultsInterfaceFactory = $this->createMock( - \Magento\Customer\Api\Data\ValidationResultsInterfaceFactory::class - ); - $this->addressRepository = $this->createMock(\Magento\Customer\Api\AddressRepositoryInterface::class); - $this->customerMetadata = $this->createMock(\Magento\Customer\Api\CustomerMetadataInterface::class); - $this->customerRegistry = $this->createMock(\Magento\Customer\Model\CustomerRegistry::class); - $this->logger = $this->createMock(\Psr\Log\LoggerInterface::class); - $this->encryptor = $this->createMock(\Magento\Framework\Encryption\EncryptorInterface::class); - $this->share = $this->createMock(\Magento\Customer\Model\Config\Share::class); - $this->string = $this->createMock(\Magento\Framework\Stdlib\StringUtils::class); - $this->customerRepository = $this->createMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $this->scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->transportBuilder = $this->createMock(\Magento\Framework\Mail\Template\TransportBuilder::class); - $this->dataObjectProcessor = $this->createMock(\Magento\Framework\Reflection\DataObjectProcessor::class); - $this->registry = $this->createMock(\Magento\Framework\Registry::class); - $this->customerViewHelper = $this->createMock(\Magento\Customer\Helper\View::class); - $this->dateTime = $this->createMock(\Magento\Framework\Stdlib\DateTime::class); - $this->customer = $this->createMock(\Magento\Customer\Model\Customer::class); - $this->objectFactory = $this->createMock(\Magento\Framework\DataObjectFactory::class); - $this->extensibleDataObjectConverter = $this->createMock( - \Magento\Framework\Api\ExtensibleDataObjectConverter::class - ); - $this->authenticationMock = $this->getMockBuilder(AuthenticationInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->emailNotificationMock = $this->getMockBuilder(EmailNotificationInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->setMethods(['setRpToken', 'addData', 'setRpTokenCreatedAt', 'setData']) - ->disableOriginalConstructor() - ->getMock(); - - $this->dateTimeFactory = $this->createMock(DateTimeFactory::class); - $this->accountConfirmation = $this->createMock(AccountConfirmation::class); - - $this->visitorCollectionFactory = $this->getMockBuilder( - \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class - ) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->sessionManager = $this->getMockBuilder(\Magento\Framework\Session\SessionManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->saveHandler = $this->getMockBuilder(\Magento\Framework\Session\SaveHandlerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->accountManagement = $this->objectManagerHelper->getObject( - \Magento\Customer\Model\AccountManagement::class, - [ - 'customerFactory' => $this->customerFactory, - 'eventManager' => $this->manager, - 'storeManager' => $this->storeManager, - 'mathRandom' => $this->random, - 'validator' => $this->validator, - 'validationResultsDataFactory' => $this->validationResultsInterfaceFactory, - 'addressRepository' => $this->addressRepository, - 'customerMetadataService' => $this->customerMetadata, - 'customerRegistry' => $this->customerRegistry, - 'logger' => $this->logger, - 'encryptor' => $this->encryptor, - 'configShare' => $this->share, - 'stringHelper' => $this->string, - 'customerRepository' => $this->customerRepository, - 'scopeConfig' => $this->scopeConfig, - 'transportBuilder' => $this->transportBuilder, - 'dataProcessor' => $this->dataObjectProcessor, - 'registry' => $this->registry, - 'customerViewHelper' => $this->customerViewHelper, - 'dateTime' => $this->dateTime, - 'customerModel' => $this->customer, - 'objectFactory' => $this->objectFactory, - 'extensibleDataObjectConverter' => $this->extensibleDataObjectConverter, - 'dateTimeFactory' => $this->dateTimeFactory, - 'accountConfirmation' => $this->accountConfirmation, - 'sessionManager' => $this->sessionManager, - 'saveHandler' => $this->saveHandler, - 'visitorCollectionFactory' => $this->visitorCollectionFactory, - ] - ); - $this->objectManagerHelper->setBackwardCompatibleProperty( - $this->accountManagement, - 'authentication', - $this->authenticationMock - ); - $this->objectManagerHelper->setBackwardCompatibleProperty( - $this->accountManagement, - 'emailNotification', - $this->emailNotificationMock - ); - } - - /** - * @expectedException \Magento\Framework\Exception\InputException - */ - public function testCreateAccountWithPasswordHashWithExistingCustomer() - { - $websiteId = 1; - $storeId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->once()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->once()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->once()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager - ->expects($this->once()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->accountManagement->createAccountWithPasswordHash($customer, $hash); - } - - /** - * @expectedException \Magento\Framework\Exception\State\InputMismatchException - */ - public function testCreateAccountWithPasswordHashWithCustomerWithoutStoreId() - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->atLeastOnce()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->once()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer - ->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer - ->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share - ->expects($this->atLeastOnce()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $exception = new \Magento\Framework\Exception\AlreadyExistsException( - new \Magento\Framework\Phrase('Exception message') - ); - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customer, $hash) - ->willThrowException($exception); - - $this->accountManagement->createAccountWithPasswordHash($customer, $hash); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountWithPasswordHashWithLocalizedException() - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->once()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer - ->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer - ->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $exception = new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase('Exception message') - ); - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customer, $hash) - ->willThrowException($exception); - - $this->accountManagement->createAccountWithPasswordHash($customer, $hash); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountWithPasswordHashWithAddressException() - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $address->expects($this->once()) - ->method('setCustomerId') - ->with($customerId); - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->once()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer - ->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer - ->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customer, $hash) - ->willReturn($customer); - $exception = new \Magento\Framework\Exception\InputException( - new \Magento\Framework\Phrase('Exception message') - ); - $this->addressRepository - ->expects($this->atLeastOnce()) - ->method('save') - ->with($address) - ->willThrowException($exception); - $this->customerRepository - ->expects($this->once()) - ->method('delete') - ->with($customer); - - $this->accountManagement->createAccountWithPasswordHash($customer, $hash); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountWithPasswordHashWithNewCustomerAndLocalizedException() - { - $storeId = 1; - $storeName = 'store_name'; - $websiteId = 1; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - - $customerMock->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn(null); - $customerMock->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customerMock->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customerMock->expects($this->once()) - ->method('setCreatedIn') - ->with($storeName) - ->willReturnSelf(); - $customerMock->expects($this->once()) - ->method('getAddresses') - ->willReturn([]); - $customerMock->expects($this->once()) - ->method('setAddresses') - ->with(null) - ->willReturnSelf(); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - - $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - - $storeMock->expects($this->once()) - ->method('getName') - ->willReturn($storeName); - - $this->storeManager->expects($this->exactly(1)) - ->method('getStore') - ->with($storeId) - ->willReturn($storeMock); - $exception = new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase('Exception message') - ); - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customerMock, $hash) - ->willThrowException($exception); - - $this->accountManagement->createAccountWithPasswordHash($customerMock, $hash); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testCreateAccountWithoutPassword() - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $newLinkToken = '2jh43j5h2345jh23lh452h345hfuzasd96ofu'; - - $datetime = $this->prepareDateTimeFactory(); - - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $address->expects($this->once()) - ->method('setCustomerId') - ->with($customerId); - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->atLeastOnce()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->atLeastOnce()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->customerRepository->expects($this->atLeastOnce()) - ->method('save') - ->willReturn($customer); - $this->addressRepository->expects($this->atLeastOnce()) - ->method('save') - ->with($address); - $this->customerRepository->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customer); - $this->random->expects($this->once()) - ->method('getUniqueHash') - ->willReturn($newLinkToken); - $customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->setMethods(['setRpToken', 'setRpTokenCreatedAt', 'getPasswordHash']) - ->disableOriginalConstructor() - ->getMock(); - $customerSecure->expects($this->any()) - ->method('setRpToken') - ->with($newLinkToken); - $customerSecure->expects($this->any()) - ->method('setRpTokenCreatedAt') - ->with($datetime) - ->willReturnSelf(); - $customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn(null); - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($customerSecure); - $this->emailNotificationMock->expects($this->once()) - ->method('newAccount') - ->willReturnSelf(); - - $this->accountManagement->createAccount($customer); - } - - /** - * Data provider for testCreateAccountWithPasswordInputException test - * - * @return array - */ - public function dataProviderCheckPasswordStrength() - { - return [ - [ - 'testNumber' => 1, - 'password' => 'qwer', - 'minPasswordLength' => 5, - 'minCharacterSetsNum' => 1, - ], - [ - 'testNumber' => 2, - 'password' => 'wrfewqedf1', - 'minPasswordLength' => 5, - 'minCharacterSetsNum' => 3, - ], - ]; - } - - /** - * @param int $testNumber - * @param string $password - * @param int $minPasswordLength - * @param int $minCharacterSetsNum - * @dataProvider dataProviderCheckPasswordStrength - */ - public function testCreateAccountWithPasswordInputException( - $testNumber, - $password, - $minPasswordLength, - $minCharacterSetsNum - ) { - $this->scopeConfig->expects($this->any()) - ->method('getValue') - ->will( - $this->returnValueMap( - [ - [ - AccountManagement::XML_PATH_MINIMUM_PASSWORD_LENGTH, - 'default', - null, - $minPasswordLength, - ], - [ - AccountManagement::XML_PATH_REQUIRED_CHARACTER_CLASSES_NUMBER, - 'default', - null, - $minCharacterSetsNum, - ], - ] - ) - ); - - $this->string->expects($this->any()) - ->method('strlen') - ->with($password) - ->willReturn(iconv_strlen($password, 'UTF-8')); - - if ($testNumber == 1) { - $this->expectException(\Magento\Framework\Exception\InputException::class); - $this->expectExceptionMessage('The password needs at least ' . $minPasswordLength . ' characters. ' - . 'Create a new password and try again.'); - } - - if ($testNumber == 2) { - $this->expectException(\Magento\Framework\Exception\InputException::class); - $this->expectExceptionMessage('Minimum of different classes of characters in password is ' . - $minCharacterSetsNum . '. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.'); - } - - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $this->accountManagement->createAccount($customer, $password); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountInputExceptionExtraLongPassword() - { - $password = '257*chars*************************************************************************************' - . '****************************************************************************************************' - . '***************************************************************'; - - $this->string->expects($this->any()) - ->method('strlen') - ->with($password) - ->willReturn(iconv_strlen($password, 'UTF-8')); - - $this->expectException(\Magento\Framework\Exception\InputException::class); - $this->expectExceptionMessage('Please enter a password with at most 256 characters.'); - - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $this->accountManagement->createAccount($customer, $password); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testCreateAccountWithPassword() - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - $newLinkToken = '2jh43j5h2345jh23lh452h345hfuzasd96ofu'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $password = 'wrfewqedf1'; - $minPasswordLength = 5; - $minCharacterSetsNum = 2; - - $datetime = $this->prepareDateTimeFactory(); - - $this->scopeConfig->expects($this->any()) - ->method('getValue') - ->willReturnMap( - [ - [ - AccountManagement::XML_PATH_MINIMUM_PASSWORD_LENGTH, - 'default', - null, - $minPasswordLength, - ], - [ - AccountManagement::XML_PATH_REQUIRED_CHARACTER_CLASSES_NUMBER, - 'default', - null, - $minCharacterSetsNum, - ], - [ - AccountManagement::XML_PATH_REGISTER_EMAIL_TEMPLATE, - ScopeInterface::SCOPE_STORE, - $defaultStoreId, - $templateIdentifier, - ], - [ - AccountManagement::XML_PATH_REGISTER_EMAIL_IDENTITY, - ScopeInterface::SCOPE_STORE, - 1, - $sender, - ], - ] - ); - $this->string->expects($this->any()) - ->method('strlen') - ->with($password) - ->willReturn(iconv_strlen($password, 'UTF-8')); - $this->encryptor->expects($this->once()) - ->method('getHash') - ->with($password, true) - ->willReturn($hash); - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $address->expects($this->once()) - ->method('setCustomerId') - ->with($customerId); - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->atLeastOnce()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->atLeastOnce()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->customerRepository->expects($this->atLeastOnce()) - ->method('save') - ->willReturn($customer); - $this->addressRepository->expects($this->atLeastOnce()) - ->method('save') - ->with($address); - $this->customerRepository->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customer); - $this->random->expects($this->once()) - ->method('getUniqueHash') - ->willReturn($newLinkToken); - $customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->setMethods(['setRpToken', 'setRpTokenCreatedAt', 'getPasswordHash']) - ->disableOriginalConstructor() - ->getMock(); - $customerSecure->expects($this->any()) - ->method('setRpToken') - ->with($newLinkToken); - $customerSecure->expects($this->any()) - ->method('setRpTokenCreatedAt') - ->with($datetime) - ->willReturnSelf(); - $customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn($hash); - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($customerSecure); - $this->emailNotificationMock->expects($this->once()) - ->method('newAccount') - ->willReturnSelf(); - - $this->accountManagement->createAccount($customer, $password); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testSendPasswordReminderEmail() - { - $customerId = 1; - $customerStoreId = 2; - $customerEmail = 'email@email.com'; - $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMock(); - $customer->expects($this->any()) - ->method('getStoreId') - ->willReturn($customerStoreId); - $customer->expects($this->any()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->any()) - ->method('getEmail') - ->willReturn($customerEmail); - - $this->store->expects($this->any()) - ->method('getId') - ->willReturn($customerStoreId); - - $this->storeManager->expects($this->at(0)) - ->method('getStore') - ->willReturn($this->store); - - $this->storeManager->expects($this->at(1)) - ->method('getStore') - ->with($customerStoreId) - ->willReturn($this->store); - - $this->customerRegistry->expects($this->once()) - ->method('retrieveSecureData') - ->with($customerId) - ->willReturn($this->customerSecure); - - $this->dataObjectProcessor->expects($this->once()) - ->method('buildOutputDataArray') - ->with($customer, \Magento\Customer\Api\Data\CustomerInterface::class) - ->willReturn($customerData); - - $this->customerViewHelper->expects($this->any()) - ->method('getCustomerName') - ->with($customer) - ->willReturn($customerName); - - $this->customerSecure->expects($this->once()) - ->method('addData') - ->with($customerData) - ->willReturnSelf(); - $this->customerSecure->expects($this->once()) - ->method('setData') - ->with('name', $customerName) - ->willReturnSelf(); - - $this->scopeConfig->expects($this->at(0)) - ->method('getValue') - ->with(AccountManagement::XML_PATH_REMIND_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($templateIdentifier); - $this->scopeConfig->expects($this->at(1)) - ->method('getValue') - ->with(AccountManagement::XML_PATH_FORGOT_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($sender); - - $transport = $this->getMockBuilder(\Magento\Framework\Mail\TransportInterface::class) - ->getMock(); - - $this->transportBuilder->expects($this->once()) - ->method('setTemplateIdentifier') - ->with($templateIdentifier) - ->willReturnSelf(); - $this->transportBuilder->expects($this->once()) - ->method('setTemplateOptions') - ->with(['area' => Area::AREA_FRONTEND, 'store' => $customerStoreId]) - ->willReturnSelf(); - $this->transportBuilder->expects($this->once()) - ->method('setTemplateVars') - ->with(['customer' => $this->customerSecure, 'store' => $this->store]) - ->willReturnSelf(); - $this->transportBuilder->expects($this->once()) - ->method('setFrom') - ->with($sender) - ->willReturnSelf(); - $this->transportBuilder->expects($this->once()) - ->method('addTo') - ->with($customerEmail, $customerName) - ->willReturnSelf(); - $this->transportBuilder->expects($this->once()) - ->method('getTransport') - ->willReturn($transport); - - $transport->expects($this->once()) - ->method('sendMessage'); - - $this->assertEquals($this->accountManagement, $this->accountManagement->sendPasswordReminderEmail($customer)); - } - - /** - * @param string $email - * @param string $templateIdentifier - * @param string $sender - * @param int $storeId - * @param int $customerId - * @param string $hash - */ - protected function prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash) - { - $websiteId = 1; - - $datetime = $this->prepareDateTimeFactory(); - - $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - - $this->store->expects($this->once()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $this->store->expects($this->any()) - ->method('getId') - ->willReturn($storeId); - - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMock(); - $customer->expects($this->any()) - ->method('getEmail') - ->willReturn($email); - $customer->expects($this->any()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->any()) - ->method('getStoreId') - ->willReturn($storeId); - - $this->customerRepository->expects($this->once()) - ->method('get') - ->with($email, $websiteId) - ->willReturn($customer); - $this->customerRepository->expects($this->once()) - ->method('save') - ->with($customer) - ->willReturnSelf(); - - $this->random->expects($this->once()) - ->method('getUniqueHash') - ->willReturn($hash); - - $this->customerViewHelper->expects($this->any()) - ->method('getCustomerName') - ->with($customer) - ->willReturn($customerName); - - $this->customerSecure->expects($this->any()) - ->method('setRpToken') - ->with($hash) - ->willReturnSelf(); - $this->customerSecure->expects($this->any()) - ->method('setRpTokenCreatedAt') - ->with($datetime) - ->willReturnSelf(); - $this->customerSecure->expects($this->any()) - ->method('addData') - ->with($customerData) - ->willReturnSelf(); - $this->customerSecure->expects($this->any()) - ->method('setData') - ->with('name', $customerName) - ->willReturnSelf(); - - $this->customerRegistry->expects($this->any()) - ->method('retrieveSecureData') - ->with($customerId) - ->willReturn($this->customerSecure); - - $this->dataObjectProcessor->expects($this->any()) - ->method('buildOutputDataArray') - ->with($customer, \Magento\Customer\Api\Data\CustomerInterface::class) - ->willReturn($customerData); - - $this->prepareEmailSend($email, $templateIdentifier, $sender, $storeId, $customerName); - } - - /** - * @param string $email - * @param int $templateIdentifier - * @param string $sender - * @param int $storeId - * @param string $customerName - */ - protected function prepareEmailSend($email, $templateIdentifier, $sender, $storeId, $customerName) - { - $transport = $this->getMockBuilder(\Magento\Framework\Mail\TransportInterface::class) - ->getMock(); - - $this->transportBuilder->expects($this->any()) - ->method('setTemplateIdentifier') - ->with($templateIdentifier) - ->willReturnSelf(); - $this->transportBuilder->expects($this->any()) - ->method('setTemplateOptions') - ->with(['area' => Area::AREA_FRONTEND, 'store' => $storeId]) - ->willReturnSelf(); - $this->transportBuilder->expects($this->any()) - ->method('setTemplateVars') - ->with(['customer' => $this->customerSecure, 'store' => $this->store]) - ->willReturnSelf(); - $this->transportBuilder->expects($this->any()) - ->method('setFrom') - ->with($sender) - ->willReturnSelf(); - $this->transportBuilder->expects($this->any()) - ->method('addTo') - ->with($email, $customerName) - ->willReturnSelf(); - $this->transportBuilder->expects($this->any()) - ->method('getTransport') - ->willReturn($transport); - - $transport->expects($this->any()) - ->method('sendMessage'); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testInitiatePasswordResetEmailReminder() - { - $customerId = 1; - - $email = 'test@example.com'; - $template = AccountManagement::EMAIL_REMINDER; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - - $storeId = 1; - - mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); - $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); - - $this->emailNotificationMock->expects($this->once()) - ->method('passwordReminder') - ->willReturnSelf(); - - $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash); - - $this->assertTrue($this->accountManagement->initiatePasswordReset($email, $template)); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testInitiatePasswordResetEmailReset() - { - $storeId = 1; - $customerId = 1; - - $email = 'test@example.com'; - $template = AccountManagement::EMAIL_RESET; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - - mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); - $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); - - $this->emailNotificationMock->expects($this->once()) - ->method('passwordResetConfirmation') - ->willReturnSelf(); - - $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash); - - $this->assertTrue($this->accountManagement->initiatePasswordReset($email, $template)); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testInitiatePasswordResetNoTemplate() - { - $storeId = 1; - $customerId = 1; - - $email = 'test@example.com'; - $template = null; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - - mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); - $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); - - $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash); - - $this->expectException(\Magento\Framework\Exception\InputException::class); - $this->expectExceptionMessage( - 'Invalid value of "" provided for the template field. Possible values: email_reminder or email_reset.' - ); - $this->accountManagement->initiatePasswordReset($email, $template); - } - - /** - * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage Invalid value of "" provided for the customerId field - */ - public function testValidateResetPasswordTokenBadCustomerId() - { - $this->accountManagement->validateResetPasswordLinkToken(null, ''); - } - - /** - * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage "resetPasswordLinkToken" is required. Enter and try again. - */ - public function testValidateResetPasswordTokenBadResetPasswordLinkToken() - { - $this->accountManagement->validateResetPasswordLinkToken(22, null); - } - - /** - * @expectedException \Magento\Framework\Exception\State\InputMismatchException - * @expectedExceptionMessage The password token is mismatched. Reset and try again. - */ - public function testValidateResetPasswordTokenTokenMismatch() - { - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($this->customerSecure); - - $this->accountManagement->validateResetPasswordLinkToken(22, 'newStringToken'); - } - - /** - * @expectedException \Magento\Framework\Exception\State\ExpiredException - * @expectedExceptionMessage The password token is expired. Reset and try again. - */ - public function testValidateResetPasswordTokenTokenExpired() - { - $this->reInitModel(); - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($this->customerSecure); - - $this->accountManagement->validateResetPasswordLinkToken(22, 'newStringToken'); - } - - /** - * return bool - */ - public function testValidateResetPasswordToken() - { - $this->reInitModel(); - - $this->customer - ->expects($this->once()) - ->method('getResetPasswordLinkExpirationPeriod') - ->willReturn(100000); - - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($this->customerSecure); - - $this->assertTrue($this->accountManagement->validateResetPasswordLinkToken(22, 'newStringToken')); - } - - /** - * reInit $this->accountManagement object - */ - private function reInitModel() - { - $this->customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->disableOriginalConstructor() - ->setMethods( - [ - 'getRpToken', - 'getRpTokenCreatedAt', - 'getPasswordHash', - 'setPasswordHash', - 'setRpToken', - 'setRpTokenCreatedAt', - ] - ) - ->getMock(); - $this->customerSecure->expects($this->any()) - ->method('getRpToken') - ->willReturn('newStringToken'); - $pastDateTime = '2016-10-25 00:00:00'; - $this->customerSecure->expects($this->any()) - ->method('getRpTokenCreatedAt') - ->willReturn($pastDateTime); - $this->customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) - ->disableOriginalConstructor() - ->setMethods(['getResetPasswordLinkExpirationPeriod']) - ->getMock(); - - $this->prepareDateTimeFactory(); - $this->sessionManager = $this->getMockBuilder(\Magento\Framework\Session\SessionManagerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->visitorCollectionFactory = $this->getMockBuilder( - \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class - ) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->saveHandler = $this->getMockBuilder(\Magento\Framework\Session\SaveHandlerInterface::class) - ->disableOriginalConstructor() - ->setMethods(['destroy']) - ->getMockForAbstractClass(); - - $dateTime = '2017-10-25 18:57:08'; - $timestamp = '1508983028'; - $dateTimeMock = $this->getMockBuilder(\DateTime::class) - ->disableOriginalConstructor() - ->setMethods(['format', 'getTimestamp', 'setTimestamp']) - ->getMock(); - - $dateTimeMock->expects($this->any()) - ->method('format') - ->with(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT) - ->willReturn($dateTime); - $dateTimeMock->expects($this->any()) - ->method('getTimestamp') - ->willReturn($timestamp); - $dateTimeMock->expects($this->any()) - ->method('setTimestamp') - ->willReturnSelf(); - $dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $dateTimeFactory->expects($this->any())->method('create')->willReturn($dateTimeMock); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->accountManagement = $this->objectManagerHelper->getObject( - \Magento\Customer\Model\AccountManagement::class, - [ - 'customerFactory' => $this->customerFactory, - 'customerRegistry' => $this->customerRegistry, - 'customerRepository' => $this->customerRepository, - 'customerModel' => $this->customer, - 'dateTimeFactory' => $dateTimeFactory, - 'stringHelper' => $this->string, - 'scopeConfig' => $this->scopeConfig, - 'sessionManager' => $this->sessionManager, - 'visitorCollectionFactory' => $this->visitorCollectionFactory, - 'saveHandler' => $this->saveHandler, - 'encryptor' => $this->encryptor, - 'dataProcessor' => $this->dataObjectProcessor, - 'storeManager' => $this->storeManager, - 'transportBuilder' => $this->transportBuilder, - ] - ); - $this->objectManagerHelper->setBackwardCompatibleProperty( - $this->accountManagement, - 'authentication', - $this->authenticationMock - ); - } - - /** - * @return void - */ - public function testChangePassword() - { - $customerId = 7; - $email = 'test@example.com'; - $currentPassword = '1234567'; - $newPassword = 'abcdefg'; - $passwordHash = '1a2b3f4c'; - - $this->reInitModel(); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMock(); - $customer->expects($this->any()) - ->method('getId') - ->willReturn($customerId); - - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($email) - ->willReturn($customer); - - $this->authenticationMock->expects($this->once()) - ->method('authenticate'); - - $this->customerSecure->expects($this->once()) - ->method('setRpToken') - ->with(null); - $this->customerSecure->expects($this->once()) - ->method('setRpTokenCreatedAt') - ->willReturnSelf(); - $this->customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn($passwordHash); - - $this->customerRegistry->expects($this->any()) - ->method('retrieveSecureData') - ->with($customerId) - ->willReturn($this->customerSecure); - - $this->scopeConfig->expects($this->any()) - ->method('getValue') - ->willReturnMap( - [ - [ - AccountManagement::XML_PATH_MINIMUM_PASSWORD_LENGTH, - 'default', - null, - 7, - ], - [ - AccountManagement::XML_PATH_REQUIRED_CHARACTER_CLASSES_NUMBER, - 'default', - null, - 1, - ], - ] - ); - $this->string->expects($this->any()) - ->method('strlen') - ->with($newPassword) - ->willReturn(7); - - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customer); - - $this->sessionManager->expects($this->atLeastOnce())->method('getSessionId'); - - $visitor = $this->getMockBuilder(\Magento\Customer\Model\Visitor::class) - ->disableOriginalConstructor() - ->setMethods(['getSessionId']) - ->getMock(); - $visitor->expects($this->atLeastOnce())->method('getSessionId') - ->willReturnOnConsecutiveCalls('session_id_1', 'session_id_2'); - $visitorCollection = $this->getMockBuilder( - \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class - ) - ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); - $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); - $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') - ->willReturn($visitorCollection); - $this->saveHandler->expects($this->atLeastOnce())->method('destroy') - ->withConsecutive( - ['session_id_1'], - ['session_id_2'] - ); - - $this->assertTrue($this->accountManagement->changePassword($email, $currentPassword, $newPassword)); - } - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function testResetPassword() - { - $customerEmail = 'customer@example.com'; - $customerId = '1'; - $resetToken = 'newStringToken'; - $newPassword = 'new_password'; - - $this->reInitModel(); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer->expects($this->any())->method('getId')->willReturn($customerId); - $this->customerRepository->expects($this->atLeastOnce())->method('get')->with($customerEmail) - ->willReturn($customer); - $this->customer->expects($this->atLeastOnce())->method('getResetPasswordLinkExpirationPeriod') - ->willReturn(100000); - $this->string->expects($this->any())->method('strlen')->willReturnCallback( - function ($string) { - return strlen($string); - } - ); - $this->customerRegistry->expects($this->atLeastOnce())->method('retrieveSecureData') - ->willReturn($this->customerSecure); - - $this->customerSecure->expects($this->once())->method('setRpToken')->with(null); - $this->customerSecure->expects($this->once())->method('setRpTokenCreatedAt')->with(null); - $this->customerSecure->expects($this->any())->method('setPasswordHash')->willReturn(null); - - $this->sessionManager->expects($this->atLeastOnce())->method('destroy'); - $this->sessionManager->expects($this->atLeastOnce())->method('getSessionId'); - $visitor = $this->getMockBuilder(\Magento\Customer\Model\Visitor::class) - ->disableOriginalConstructor() - ->setMethods(['getSessionId']) - ->getMock(); - $visitor->expects($this->atLeastOnce())->method('getSessionId') - ->willReturnOnConsecutiveCalls('session_id_1', 'session_id_2'); - $visitorCollection = $this->getMockBuilder( - \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class - ) - ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); - $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); - $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') - ->willReturn($visitorCollection); - $this->saveHandler->expects($this->atLeastOnce())->method('destroy') - ->withConsecutive( - ['session_id_1'], - ['session_id_2'] - ); - $this->assertTrue($this->accountManagement->resetPassword($customerEmail, $resetToken, $newPassword)); - } - - /** - * @return void - */ - public function testChangePasswordException() - { - $email = 'test@example.com'; - $currentPassword = '1234567'; - $newPassword = 'abcdefg'; - - $exception = new NoSuchEntityException( - new \Magento\Framework\Phrase('Exception message') - ); - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($email) - ->willThrowException($exception); - - $this->expectException(\Magento\Framework\Exception\InvalidEmailOrPasswordException::class); - $this->expectExceptionMessage('Invalid login or password.'); - - $this->accountManagement->changePassword($email, $currentPassword, $newPassword); - } - - /** - * @return void - */ - public function testAuthenticate() - { - $username = 'login'; - $password = '1234567'; - $passwordHash = '1a2b3f4c'; - - $customerData = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMock(); - - $customerModel = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) - ->disableOriginalConstructor() - ->getMock(); - $customerModel->expects($this->once()) - ->method('updateData') - ->willReturn($customerModel); - - $this->customerRepository - ->expects($this->once()) - ->method('get') - ->with($username) - ->willReturn($customerData); - - $this->authenticationMock->expects($this->once()) - ->method('authenticate'); - - $customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->setMethods(['getPasswordHash']) - ->disableOriginalConstructor() - ->getMock(); - $customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn($passwordHash); - - $this->customerRegistry->expects($this->any()) - ->method('retrieveSecureData') - ->willReturn($customerSecure); - - $this->customerFactory->expects($this->once()) - ->method('create') - ->willReturn($customerModel); - - $this->manager->expects($this->exactly(2)) - ->method('dispatch') - ->withConsecutive( - [ - 'customer_customer_authenticated', - ['model' => $customerModel, 'password' => $password], - ], - [ - 'customer_data_object_login', ['customer' => $customerData], - ] - ); - - $this->assertEquals($customerData, $this->accountManagement->authenticate($username, $password)); - } - - /** - * @param int $isConfirmationRequired - * @param string|null $confirmation - * @param string $expected - * @dataProvider dataProviderGetConfirmationStatus - */ - public function testGetConfirmationStatus( - $isConfirmationRequired, - $confirmation, - $expected - ) { - $websiteId = 1; - $customerId = 1; - $customerEmail = 'test1@example.com'; - - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $customerMock->expects($this->once()) - ->method('getId') - ->willReturn($customerId); - $customerMock->expects($this->any()) - ->method('getConfirmation') - ->willReturn($confirmation); - $customerMock->expects($this->once()) - ->method('getEmail') - ->willReturn($customerEmail); - $customerMock->expects($this->once()) - ->method('getWebsiteId') - ->willReturn($websiteId); - - $this->accountConfirmation->expects($this->once()) - ->method('isConfirmationRequired') - ->with($websiteId, $customerId, $customerEmail) - ->willReturn($isConfirmationRequired); - - $this->customerRepository->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customerMock); - - $this->assertEquals($expected, $this->accountManagement->getConfirmationStatus($customerId)); - } - - /** - * @return array - */ - public function dataProviderGetConfirmationStatus() - { - return [ - [0, null, AccountManagement::ACCOUNT_CONFIRMATION_NOT_REQUIRED], - [0, null, AccountManagement::ACCOUNT_CONFIRMATION_NOT_REQUIRED], - [0, null, AccountManagement::ACCOUNT_CONFIRMATION_NOT_REQUIRED], - [1, null, AccountManagement::ACCOUNT_CONFIRMED], - [1, 'test', AccountManagement::ACCOUNT_CONFIRMATION_REQUIRED], - ]; - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountWithPasswordHashForGuest() - { - $storeId = 1; - $storeName = 'store_name'; - $websiteId = 1; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - $storeMock->expects($this->once()) - ->method('getId') - ->willReturn($storeId); - $storeMock->expects($this->once()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $storeMock->expects($this->once()) - ->method('getName') - ->willReturn($storeName); - - $this->storeManager->expects($this->exactly(3)) - ->method('getStore') - ->willReturn($storeMock); - - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - $customerMock->expects($this->exactly(2)) - ->method('getId') - ->willReturn(null); - $customerMock->expects($this->exactly(3)) - ->method('getStoreId') - ->willReturn(null); - $customerMock->expects($this->exactly(3)) - ->method('getWebsiteId') - ->willReturn(null); - $customerMock->expects($this->once()) - ->method('setStoreId') - ->with($storeId) - ->willReturnSelf(); - $customerMock->expects($this->once()) - ->method('setWebsiteId') - ->with($websiteId) - ->willReturnSelf(); - $customerMock->expects($this->once()) - ->method('setCreatedIn') - ->with($storeName) - ->willReturnSelf(); - $customerMock->expects($this->once()) - ->method('getAddresses') - ->willReturn(null); - $customerMock->expects($this->once()) - ->method('setAddresses') - ->with(null) - ->willReturnSelf(); - - $this->customerRepository - ->expects($this->once()) - ->method('save') - ->with($customerMock, $hash) - ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('Exception message'))); - - $this->accountManagement->createAccountWithPasswordHash($customerMock, $hash); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testCreateAccountWithPasswordHashWithCustomerAddresses() - { - $websiteId = 1; - $addressId = 2; - $customerId = null; - $storeId = 1; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - - $this->prepareDateTimeFactory(); - - //Handle store - $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock(); - $store->expects($this->any()) - ->method('getWebsiteId') - ->willReturn($websiteId); - //Handle address - existing and non-existing. Non-Existing should return null when call getId method - $existingAddress = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $nonExistingAddress = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) - ->disableOriginalConstructor() - ->getMock(); - //Ensure that existing address is not in use - $this->addressRepository - ->expects($this->atLeastOnce()) - ->method("save") - ->withConsecutive( - [$this->logicalNot($this->identicalTo($existingAddress))], - [$this->identicalTo($nonExistingAddress)] - ); - - $existingAddress - ->expects($this->any()) - ->method("getId") - ->willReturn($addressId); - //Expects that id for existing address should be unset - $existingAddress - ->expects($this->once()) - ->method("setId") - ->with(null); - //Handle Customer calls - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); - $customer - ->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer - ->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer - ->expects($this->any()) - ->method("getId") - ->willReturn($customerId); - //Return Customer from customer repository - $this->customerRepository - ->expects($this->atLeastOnce()) - ->method('save') - ->willReturn($customer); - $this->customerRepository - ->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customer); - $customerSecure = $this->getMockBuilder(\Magento\Customer\Model\Data\CustomerSecure::class) - ->setMethods(['setRpToken', 'setRpTokenCreatedAt', 'getPasswordHash']) - ->disableOriginalConstructor() - ->getMock(); - $customerSecure->expects($this->once()) - ->method('setRpToken') - ->with($hash); - - $customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn($hash); - - $this->customerRegistry->expects($this->any()) - ->method('retrieveSecureData') - ->with($customerId) - ->willReturn($customerSecure); - - $this->random->expects($this->once()) - ->method('getUniqueHash') - ->willReturn($hash); - - $customer - ->expects($this->atLeastOnce()) - ->method('getAddresses') - ->willReturn([$existingAddress, $nonExistingAddress]); - - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getStore') - ->willReturn($store); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - - $this->assertSame($customer, $this->accountManagement->createAccountWithPasswordHash($customer, $hash)); - } - - /** - * @return string - */ - private function prepareDateTimeFactory() - { - $dateTime = '2017-10-25 18:57:08'; - $timestamp = '1508983028'; - $dateTimeMock = $this->createMock(\DateTime::class); - $dateTimeMock->expects($this->any()) - ->method('format') - ->with(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT) - ->willReturn($dateTime); - - $dateTimeMock - ->expects($this->any()) - ->method('getTimestamp') - ->willReturn($timestamp); - - $this->dateTimeFactory - ->expects($this->any()) - ->method('create') - ->willReturn($dateTimeMock); - - return $dateTime; - } - - /** - * @return void - */ - public function testCreateAccountUnexpectedValueException(): void - { - $websiteId = 1; - $storeId = null; - $defaultStoreId = 1; - $customerId = 1; - $customerEmail = 'email@email.com'; - $newLinkToken = '2jh43j5h2345jh23lh452h345hfuzasd96ofu'; - $exception = new \UnexpectedValueException('Template file was not found'); - - $datetime = $this->prepareDateTimeFactory(); - - $address = $this->createMock(\Magento\Customer\Api\Data\AddressInterface::class); - $address->expects($this->once()) - ->method('setCustomerId') - ->with($customerId); - $store = $this->createMock(\Magento\Store\Model\Store::class); - $store->expects($this->once()) - ->method('getId') - ->willReturn($defaultStoreId); - $website = $this->createMock(\Magento\Store\Model\Website::class); - $website->expects($this->atLeastOnce()) - ->method('getStoreIds') - ->willReturn([1, 2, 3]); - $website->expects($this->once()) - ->method('getDefaultStore') - ->willReturn($store); - $customer = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); - $customer->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($customerId); - $customer->expects($this->atLeastOnce()) - ->method('getEmail') - ->willReturn($customerEmail); - $customer->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $customer->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customer->expects($this->once()) - ->method('setStoreId') - ->with($defaultStoreId); - $customer->expects($this->once()) - ->method('getAddresses') - ->willReturn([$address]); - $customer->expects($this->once()) - ->method('setAddresses') - ->with(null); - $this->customerRepository->expects($this->once()) - ->method('get') - ->with($customerEmail) - ->willReturn($customer); - $this->share->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $this->storeManager->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->customerRepository->expects($this->atLeastOnce()) - ->method('save') - ->willReturn($customer); - $this->addressRepository->expects($this->atLeastOnce()) - ->method('save') - ->with($address); - $this->customerRepository->expects($this->once()) - ->method('getById') - ->with($customerId) - ->willReturn($customer); - $this->random->expects($this->once()) - ->method('getUniqueHash') - ->willReturn($newLinkToken); - $customerSecure = $this->createPartialMock( - \Magento\Customer\Model\Data\CustomerSecure::class, - ['setRpToken', 'setRpTokenCreatedAt', 'getPasswordHash'] - ); - $customerSecure->expects($this->any()) - ->method('setRpToken') - ->with($newLinkToken); - $customerSecure->expects($this->any()) - ->method('setRpTokenCreatedAt') - ->with($datetime) - ->willReturnSelf(); - $customerSecure->expects($this->any()) - ->method('getPasswordHash') - ->willReturn(null); - $this->customerRegistry->expects($this->atLeastOnce()) - ->method('retrieveSecureData') - ->willReturn($customerSecure); - $this->emailNotificationMock->expects($this->once()) - ->method('newAccount') - ->willThrowException($exception); - $this->logger->expects($this->once())->method('error')->with($exception); - - $this->accountManagement->createAccount($customer); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCreateAccountWithStoreNotInWebsite() - { - $storeId = 1; - $websiteId = 1; - $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); - $customerMock->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn(null); - $customerMock->expects($this->atLeastOnce()) - ->method('getStoreId') - ->willReturn($storeId); - $customerMock->expects($this->atLeastOnce()) - ->method('getWebsiteId') - ->willReturn($websiteId); - $this->share - ->expects($this->once()) - ->method('isWebsiteScope') - ->willReturn(true); - $website = $this->getMockBuilder(\Magento\Store\Model\Website::class)->disableOriginalConstructor()->getMock(); - $website->expects($this->once()) - ->method('getStoreIds') - ->willReturn([2, 3]); - $this->storeManager - ->expects($this->atLeastOnce()) - ->method('getWebsite') - ->with($websiteId) - ->willReturn($website); - $this->accountManagement->createAccountWithPasswordHash($customerMock, $hash); - } -} From e41cd3a5aef2c0620f05b758dc6852ceb46785d8 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 16:09:39 +0300 Subject: [PATCH 0176/1415] MAGETWO-70943: Incorrect reset password flow --- app/code/Magento/Customer/Model/AccountManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 52264c78b7717..6aee2894f4907 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -661,7 +661,7 @@ private function handleUnknownTemplate($template) /** * @inheritdoc */ - public function resetPassword(?string $email, string $resetToken, string $newPassword): bool + public function resetPassword($email, $resetToken, $newPassword): bool { if (!$email) { $customer = $this->matchCustomerByRpToken($resetToken); From 5f25e562a87f74b3f4794f3facfbd6b2f59d9892 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 21 Sep 2018 17:01:19 +0300 Subject: [PATCH 0177/1415] MAGETWO-69021: salesOrderRepositoryV1 API Missing Extension Attributes - Add information about tax to extension attributes --- .../Magento/Sales/Model/OrderRepository.php | 41 ++++++++- .../Test/Unit/Model/OrderRepositoryTest.php | 40 ++++++++- .../Magento/Sales/Service/V1/OrderGetTest.php | 35 ++++++++ .../Sales/Service/V1/OrderListTest.php | 86 ++++++++++++++----- .../Magento/Sales/_files/order_list.php | 2 + .../Sales/_files/order_list_with_tax.php | 55 ++++++++++++ .../_files/order_list_with_tax_rollback.php | 8 ++ .../Magento/Sales/_files/order_with_tax.php | 52 +++++++++++ .../Sales/_files/order_with_tax_rollback.php | 8 ++ 9 files changed, 301 insertions(+), 26 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax_rollback.php diff --git a/app/code/Magento/Sales/Model/OrderRepository.php b/app/code/Magento/Sales/Model/OrderRepository.php index f5ab45c5eb1ba..a98d6193402a9 100644 --- a/app/code/Magento/Sales/Model/OrderRepository.php +++ b/app/code/Magento/Sales/Model/OrderRepository.php @@ -17,6 +17,7 @@ use Magento\Sales\Model\Order\ShippingAssignmentBuilder; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Framework\App\ObjectManager; +use Magento\Tax\Api\OrderTaxManagementInterface; /** * Repository class @@ -55,6 +56,11 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface */ protected $registry = []; + /** + * @var OrderTaxManagementInterface + */ + private $orderTaxManagement; + /** * Constructor * @@ -62,12 +68,14 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface * @param SearchResultFactory $searchResultFactory * @param CollectionProcessorInterface|null $collectionProcessor * @param \Magento\Sales\Api\Data\OrderExtensionFactory|null $orderExtensionFactory + * @param OrderTaxManagementInterface|null $orderTaxManagement */ public function __construct( Metadata $metadata, SearchResultFactory $searchResultFactory, CollectionProcessorInterface $collectionProcessor = null, - \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory = null + \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory = null, + OrderTaxManagementInterface $orderTaxManagement = null ) { $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; @@ -75,10 +83,12 @@ public function __construct( ->get(\Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class); $this->orderExtensionFactory = $orderExtensionFactory ?: ObjectManager::getInstance() ->get(\Magento\Sales\Api\Data\OrderExtensionFactory::class); + $this->orderTaxManagement = $orderTaxManagement ?: ObjectManager::getInstance() + ->get(OrderTaxManagementInterface::class); } /** - * load entity + * Load entity * * @param int $id * @return \Magento\Sales\Api\Data\OrderInterface @@ -98,12 +108,36 @@ public function get($id) __("The entity that was requested doesn't exist. Verify the entity and try again.") ); } + $this->setOrderTaxDetails($entity); $this->setShippingAssignments($entity); $this->registry[$id] = $entity; } return $this->registry[$id]; } + /** + * Set order tax details to extension attributes. + * + * @param OrderInterface $order + * @return void + */ + private function setOrderTaxDetails(OrderInterface $order) + { + $extensionAttributes = $order->getExtensionAttributes(); + $orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getEntityId()); + $appliedTaxes = $orderTaxDetails->getAppliedTaxes(); + + $extensionAttributes->setAppliedTaxes($appliedTaxes); + if (!empty($appliedTaxes)) { + $extensionAttributes->setConvertingFromQuote(true); + } + + $items = $orderTaxDetails->getItems(); + $extensionAttributes->setItemAppliedTaxes($items); + + $order->setExtensionAttributes($extensionAttributes); + } + /** * Find entities by criteria * @@ -118,6 +152,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $searchResult->setSearchCriteria($searchCriteria); foreach ($searchResult->getItems() as $order) { $this->setShippingAssignments($order); + $this->setOrderTaxDetails($order); } return $searchResult; } @@ -171,6 +206,8 @@ public function save(\Magento\Sales\Api\Data\OrderInterface $entity) } /** + * Set shipping assignments to extension attributes. + * * @param OrderInterface $order * @return void */ diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php index 3df667094f2a9..2e82d8064a9e8 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php @@ -9,6 +9,7 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderSearchResultInterfaceFactory as SearchResultFactory; use Magento\Sales\Model\ResourceModel\Metadata; +use Magento\Tax\Api\OrderTaxManagementInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -40,8 +41,15 @@ class OrderRepositoryTest extends \PHPUnit\Framework\TestCase */ private $collectionProcessor; + /** + * @var OrderTaxManagementInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderTaxManagementMock; + /** * Setup the test + * + * @return void */ protected function setUp() { @@ -58,34 +66,53 @@ protected function setUp() $orderExtensionFactoryMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderExtensionFactory::class) ->disableOriginalConstructor() ->getMock(); + $this->orderTaxManagementMock = $this->getMockBuilder(OrderTaxManagementInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); $this->orderRepository = $this->objectManager->getObject( \Magento\Sales\Model\OrderRepository::class, [ 'metadata' => $this->metadata, 'searchResultFactory' => $this->searchResultFactory, 'collectionProcessor' => $this->collectionProcessor, - 'orderExtensionFactory' => $orderExtensionFactoryMock + 'orderExtensionFactory' => $orderExtensionFactoryMock, + 'orderTaxManagement' => $this->orderTaxManagementMock ] ); } + /** + * Test for method getList. + * + * @return void + */ public function testGetList() { $searchCriteriaMock = $this->createMock(\Magento\Framework\Api\SearchCriteria::class); $collectionMock = $this->createMock(\Magento\Sales\Model\ResourceModel\Order\Collection::class); - $itemsMock = $this->getMockBuilder(OrderInterface::class)->disableOriginalConstructor()->getMock(); + $itemsMock = $this->getMockBuilder(OrderInterface::class)->disableOriginalConstructor() + ->getMockForAbstractClass(); + $orderTaxDetailsMock = $this->getMockBuilder(\Magento\Tax\Api\Data\OrderTaxDetailsInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getAppliedTaxes', 'getItems'])->getMockForAbstractClass(); $extensionAttributes = $this->createPartialMock( \Magento\Sales\Api\Data\OrderExtension::class, - ['getShippingAssignments'] + [ + 'getShippingAssignments', 'setShippingAssignments', 'setConvertingFromQuote', + 'setAppliedTaxes', 'setItemAppliedTaxes' + ] ); $shippingAssignmentBuilder = $this->createMock( \Magento\Sales\Model\Order\ShippingAssignmentBuilder::class ); + $itemsMock->expects($this->atLeastOnce())->method('getEntityId')->willReturn(1); $this->collectionProcessor->expects($this->once()) ->method('process') ->with($searchCriteriaMock, $collectionMock); - $itemsMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes); + $itemsMock->expects($this->atLeastOnce())->method('getExtensionAttributes')->willReturn($extensionAttributes); + $this->orderTaxManagementMock->expects($this->atLeastOnce())->method('getOrderTaxDetails') + ->willReturn($orderTaxDetailsMock); $extensionAttributes->expects($this->any()) ->method('getShippingAssignments') ->willReturn($shippingAssignmentBuilder); @@ -96,6 +123,11 @@ public function testGetList() $this->assertEquals($collectionMock, $this->orderRepository->getList($searchCriteriaMock)); } + /** + * Test for method save. + * + * @return void + */ public function testSave() { $mapperMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order::class) diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php index 7adde3c11ac61..a10a224604897 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php @@ -115,4 +115,39 @@ public function testOrderGet() $this->assertNotNull($value); } } + + /** + * @magentoApiDataFixture Magento/Sales/_files/order_with_tax.php + */ + public function testOrderGetExtensionAttributes() + { + $expectedTax = [ + 'code' => 'US-NY-*-Rate 1', + 'type' => 'shipping' + ]; + + /** @var \Magento\Sales\Model\Order $order */ + $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); + $order->loadByIncrementId(self::ORDER_INCREMENT_ID); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '/' . $order->getId(), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'get', + ], + ]; + $result = $this->_webApiCall($serviceInfo, ['id' => $order->getId()]); + + $appliedTaxes = $result['extension_attributes']['applied_taxes']; + $this->assertEquals($expectedTax['code'], $appliedTaxes[0]['code']); + $appliedTaxes = $result['extension_attributes']['item_applied_taxes']; + $this->assertEquals($expectedTax['type'], $appliedTaxes[0]['type']); + $this->assertNotEmpty($appliedTaxes[0]['applied_taxes']); + $this->assertEquals(true, $result['extension_attributes']['converting_from_quote']); + } } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php index 0500f31858291..5050b6be7e56c 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php @@ -33,6 +33,71 @@ protected function setUp() * @magentoApiDataFixture Magento/Sales/_files/order_list.php */ public function testOrderList() + { + $searchData = $this->getSearchData(); + + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'getList', + ], + ]; + + $result = $this->_webApiCall($serviceInfo, $requestData); + $this->assertArrayHasKey('items', $result); + $this->assertCount(2, $result['items']); + $this->assertArrayHasKey('search_criteria', $result); + $this->assertEquals($searchData, $result['search_criteria']); + $this->assertEquals('100000002', $result['items'][0]['increment_id']); + $this->assertEquals('100000001', $result['items'][1]['increment_id']); + } + + /** + * @magentoApiDataFixture Magento/Sales/_files/order_list_with_tax.php + */ + public function testOrderListExtensionAttributes() + { + $searchData = $this->getSearchData(); + + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'getList', + ], + ]; + + $result = $this->_webApiCall($serviceInfo, $requestData); + + $expectedTax = [ + 'code' => 'US-NY-*-Rate 1', + 'type' => 'shipping' + ]; + $appliedTaxes = $result['items'][0]['extension_attributes']['applied_taxes']; + $this->assertEquals($expectedTax['code'], $appliedTaxes[0]['code']); + $appliedTaxes = $result['items'][0]['extension_attributes']['item_applied_taxes']; + $this->assertEquals($expectedTax['type'], $appliedTaxes[0]['type']); + $this->assertNotEmpty($appliedTaxes[0]['applied_taxes']); + $this->assertEquals(true, $result['items'][0]['extension_attributes']['converting_from_quote']); + } + + /** + * Get search data for request. + * + * @return array + */ + private function getSearchData() : array { /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ $sortOrderBuilder = $this->objectManager->get( @@ -70,25 +135,6 @@ public function testOrderList() $searchCriteriaBuilder->addSortOrder($sortOrder); $searchData = $searchCriteriaBuilder->create()->__toArray(); - $requestData = ['searchCriteria' => $searchData]; - $serviceInfo = [ - 'rest' => [ - 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, - ], - 'soap' => [ - 'service' => self::SERVICE_READ_NAME, - 'serviceVersion' => self::SERVICE_VERSION, - 'operation' => self::SERVICE_READ_NAME . 'getList', - ], - ]; - - $result = $this->_webApiCall($serviceInfo, $requestData); - $this->assertArrayHasKey('items', $result); - $this->assertCount(2, $result['items']); - $this->assertArrayHasKey('search_criteria', $result); - $this->assertEquals($searchData, $result['search_criteria']); - $this->assertEquals('100000002', $result['items'][0]['increment_id']); - $this->assertEquals('100000001', $result['items'][1]['increment_id']); + return $searchData; } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php index 43e98419798a8..890c475b0c316 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php @@ -48,6 +48,7 @@ ], ]; +$orderList = []; /** @var array $orderData */ foreach ($orders as $orderData) { /** @var $order \Magento\Sales\Model\Order */ @@ -60,4 +61,5 @@ ->setBillingAddress($billingAddress) ->setBillingAddress($shippingAddress) ->save(); + $orderList[] = $order; } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax.php new file mode 100644 index 0000000000000..48f6ccfead297 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Model\Order\Tax\ItemFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Tax\Model\Sales\Order\TaxFactory; + +require 'default_rollback.php'; +require 'order_list.php'; + +/** @var array $orderList */ +foreach ($orderList as $order) { + $amount = 45; + $taxFactory = $objectManager->create(TaxFactory::class); + + /** @var \Magento\Tax\Model\Sales\Order\Tax $tax */ + $tax = $taxFactory->create(); + $tax->setOrderId($order->getId()) + ->setCode('US-NY-*-Rate 1') + ->setTitle('US-NY-*-Rate 1') + ->setPercent(8.37) + ->setAmount($amount) + ->setBaseAmount($amount) + ->setBaseRealAmount($amount); + $tax->save(); + + $salesOrderFactory = $objectManager->create(ItemFactory::class); + + /** @var \Magento\Sales\Model\Order\Tax\Item $salesOrderItem */ + $salesOrderItem = $salesOrderFactory->create(); + $salesOrderItem->setOrderId($order->getId()) + ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) + ->setProductOptions([]); + $salesCollection = $objectManager->create(\Magento\Sales\Model\ResourceModel\Order\Item::class); + $salesCollection->save($salesOrderItem); + + /** @var \Magento\Sales\Model\Order\Tax\Item $salesOrderItem */ + $salesOrderTaxItem = $salesOrderFactory->create(); + $salesOrderTaxItem->setTaxId($tax->getId()) + ->setTaxPercent(8.37) + ->setTaxAmount($amount) + ->setBaseAmount($amount) + ->setRealAmount($amount) + ->setRealBaseAmount($amount) + ->setAppliedTaxes([$tax]) + ->setTaxableItemType('shipping') + ->setItemId($salesOrderItem->getId()); + + $taxItemCollection = $objectManager->create(\Magento\Sales\Model\ResourceModel\Order\Tax\Item::class); + $taxItemCollection->save($salesOrderTaxItem); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax_rollback.php new file mode 100644 index 0000000000000..dd52deab825cb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_with_tax_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require 'order_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax.php new file mode 100644 index 0000000000000..0c7dc522f5759 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Model\Order\Tax\ItemFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Tax\Model\Sales\Order\TaxFactory; + +require 'default_rollback.php'; +require 'order.php'; + +$amount = 45; +$taxFactory = $objectManager->create(TaxFactory::class); + +/** @var \Magento\Tax\Model\Sales\Order\Tax $tax */ +$tax = $taxFactory->create(); +$tax->setOrderId($order->getId()) + ->setCode('US-NY-*-Rate 1') + ->setTitle('US-NY-*-Rate 1') + ->setPercent(8.37) + ->setAmount($amount) + ->setBaseAmount($amount) + ->setBaseRealAmount($amount); +$tax->save(); + +$salesOrderFactory = $objectManager->create(ItemFactory::class); + +/** @var \Magento\Sales\Model\Order\Tax\Item $salesOrderItem */ +$salesOrderItem = $salesOrderFactory->create(); +$salesOrderItem->setOrderId($order->getId()) + ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) + ->setProductOptions([]); +$salesCollection = $objectManager->create(\Magento\Sales\Model\ResourceModel\Order\Item::class); +$salesCollection->save($salesOrderItem); + +/** @var \Magento\Sales\Model\Order\Tax\Item $salesOrderTaxItem */ +$salesOrderTaxItem = $salesOrderFactory->create(); +$salesOrderTaxItem->setTaxId($tax->getId()) + ->setTaxPercent(8.37) + ->setTaxAmount($amount) + ->setBaseAmount($amount) + ->setRealAmount($amount) + ->setRealBaseAmount($amount) + ->setAppliedTaxes([$tax]) + ->setTaxableItemType('shipping') + ->setItemId($salesOrderItem->getId()); + +$taxItemCollection = $objectManager->create(\Magento\Sales\Model\ResourceModel\Order\Tax\Item::class); +$taxItemCollection->save($salesOrderTaxItem); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax_rollback.php new file mode 100644 index 0000000000000..dd52deab825cb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_tax_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require 'order_rollback.php'; From bb949b4f3a0322f1ab73b19c2680d12859294038 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Fri, 21 Sep 2018 20:50:29 +0600 Subject: [PATCH 0178/1415] MAGETWO-91745: Product pages load blank page - Added automated test --- .../Mftf/Data/CatalogAttributeSetData.xml | 16 ++++++++++++ .../Catalog/Test/Mftf/Data/ProductData.xml | 14 +++++++++++ .../Metadata/catalog_attribute_set-meta.xml | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml new file mode 100644 index 0000000000000..d78c03a51dd75 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CatalogAttributeSet" type="CatalogAttributeSet"> + <data key="attribute_set_name" unique="suffix">test_set_</data> + <data key="attributeGroupId">7</data> + <data key="skeletonId">4</data> + </entity> +</entities> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 9ae551b69d388..3da3272567c9d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -301,6 +301,20 @@ <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> </entity> + <entity name="SimpleProductWithCustomAttributeSet" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <var key="attribute_set_id" entityKey="attribute_set_id" entityType="CatalogAttributeSet"/> + <data key="visibility">4</data> + <data key="name" unique="suffix">testProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">testurlkey</data> + <data key="status">1</data> + <data key="weight">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> <entity name="productWithOptions" type="product"> <var key="sku" entityType="product" entityKey="sku" /> <data key="file">magento.jpg</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml new file mode 100644 index 0000000000000..9ef7b507812a0 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="AddCatalogAttributeToAttributeSet" dataType="CatalogAttributeSet" type="create" auth="adminOauth" url="/V1/products/attribute-sets" method="POST"> + <contentType>application/json</contentType> + <object key="attributeSet" dataType="CatalogAttributeSet"> + <field key="attribute_set_name">string</field> + <field key="sort_order">integer</field> + </object> + <field key="skeletonId">integer</field> + </operation> + <operation name="DeleteCatalogAttributeFromAttributeSet" dataType="CatalogAttributeSet" type="delete" auth="adminOauth" url="/V1/products/attribute-sets/{attribute_set_id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> + <operation name="GetCatalogAttributesFromDefaultSet" dataType="CatalogAttributeSet" type="get" auth="adminOauth" url="/V1/products/attribute-sets/{attribute_set_id}" method="GET"> + <contentType>application/json</contentType> + </operation> +</operations> \ No newline at end of file From b35b68130265163f2ed151ff94e0d9f7fc63d44c Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 21 Sep 2018 18:57:25 +0300 Subject: [PATCH 0179/1415] MAGETWO-91702: Shipping method Table Rates settings gets from wrong store - Get store id from quote for shipping rates --- .../Magento/Quote/Model/Quote/Address.php | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 3eb5d68885035..11beffe5711b9 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -965,6 +965,7 @@ public function collectShippingRates() /** * Request shipping rates for entire address or specified address item + * * Returns true if current selected shipping method code corresponds to one of the found rates * * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item @@ -1002,7 +1003,7 @@ public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractIte /** * Store and website identifiers specified from StoreManager */ - $request->setStoreId($this->storeManager->getStore()->getId()); + $request->setStoreId($this->getQuote()->getStoreId() ?? $this->storeManager->getStore()->getId()); $request->setWebsiteId($this->storeManager->getWebsite()->getId()); $request->setFreeShipping($this->getFreeShipping()); /** @@ -1348,7 +1349,7 @@ public function getAllBaseTotalAmounts() /******************************* End Total Collector Interface *******************************************/ /** - * {@inheritdoc} + * @inheritdoc */ protected function _getValidationRulesBeforeSave() { @@ -1356,7 +1357,7 @@ protected function _getValidationRulesBeforeSave() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCountryId() { @@ -1364,7 +1365,7 @@ public function getCountryId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($countryId) { @@ -1372,7 +1373,7 @@ public function setCountryId($countryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getStreet() { @@ -1381,7 +1382,7 @@ public function getStreet() } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -1389,7 +1390,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompany() { @@ -1397,7 +1398,7 @@ public function getCompany() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -1405,7 +1406,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function getTelephone() { @@ -1413,7 +1414,7 @@ public function getTelephone() } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -1421,7 +1422,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFax() { @@ -1429,7 +1430,7 @@ public function getFax() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -1437,7 +1438,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPostcode() { @@ -1445,7 +1446,7 @@ public function getPostcode() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -1453,7 +1454,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCity() { @@ -1461,7 +1462,7 @@ public function getCity() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -1469,7 +1470,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFirstname() { @@ -1477,7 +1478,7 @@ public function getFirstname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -1485,7 +1486,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getLastname() { @@ -1493,7 +1494,7 @@ public function getLastname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -1501,7 +1502,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getMiddlename() { @@ -1509,7 +1510,7 @@ public function getMiddlename() } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -1517,7 +1518,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPrefix() { @@ -1525,7 +1526,7 @@ public function getPrefix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -1533,7 +1534,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSuffix() { @@ -1541,7 +1542,7 @@ public function getSuffix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -1549,7 +1550,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getVatId() { @@ -1557,7 +1558,7 @@ public function getVatId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($vatId) { @@ -1565,7 +1566,7 @@ public function setVatId($vatId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerId() { @@ -1573,7 +1574,7 @@ public function getCustomerId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($customerId) { @@ -1581,7 +1582,7 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getEmail() { @@ -1594,7 +1595,7 @@ public function getEmail() } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -1602,7 +1603,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -1610,7 +1611,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($regionId) { @@ -1618,7 +1619,7 @@ public function setRegionId($regionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -1626,7 +1627,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSameAsBilling() { @@ -1634,7 +1635,7 @@ public function getSameAsBilling() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSameAsBilling($sameAsBilling) { @@ -1642,7 +1643,7 @@ public function setSameAsBilling($sameAsBilling) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerAddressId() { @@ -1650,7 +1651,7 @@ public function getCustomerAddressId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($customerAddressId) { @@ -1681,9 +1682,7 @@ public function setSaveInAddressBook($saveInAddressBook) //@codeCoverageIgnoreEnd /** - * {@inheritdoc} - * - * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null + * @inheritdoc */ public function getExtensionAttributes() { @@ -1691,10 +1690,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} - * - * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes - * @return $this + * @inheritdoc */ public function setExtensionAttributes(\Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes) { @@ -1712,7 +1708,7 @@ public function getShippingMethod() } /** - * {@inheritdoc} + * @inheritdoc */ protected function getCustomAttributesCodes() { From 14d9528852bd30b6f7545b3a22ac2d555a196543 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Fri, 21 Sep 2018 15:14:11 -0300 Subject: [PATCH 0180/1415] Replaced {@inheritdoc} with the actual documentation in order to fix code style violations --- .../Framework/Stdlib/DateTime/Timezone.php | 71 +++++++++++++++---- .../Stdlib/DateTime/TimezoneInterface.php | 18 ++++- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 59b299d176bd1..2bfa465c8268f 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -85,7 +85,9 @@ public function __construct( } /** - * {@inheritdoc} + * Return path to default timezone + * + * @return string */ public function getDefaultTimezonePath() { @@ -93,7 +95,9 @@ public function getDefaultTimezonePath() } /** - * {@inheritdoc} + * Retrieve timezone code + * + * @return string */ public function getDefaultTimezone() { @@ -101,7 +105,11 @@ public function getDefaultTimezone() } /** - * {@inheritdoc} + * Gets the scope config timezone + * + * @param string $scopeType + * @param string $scopeCode + * @return string */ public function getConfigTimezone($scopeType = null, $scopeCode = null) { @@ -113,7 +121,10 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null) } /** - * {@inheritdoc} + * Retrieve ISO date format + * + * @param int $type + * @return string */ public function getDateFormat($type = \IntlDateFormatter::SHORT) { @@ -125,7 +136,9 @@ public function getDateFormat($type = \IntlDateFormatter::SHORT) } /** - * {@inheritdoc} + * Retrieve short date format with 4-digit year + * + * @return string */ public function getDateFormatWithLongYear() { @@ -137,7 +150,10 @@ public function getDateFormatWithLongYear() } /** - * {@inheritdoc} + * Retrieve ISO time format + * + * @param string $type + * @return string */ public function getTimeFormat($type = \IntlDateFormatter::SHORT) { @@ -149,7 +165,10 @@ public function getTimeFormat($type = \IntlDateFormatter::SHORT) } /** - * {@inheritdoc} + * Retrieve ISO datetime format + * + * @param string $type + * @return string */ public function getDateTimeFormat($type) { @@ -157,7 +176,13 @@ public function getDateTimeFormat($type) } /** - * {@inheritdoc} + * Create \DateTime object for current locale + * + * @param mixed $date + * @param string $locale + * @param bool $useTimezone + * @param bool $includeTime + * @return \DateTime */ public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true) { @@ -191,7 +216,12 @@ public function date($date = null, $locale = null, $useTimezone = true, $include } /** - * {@inheritdoc} + * Create \DateTime object with date converted to scope timezone and scope Locale + * + * @param mixed $scope Information about scope + * @param string|integer|\DateTime|array|null $date date in UTC + * @param boolean $includeTime flag for including time to date + * @return \DateTime */ public function scopeDate($scope = null, $date = null, $includeTime = false) { @@ -204,7 +234,12 @@ public function scopeDate($scope = null, $date = null, $includeTime = false) } /** - * {@inheritdoc} + * Format date using current locale options and time zone. + * + * @param \DateTime|null $date + * @param int $format + * @param bool $showTime + * @return string */ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $showTime = false) { @@ -218,7 +253,12 @@ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $s } /** - * {@inheritdoc} + * Get scope timestamp + * + * Timestamp will be built with scope timezone settings + * + * @param mixed $scope + * @return int */ public function scopeTimeStamp($scope = null) { @@ -231,7 +271,12 @@ public function scopeTimeStamp($scope = null) } /** - * {@inheritdoc} + * Checks if current date of the given scope (in the scope timezone) is within the range + * + * @param int|string|\Magento\Framework\App\ScopeInterface $scope + * @param string|null $dateFrom + * @param string|null $dateTo + * @return bool */ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) { @@ -300,6 +345,7 @@ public function formatDateTime( /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date @@ -315,6 +361,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 5a4b15d6cca0c..17ba759a4d763 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -80,6 +80,7 @@ public function scopeDate($scope = null, $date = null, $includeTime = false); /** * Get scope timestamp + * * Timestamp will be built with scope timezone settings * * @param mixed $scope @@ -121,6 +122,7 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -139,19 +141,29 @@ public function formatDateTime( ); /** + * Convert date from config timezone to Utc. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * * @param string|\DateTimeInterface $date * @param string $format + * @throws LocalizedException * @return string - * @since 100.1.0 * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); /** - * @param $date + * Convert date from config timezone to Utc. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date * @param string $format * @param string $pattern - * @return mixed + * @throws LocalizedException + * @return string + * @deprecated */ public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From 63d33c5081068ca8253e52763fb8ab7d5ffe8a1a Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 21 Sep 2018 15:08:49 -0500 Subject: [PATCH 0181/1415] MAGETWO-90280: Could not create customer via API without store_id --- .../Customer/Model/AccountManagement.php | 1 + .../Customer/Api/AccountManagementTest.php | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index fe17adcb09c0d..3d88aeaef767b 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -781,6 +781,7 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash if ($customer->getWebsiteId()) { $storeId = $this->storeManager->getWebsite($customer->getWebsiteId())->getDefaultStore()->getId(); } else { + $this->storeManager->setCurrentStore(null); $storeId = $this->storeManager->getStore()->getId(); } $customer->setStoreId($storeId); 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 b0d1647d8b837..b2276d79f5ecf 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php @@ -213,6 +213,34 @@ public function testCreateCustomerWithErrors() } } + public function testCreateCustomerWithoutOptionalFields() + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'CreateAccount', + ], + ]; + + $customerDataArray = $this->dataObjectProcessor->buildOutputDataArray( + $this->customerHelper->createSampleCustomerDataObject(), + \Magento\Customer\Api\Data\CustomerInterface::class + ); + unset($customerDataArray['store_id']); + unset($customerDataArray['website_id']); + $requestData = ['customer' => $customerDataArray, 'password' => CustomerHelper::PASSWORD]; + try { + $customerData = $this->_webApiCall($serviceInfo, $requestData, null, 'all'); + $this->assertNotNull($customerData['id']); + } catch (\Exception $e) { + $this->fail('Customer should be created without optional fields.'); + } + } + /** * Test customer activation when it is required * From 93f6e5e17d024e00cea0bcf6254afc47cf53b73a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sat, 22 Sep 2018 11:46:44 +0200 Subject: [PATCH 0182/1415] Added schema concept for working with cart addresses and shipping methods --- .../Magento/QuoteGraphQl/etc/schema.graphqls | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 06b3328b9e058..b10575171781e 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -1,10 +1,82 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. +type Query { + getAvailableShippingMethodsOnCart(input: AvailableShippingMethodsOnCartInput): AvailableShippingMethodsOnCartOutput @doc(description:"Returns available shipping methods for cart by address/address_id") +} + type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput + setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput +} + +input SetShippingAddressesOnCartInput { + cart_id: String! + customer_address_id: Int # Can be provided in one-page checkout and is required for multi-shipping checkout + address: CartAddressInput + cart_items: [CartItemQuantityInput!] +} + +input CartItemQuantityInput { + cart_item_id: Int! + quantity: Float! +} + +input SetBillingAddressOnCartInput { + cart_id: String! + customer_address_id: Int + address: CartAddressInput + # TODO: consider adding "Same as shipping" option +} + +input CartAddressInput { + firstname: String! + lastname: String! + company: String + street: [String!]! + city: String! + region: String + postcode: String + country_code: String! + telephone: String! + save_in_address_book: Boolean! +} + +input SetShippingMethodsOnCartInput { + shipping_methods: [ShippingMethodForAddressInput!]! +} + +input ShippingMethodForAddressInput { + cart_address_id: String! + shipping_method_code: String! +} + +type SetBillingAddressOnCartOutput { + cart: Cart! +} + +type SetShippingAddressesOnCartOutput { + cart: Cart! +} + +type SetShippingMethodsOnCartOutput { + cart: Cart! +} + +# If no address is provided, the system get address assigned to a quote +# If there's no address at all - the system returns all shipping methods +type AvailableShippingMethodsOnCartInput { + cart_id: String! + customer_address_id: Int + address: CartAddressInput +} + +type AvailableShippingMethodsOnCartOutput { + available_shipping_methods: [CheckoutShippingMethod] } input ApplyCouponToCartInput { @@ -18,12 +90,56 @@ type ApplyCouponToCartOutput { type Cart { applied_coupon: AppliedCoupon + addresses: [CartAddress]! } type CartAddress { + firstname: String! + lastname: String! + company: String + street: [String!]! + city: String! + region: CartAddressRegion + postcode: String + country: CartAddressCountry! + telephone: String! + address_type: AdressTypeEnum! + selected_shipping_method: CheckoutShippingMethod + available_shipping_methods: [CheckoutShippingMethod]! + items_weight: Float + customer_notes: String + cart_items: [CartItemQuantity] applied_coupon: AppliedCoupon } +type CartItemQuantity { + cart_item_id: String! + quantity: Float! +} + +type CartAddressRegion { + code: String + label: String +} + +type CartAddressCountry { + code: String + label: String +} + +type CheckoutShippingMethod { + code: String + label: String + free_shipping: Boolean! + error_message: String + # TODO: Add more complex structure for shipping rates +} + +enum AdressTypeEnum { + SHIPPING + BILLING +} + type AppliedCoupon { code: String! } From 79a968ba6bbb54ce8c3e5714bba164f924fc74f3 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 22 Sep 2018 10:28:58 +0000 Subject: [PATCH 0183/1415] graphQl-44: refactoring of format strategy Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++---------- .../ProductTextAttribute/FormatInterface.php | 2 +- .../ProductTextAttribute/FormatList.php | 28 +++++++++------- .../Product/ProductTextAttribute/Html.php | 2 +- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 ++++ .../CatalogGraphQl/etc/schema.graphqls | 12 +++---- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index f04609f91c86d..9c1212667acf3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; @@ -18,9 +18,12 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextareaAttribute implements ResolverInterface +class ProductTextAttribute implements ResolverInterface { - const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** + * @var FormatList + */ + private $formatList; /** * @var ValueFactory @@ -28,20 +31,20 @@ class ProductTextareaAttribute implements ResolverInterface private $valueFactory; /** - * @var FormatFactory + * @var string */ - private $formatFactory; + private $defaultFormat = 'html'; /** * @param ValueFactory $valueFactory - * @param FormatFactory $formatFactory + * @param FormatList $formatFactory */ public function __construct( ValueFactory $valueFactory, - FormatFactory $formatFactory + FormatList $formatFactory ) { $this->valueFactory = $valueFactory; - $this->formatFactory = $formatFactory; + $this->formatList = $formatFactory; } /** @@ -55,22 +58,16 @@ public function resolve( array $args = null ): Value { if (!isset($value['model'])) { - $result = function () { - return null; - }; + $result = []; return $this->valueFactory->create($result); } /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; - $format = $this->formatFactory->create($formatIdentifier); - $attribute = ['content' => $format->getContent($product, $fieldName)]; - - $result = function () use ($attribute) { - return $attribute; - }; + $formatIdentifier = $args['format'] ?? $this->defaultFormat; + $format = $this->formatList->create($formatIdentifier); + $result = ['content' => $format->getContent($product, $fieldName)]; return $this->valueFactory->create($result); } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php index fae685b75c060..2cf702bf18466 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Catalog\Model\Product as ModelProduct; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 97e0be3763f1d..2e2f21d643092 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -9,35 +9,39 @@ use Magento\Framework\ObjectManagerInterface; -class FormatFactory +class FormatList { /** * @var ObjectManagerInterface */ private $objectManager; + /** + * @var string + */ + private $formats; + /** * @param ObjectManagerInterface $objectManager + * @param array $formats */ - public function __construct(ObjectManagerInterface $objectManager) - { + public function __construct( + ObjectManagerInterface $objectManager, + array $formats + ) { $this->objectManager = $objectManager; + $this->formats = $formats; } /** * @param string $formatIdentifier - * @param array $data * @return FormatInterface */ - public function create(string $formatIdentifier, $data = []) : FormatInterface + public function create(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->create($formatClassName, $data); - if (false == $formatInstance instanceof FormatInterface) { - throw new \InvalidArgumentException( - $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' - ); - } + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->get($formatClassName); + return $formatInstance; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 8201c40427dc9..75c29a3f78fac 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Catalog\Helper\Output as OutputHelper; diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 68a292ede6b4a..8d4ca97001d3d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,6 +63,13 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList"> + <arguments> + <argument name="formats" xsi:type="array"> + <item name="html" xsi:type="string">Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html</item> + </argument> + </arguments> + </type> <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="customFilters" xsi:type="array"> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a9c4a1b4bd8ae..3f3282ed5f529 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -552,9 +552,9 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextareaAttribute { +type ProductTextAttribute { content ( - format: String! @doc(description: "The format of content") -): String - @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") + format: String @doc(description: "The format of content") +): String @doc(description: "The format of content") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") } From e327bb695bf2cb01240d5d442d5d269fb3c50064 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 22 Sep 2018 15:18:18 +0000 Subject: [PATCH 0184/1415] graphQl: shipping address concept Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../SetShippingAddressesOnCart.php | 104 ++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..9d54792136367 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; + +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\ShippingAddressManagementInterface; + +/** + * @inheritdoc + */ +class SetShippingAddressesOnCart implements ResolverInterface +{ + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + + /** + * @var Address + */ + private $addressModel; + /** + * @var DataObjectHelper + */ + private $dataObjectHelper; + + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param AddressRepositoryInterface $addressRepository + * @param Address $addressModel + * @param DataObjectHelper $dataObjectHelper + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + */ + public function __construct( + ShippingAddressManagementInterface $shippingAddressManagement, + AddressRepositoryInterface $addressRepository, + Address $addressModel, + DataObjectHelper $dataObjectHelper, + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + ) { + $this->shippingAddressManagement = $shippingAddressManagement; + $this->addressRepository = $addressRepository; + $this->addressModel = $addressModel; + $this->dataObjectHelper = $dataObjectHelper; + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($args['input']['cart_id'])) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + $maskedCartId = $args['input']['cart_id']; + $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); + + $customerAddressId = $args['input']['customer_address_id'] ?? 0; + $address = $args['input']['address'] ?? null; + $cartItems = $args['input']['cart_items'] ?? []; + + if (!$customerAddressId && !$address) { + throw new GraphQlInputException(__('Query should contain either address id or address input.')); + } + + if (!$cartItems) { + if($customerAddressId) { + $customerAddress = $this->addressRepository->getById($customerAddressId); + $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } else { + $shippingAddress = $this->addressModel->addData($address); + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } + } else { + //TODO: implement multi shipping address assign flow + } + + return []; + } +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index b10575171781e..d13240a23140b 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -9,7 +9,7 @@ type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddress\\SetShippingAddressesOnCart") setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput } From 765f88f0359dbd689a2b662f3c5a76f91a839e52 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 10 Sep 2018 10:12:55 +0300 Subject: [PATCH 0185/1415] Fixes saving product in single-store mode if website_id <> 1 --- app/code/Magento/Catalog/Model/Product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index b29eee9a47f8b..9907ce9de1f8d 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -810,7 +810,7 @@ public function getStoreIds() if (!$this->hasStoreIds()) { $storeIds = []; if ($websiteIds = $this->getWebsiteIds()) { - foreach ($websiteIds as $websiteId) { + foreach ($websiteIds as $websiteId => $selectedId) { $websiteStores = $this->_storeManager->getWebsite($websiteId)->getStoreIds(); $storeIds = array_merge($storeIds, $websiteStores); } From 558d5279f200d4e9753aae715f2d7f4f44a0d5c4 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 10 Sep 2018 12:56:30 +0300 Subject: [PATCH 0186/1415] Refactored the website_ids array --- app/code/Magento/Catalog/Model/Product.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 9907ce9de1f8d..e14cde3e692b9 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -810,7 +810,8 @@ public function getStoreIds() if (!$this->hasStoreIds()) { $storeIds = []; if ($websiteIds = $this->getWebsiteIds()) { - foreach ($websiteIds as $websiteId => $selectedId) { + $websiteIds = array_keys($websiteIds); + foreach ($websiteIds as $websiteId) { $websiteStores = $this->_storeManager->getWebsite($websiteId)->getStoreIds(); $storeIds = array_merge($storeIds, $websiteStores); } From deebbc08e59a7eec5b6c5b3a013291330a194126 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 10 Sep 2018 17:36:05 +0300 Subject: [PATCH 0187/1415] Applying the changes only for single store mode --- app/code/Magento/Catalog/Model/Product.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index e14cde3e692b9..223db01351d66 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -810,7 +810,9 @@ public function getStoreIds() if (!$this->hasStoreIds()) { $storeIds = []; if ($websiteIds = $this->getWebsiteIds()) { - $websiteIds = array_keys($websiteIds); + if ($this->_storeManager->isSingleStoreMode()) { + $websiteIds = array_keys($websiteIds); + } foreach ($websiteIds as $websiteId) { $websiteStores = $this->_storeManager->getWebsite($websiteId)->getStoreIds(); $storeIds = array_merge($storeIds, $websiteStores); From 3ec2f751b69da562d5b47f0e81310756eb4dbe32 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 24 Sep 2018 14:23:29 +0300 Subject: [PATCH 0188/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Fix static tests --- app/code/Magento/Sales/Model/Order.php | 20 ++- .../Magento/Sales/Model/Order/Creditmemo.php | 119 ++++++++++-------- 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 3c423d075be90..98b514f3a6af5 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -636,6 +636,17 @@ public function canCreditmemo() return $this->canCreditmemoForZeroTotal($totalRefunded); } + return $this->canCreditmemoForZeroTotalRefunded($totalRefunded); + } + + /** + * Retrieve credit memo for zero total refunded availability. + * + * @param float $totalRefunded + * @return bool + */ + private function canCreditmemoForZeroTotalRefunded($totalRefunded) + { $isRefundZero = abs($totalRefunded) < .0001; // Case when Adjustment Fee (adjustment_negative) has been used for first creditmemo $hasAdjustmentFee = abs($totalRefunded - $this->getAdjustmentNegative()) < .0001; @@ -646,11 +657,11 @@ public function canCreditmemo() return true; } - + /** * Retrieve credit memo for zero total availability. * - * @param $totalRefunded + * @param float $totalRefunded * @return bool */ public function canCreditmemoForZeroTotal($totalRefunded) @@ -661,7 +672,10 @@ public function canCreditmemoForZeroTotal($totalRefunded) //case when amount is due for invoice $dueAmountCondition = $this->canInvoice() && ($checkAmtTotalPaid); //case when paid amount is refunded and order has creditmemo created - $paidAmtIsRefunded = $this->getTotalRefunded() == $totalPaid && count($this->getCreditmemosCollection()) > 0; + + $creditmemos = ($this->getCreditmemosCollection() === false) ? + true : (count($this->getCreditmemosCollection()) > 0); + $paidAmtIsRefunded = $this->getTotalRefunded() == $totalPaid && $creditmemos; if (($dueAmountCondition || $paidAmtIsRefunded) || (!$checkAmtTotalPaid && abs($totalRefunded - $this->getAdjustmentNegative()) < .0001)) { diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index ec38ad9ad3ae6..20cec81240262 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -27,6 +27,7 @@ * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) * @since 100.0.2 */ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInterface @@ -147,6 +148,7 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param InvoiceFactory $invoiceFactory + * @param ScopeConfigInterface $scopeConfig * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -276,6 +278,8 @@ public function getShippingAddress() } /** + * Retrieve collection if items. + * * @return mixed */ public function getItemsCollection() @@ -291,6 +295,8 @@ public function getItemsCollection() } /** + * Retrieve all items. + * * @return \Magento\Sales\Model\Order\Creditmemo\Item[] */ public function getAllItems() @@ -305,6 +311,8 @@ public function getAllItems() } /** + * Retrieve item by id. + * * @param mixed $itemId * @return mixed */ @@ -335,6 +343,8 @@ public function getItemByOrderId($orderId) } /** + * Add an item to credit memo. + * * @param \Magento\Sales\Model\Order\Creditmemo\Item $item * @return $this */ @@ -380,6 +390,8 @@ public function roundPrice($price, $type = 'regular', $negative = false) } /** + * Check if credit memo can be refunded. + * * @return bool */ public function canRefund() @@ -477,6 +489,8 @@ public function getStateName($stateId = null) } /** + * Set shipping amount. + * * @param float $amount * @return $this */ @@ -486,6 +500,8 @@ public function setShippingAmount($amount) } /** + * Set adjustment positive amount. + * * @param string $amount * @return $this */ @@ -506,6 +522,8 @@ public function setAdjustmentPositive($amount) } /** + * Set adjustment negative amount. + * * @param string $amount * @return $this */ @@ -554,6 +572,8 @@ public function isLast() } /** + * Add comment to credit memo. + * * Adds comment to credit memo with additional possibility to send it to customer via email * and show it in customer account * @@ -580,6 +600,8 @@ public function addComment($comment, $notify = false, $visibleOnFront = false) } /** + * Retrieve collection of comments. + * * @param bool $reload * @return \Magento\Sales\Model\ResourceModel\Order\Creditmemo\Comment\Collection * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -619,6 +641,8 @@ public function getIncrementId() } /** + * Check if grand total is valid. + * * @return bool */ public function isValidGrandTotal() @@ -685,7 +709,7 @@ public function getDiscountDescription() } /** - * {@inheritdoc} + * @inheritdoc */ public function setItems($items) { @@ -925,7 +949,7 @@ public function getCreatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCreatedAt($createdAt) { @@ -1184,7 +1208,7 @@ public function getUpdatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setComments($comments) { @@ -1192,7 +1216,7 @@ public function setComments($comments) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreId($id) { @@ -1200,7 +1224,7 @@ public function setStoreId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingTaxAmount($amount) { @@ -1208,7 +1232,7 @@ public function setBaseShippingTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreToOrderRate($rate) { @@ -1216,7 +1240,7 @@ public function setStoreToOrderRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountAmount($amount) { @@ -1224,7 +1248,7 @@ public function setBaseDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseToOrderRate($rate) { @@ -1232,7 +1256,7 @@ public function setBaseToOrderRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGrandTotal($amount) { @@ -1240,7 +1264,7 @@ public function setGrandTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseSubtotalInclTax($amount) { @@ -1248,7 +1272,7 @@ public function setBaseSubtotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSubtotalInclTax($amount) { @@ -1256,7 +1280,7 @@ public function setSubtotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingAmount($amount) { @@ -1264,7 +1288,7 @@ public function setBaseShippingAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreToBaseRate($rate) { @@ -1272,7 +1296,7 @@ public function setStoreToBaseRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseToGlobalRate($rate) { @@ -1280,7 +1304,7 @@ public function setBaseToGlobalRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseAdjustment($baseAdjustment) { @@ -1288,7 +1312,7 @@ public function setBaseAdjustment($baseAdjustment) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseSubtotal($amount) { @@ -1296,7 +1320,7 @@ public function setBaseSubtotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountAmount($amount) { @@ -1304,7 +1328,7 @@ public function setDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSubtotal($amount) { @@ -1312,7 +1336,7 @@ public function setSubtotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAdjustment($adjustment) { @@ -1320,7 +1344,7 @@ public function setAdjustment($adjustment) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseGrandTotal($amount) { @@ -1328,7 +1352,7 @@ public function setBaseGrandTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxAmount($amount) { @@ -1336,7 +1360,7 @@ public function setBaseTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingTaxAmount($amount) { @@ -1344,7 +1368,7 @@ public function setShippingTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxAmount($amount) { @@ -1352,7 +1376,7 @@ public function setTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOrderId($id) { @@ -1360,7 +1384,7 @@ public function setOrderId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmailSent($emailSent) { @@ -1368,7 +1392,7 @@ public function setEmailSent($emailSent) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCreditmemoStatus($creditmemoStatus) { @@ -1376,7 +1400,7 @@ public function setCreditmemoStatus($creditmemoStatus) } /** - * {@inheritdoc} + * @inheritdoc */ public function setState($state) { @@ -1384,7 +1408,7 @@ public function setState($state) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingAddressId($id) { @@ -1392,7 +1416,7 @@ public function setShippingAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBillingAddressId($id) { @@ -1400,7 +1424,7 @@ public function setBillingAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setInvoiceId($id) { @@ -1408,7 +1432,7 @@ public function setInvoiceId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreCurrencyCode($code) { @@ -1416,7 +1440,7 @@ public function setStoreCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOrderCurrencyCode($code) { @@ -1424,7 +1448,7 @@ public function setOrderCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseCurrencyCode($code) { @@ -1432,7 +1456,7 @@ public function setBaseCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGlobalCurrencyCode($code) { @@ -1440,7 +1464,7 @@ public function setGlobalCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setIncrementId($id) { @@ -1448,7 +1472,7 @@ public function setIncrementId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setUpdatedAt($timestamp) { @@ -1456,7 +1480,7 @@ public function setUpdatedAt($timestamp) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationAmount($amount) { @@ -1464,7 +1488,7 @@ public function setDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountTaxCompensationAmount($amount) { @@ -1472,7 +1496,7 @@ public function setBaseDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingDiscountTaxCompensationAmount($amount) { @@ -1480,7 +1504,7 @@ public function setShippingDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) { @@ -1488,7 +1512,7 @@ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingInclTax($amount) { @@ -1496,7 +1520,7 @@ public function setShippingInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingInclTax($amount) { @@ -1504,7 +1528,7 @@ public function setBaseShippingInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountDescription($description) { @@ -1512,9 +1536,7 @@ public function setDiscountDescription($description) } /** - * {@inheritdoc} - * - * @return \Magento\Sales\Api\Data\CreditmemoExtensionInterface|null + * @inheritdoc */ public function getExtensionAttributes() { @@ -1522,10 +1544,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} - * - * @param \Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes - * @return $this + * @inheritdoc */ public function setExtensionAttributes(\Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes) { From 18f78d5c5b1a760813647b794e5365dfe885367e Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 24 Sep 2018 15:26:43 +0300 Subject: [PATCH 0189/1415] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Fixed an issue with incorrect work of 'Subscribe for Balance Updates' functionality; --- .../Model/Metadata/CustomerMetadata.php | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php index 7ed806e657e82..7e8f0b9236fe9 100644 --- a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php +++ b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php @@ -46,7 +46,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getAttributes($formCode) { @@ -67,7 +67,7 @@ public function getAttributes($formCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAttributeMetadata($attributeCode) { @@ -92,7 +92,7 @@ public function getAttributeMetadata($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAllAttributesMetadata() { @@ -116,7 +116,7 @@ public function getAllAttributesMetadata() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_INTERFACE_NAME) { @@ -134,13 +134,27 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN $isDataObjectMethod = isset($this->customerDataObjectMethods['get' . $camelCaseKey]) || isset($this->customerDataObjectMethods['is' . $camelCaseKey]); - /** Even though disable_auto_group_change is system attribute, it should be available to the clients */ if (!$isDataObjectMethod - && (!$attributeMetadata->isSystem() || $attributeCode == 'disable_auto_group_change') + && (!$attributeMetadata->isSystem() + || in_array($attributeCode, $this->getAllowedSystemAttributesList()) + ) ) { $customAttributes[] = $attributeMetadata; } } return $customAttributes; } + + /** + * Get list of system attributes which should be available to the clients + * + * @return array + */ + private function getAllowedSystemAttributesList() + { + return [ + 'disable_auto_group_change', + 'reward_update_notification' + ]; + } } From aef18a56e212eb0f55c5393c5a814b6bb15c9510 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Mon, 24 Sep 2018 19:04:00 +0600 Subject: [PATCH 0190/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Added automated test --- .../StorefrontCategoryActionGroup.xml | 15 +++ .../Mftf/Data/CatalogStorefrontConfigData.xml | 41 ++++++ .../Metadata/catalog_configuration-meta.xml | 118 ++++++++++++++++++ .../Section/StorefrontCategoryMainSection.xml | 3 + ...orefrontRememberCategoryPaginationTest.xml | 68 ++++++++++ 5 files changed, 245 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index c980c43b8f3af..e215aa81b3384 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -21,6 +21,21 @@ <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> + <actionGroup name="VerifyCategoryPageParameters"> + <arguments> + <argument name="category"/> + <argument name="mode" type="string"/> + <argument name="numOfProductsPerPage" type="string"/> + <argument name="sortBy" type="string" defaultValue="position"/> + </arguments> + <seeInCurrentUrl url="/{{category.custom_attributes[url_key]}}.html" stepKey="checkUrl"/> + <seeInTitle userInput="{{category.name}}" stepKey="assertCategoryNameInTitle"/> + <see userInput="{{category.name}}" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="assertCategoryName"/> + <see userInput="{{mode}}" selector="{{StorefrontCategoryMainSection.modeGridIsActive}}" stepKey="assertViewMode"/> + <see userInput="{{numOfProductsPerPage}}" selector="{{StorefrontCategoryMainSection.perPage}}" stepKey="assertNumberOfProductsPerPage"/> + <see userInput="{{sortBy}}" selector="{{StorefrontCategoryMainSection.sortedBy}}" stepKey="assertSortedBy"/> + </actionGroup> + <!-- Check the category page --> <actionGroup name="StorefrontCheckCategoryActionGroup"> <arguments> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml new file mode 100644 index 0000000000000..d8ec84013d93b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="RememberPaginationCatalogStorefrontConfig" type="catalog_storefront_config"> + <requiredEntity type="grid_per_page_values">GridPerPageValues</requiredEntity> + <requiredEntity type="remember_pagination">RememberCategoryPagination</requiredEntity> + </entity> + + <entity name="GridPerPageValues" type="grid_per_page_values"> + <data key="value">9,12,20,24</data> + </entity> + + <entity name="RememberCategoryPagination" type="remember_pagination"> + <data key="value">1</data> + </entity> + + <entity name="DefaultCatalogStorefrontConfiguration" type="default_catalog_storefront_config"> + <requiredEntity type="catalogStorefrontFlagZero">DefaultCatalogStorefrontFlagZero</requiredEntity> + <data key="list_allow_all">DefaultListAllowAll</data> + <data key="flat_catalog_product">DefaultFlatCatalogProduct</data> + </entity> + + <entity name="DefaultCatalogStorefrontFlagZero" type="catalogStorefrontFlagZero"> + <data key="value">0</data> + </entity> + + <entity name="DefaultListAllowAll" type="list_allow_all"> + <data key="value">0</data> + </entity> + + <entity name="DefaultFlatCatalogProduct" type="flat_catalog_product"> + <data key="value">0</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml new file mode 100644 index 0000000000000..b1f2b43220b36 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="CatalogStorefrontConfiguration" dataType="catalog_storefront_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/catalog/" method="POST"> + <object key="groups" dataType="catalog_storefront_config"> + <object key="frontend" dataType="catalog_storefront_config"> + <object key="fields" dataType="catalog_storefront_config"> + <object key="list_mode" dataType="list_mode"> + <field key="value">string</field> + </object> + <object key="grid_per_page_values" dataType="grid_per_page_values"> + <field key="value">string</field> + </object> + <object key="grid_per_page" dataType="grid_per_page"> + <field key="value">string</field> + </object> + <object key="list_per_page_values" dataType="list_per_page_values"> + <field key="value">string</field> + </object> + <object key="list_per_page" dataType="list_per_page"> + <field key="value">string</field> + </object> + <object key="default_sort_by" dataType="default_sort_by"> + <field key="value">string</field> + </object> + <object key="list_allow_all" dataType="list_allow_all"> + <field key="value">integer</field> + </object> + <object key="remember_pagination" dataType="remember_pagination"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_category" dataType="flat_catalog_category"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_product" dataType="flat_catalog_product"> + <field key="value">integer</field> + </object> + <object key="swatches_per_product" dataType="swatches_per_product"> + <field key="value">string</field> + </object> + <object key="show_swatches_in_product_list" dataType="show_swatches_in_product_list"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> + + <operation name="DefaultCatalogStorefrontConfiguration" dataType="default_catalog_storefront_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/catalog/" method="POST"> + <object key="groups" dataType="default_catalog_storefront_config"> + <object key="frontend" dataType="default_catalog_storefront_config"> + <object key="fields" dataType="default_catalog_storefront_config"> + <object key="list_mode" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grid_per_page_values" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grid_per_page" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_per_page_values" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_per_page" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="default_sort_by" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="remember_pagination" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="flat_catalog_category" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="swatches_per_product" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="show_swatches_in_product_list" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_allow_all" dataType="list_allow_all"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_product" dataType="flat_catalog_product"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> +</operations> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml index d484abf2069ff..03566be55ad2f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml @@ -9,6 +9,9 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontCategoryMainSection"> + <element name="perPage" type="select" selector="//*[@id='authenticationPopup']/following-sibling::div[3]//*[@id='limiter']"/> + <element name="sortedBy" type="select" selector="//*[@id='authenticationPopup']/following-sibling::div[1]//*[@id='sorter']"/> + <element name="modeGridIsActive" type="text" selector="//*[@id='authenticationPopup']/following-sibling::div[1]//*[@class='modes']/strong[@class='modes-mode active mode-grid']/span"/> <element name="modeListButton" type="button" selector="#mode-list"/> <element name="CategoryTitle" type="text" selector="#page-title-heading span"/> <element name="ProductItemInfo" type="button" selector=".product-item-info"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml new file mode 100644 index 0000000000000..0ed61b8636c4f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontRememberCategoryPaginationTest"> + <annotations> + <title value="Verify that Number of Products per page retained when visiting a different category"/> + <stories value="MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category"/> + <description value="Verify that Number of Products per page retained when visiting a different category"/> + <features value="Catalog"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94210"/> + <group value="Catalog"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="defaultCategory1"/> + <createData entity="SimpleProduct" stepKey="simpleProduct1"> + <requiredEntity createDataKey="defaultCategory1"/> + </createData> + + <createData entity="_defaultCategory" stepKey="defaultCategory2"/> + <createData entity="SimpleProduct" stepKey="simpleProduct2"> + <requiredEntity createDataKey="defaultCategory2"/> + </createData> + + <createData entity="RememberPaginationCatalogStorefrontConfig" stepKey="setRememberPaginationCatalogStorefrontConfig"/> + </before> + + <actionGroup ref="GoToStorefrontCategoryPageByParameters" stepKey="GoToStorefrontCategory1Page"> + <argument name="category" value="$$defaultCategory1.custom_attributes[url_key]$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <actionGroup ref="VerifyCategoryPageParameters" stepKey="verifyCategory1PageParameters"> + <argument name="category" value="$$defaultCategory1$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <amOnPage url="{{StorefrontCategoryPage.url($$defaultCategory2.name$$)}}" stepKey="navigateToCategory2Page"/> + <waitForPageLoad stepKey="waitForCategory2PageToLoad"/> + + <actionGroup ref="VerifyCategoryPageParameters" stepKey="verifyCategory2PageParameters"> + <argument name="category" value="$$defaultCategory2$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <after> + <createData entity="DefaultCatalogStorefrontConfiguration" stepKey="setDefaultCatalogStorefrontConfiguration"/> + + <deleteData createDataKey="simpleProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="defaultCategory1" stepKey="deleteCategory1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteProduct2"/> + <deleteData createDataKey="defaultCategory2" stepKey="deleteCategory2"/> + + <magentoCLI command="cache:flush" stepKey="flushCache"/> + + </after> + </test> +</tests> From 160f0879e39e39a6baa48723c05255c0fc37c860 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 24 Sep 2018 16:48:01 +0300 Subject: [PATCH 0191/1415] MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11 - Fix added --- lib/web/fotorama/fotorama.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/web/fotorama/fotorama.js b/lib/web/fotorama/fotorama.js index 89cb315b0d2c4..4bfa2f12d5248 100644 --- a/lib/web/fotorama/fotorama.js +++ b/lib/web/fotorama/fotorama.js @@ -2487,11 +2487,11 @@ fotoramaVersion = '4.6.4'; .append($videoPlay.clone()); // This solves tabbing problems - addFocus(frame, function () { + addFocus(frame, function (e) { setTimeout(function () { lockScroll($stage); }, 0); - clickToShow({index: frameData.eq, user: true}); + clickToShow({index: frameData.eq, user: true}, e); }); $stageFrame = $stageFrame.add($frame); @@ -3040,7 +3040,10 @@ fotoramaVersion = '4.6.4'; return time; } - that.showStage = function (silent, options, time) { + that.showStage = function (silent, options, time, e) { + if (e !== undefined && e.target.tagName == 'IFRAME') { + return; + } unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i); frameDraw(activeIndexes, 'stage'); stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]); @@ -3128,7 +3131,7 @@ fotoramaVersion = '4.6.4'; } }; - that.show = function (options) { + that.show = function (options, e) { that.longPress.singlePressInProgress = true; var index = calcActiveIndex(options); @@ -3139,7 +3142,7 @@ fotoramaVersion = '4.6.4'; var silent = _activeFrame === activeFrame && !options.user; - that.showStage(silent, options, time); + that.showStage(silent, options, time, e); that.showNav(silent, options, time); showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex; @@ -3499,7 +3502,7 @@ fotoramaVersion = '4.6.4'; $stage.on('mousemove', stageCursor); - function clickToShow(showOptions) { + function clickToShow(showOptions, e) { clearTimeout(clickToShow.t); if (opts.clicktransition && opts.clicktransition !== opts.transition) { @@ -3516,7 +3519,7 @@ fotoramaVersion = '4.6.4'; }, 10); }, 0); } else { - that.show(showOptions); + that.show(showOptions, e); } } From b4bb58cfd3e0c33c96b4100ea84ba30197ad7c23 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 24 Sep 2018 16:59:40 +0300 Subject: [PATCH 0192/1415] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Added new validation rule for percentage value; --- .../Product/Form/Modifier/TierPrice.php | 4 +--- .../view/base/web/js/lib/validation/rules.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 5f8d7fcf9049a..1f0da62f61056 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -154,9 +154,7 @@ private function getUpdatedTierPriceStructure(array $priceMeta) 'addbefore' => '%', 'validation' => [ 'required-entry' => true, - 'validate-number' => true, - 'validate-greater-than-zero' => true, - 'less-than-equals-to' => 100 + 'validate-positive-percent-decimal' => true ], 'visible' => $firstOption && $firstOption['value'] == ProductPriceOptionsInterface::VALUE_PERCENT, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index 74f696f3f2a24..1c647bed2ea7b 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -686,6 +686,24 @@ define([ }, $.mage.__('The value is not within the specified range.') ], + 'validate-positive-percent-decimal': [ + function (value) { + var numValue; + + if (utils.isEmptyNoTrim(value) || !/^\s*-?\d*(\.\d*)?\s*$/.test(value)) { + return false; + } + + numValue = utils.parseNumber(value); + + if (isNaN(numValue)) { + return false; + } + + return utils.isBetween(numValue, 0.01, 100); + }, + $.mage.__('Please enter a valid percentage discount value greater than 0.') + ], 'validate-digits': [ function (value) { return utils.isEmptyNoTrim(value) || !/[^\d]/.test(value); From 68933c1b128f09b74298f81822879e2bee63d68a Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Mon, 24 Sep 2018 17:35:47 +0300 Subject: [PATCH 0193/1415] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Change index table and temporary table --- .../Category/Product/AbstractAction.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index 6a499883ac723..d312b78e74059 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -499,7 +499,7 @@ protected function createAnchorSelect(Store $store) 'cc2.parent_id = cc.entity_id AND cc.entity_id NOT IN (' . implode( ',', $rootCatIds - ) . ')', + ) . ') AND cc2.store_id = ' . $store->getId(), [] )->joinInner( ['ccp' => $this->getTable('catalog_category_product')], @@ -586,6 +586,8 @@ protected function createAnchorSelect(Store $store) } /** + * Get temporary table name + * * Get temporary table name for concurrent indexing in persistent connection * Temp table name is NOT shared between action instances and each action has it's own temp tree index * @@ -629,6 +631,12 @@ protected function makeTempCategoryTreeIndex() null, ['nullable' => false, 'unsigned' => true] ); + $temporaryTable->addColumn( + 'store_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true] + ); // Each entry will be unique. $temporaryTable->addIndex( 'idx_primary', @@ -642,6 +650,11 @@ protected function makeTempCategoryTreeIndex() ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] ); + $temporaryTable->addIndex( + 'store_id', + ['store_id'], + ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] + ); // Drop the temporary table in case it already exists on this (persistent?) connection. $this->connection->dropTemporaryTable($temporaryName); $this->connection->createTemporaryTable($temporaryTable); @@ -659,11 +672,23 @@ protected function makeTempCategoryTreeIndex() */ protected function fillTempCategoryTreeIndex($temporaryName) { + $isActiveAttributeId = $this->config->getAttribute( + \Magento\Catalog\Model\Category::ENTITY, + 'is_active' + )->getId(); + $categoryMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class); + $categoryLinkField = $categoryMetadata->getLinkField(); $selects = $this->prepareSelectsByRange( $this->connection->select() ->from( ['c' => $this->getTable('catalog_category_entity')], ['entity_id', 'path'] + )->joinInner( + ['ccei' => $this->getTable('catalog_category_entity_int')], + 'ccei.' . $categoryLinkField . ' = c.' . $categoryLinkField . + ' AND ccei.attribute_id = ' . $isActiveAttributeId . + ' AND ccei.value = 1', + ['store_id'] ), 'entity_id' ); @@ -674,13 +699,13 @@ protected function fillTempCategoryTreeIndex($temporaryName) foreach ($this->connection->fetchAll($select) as $category) { foreach (explode('/', $category['path']) as $parentId) { if ($parentId !== $category['entity_id']) { - $values[] = [$parentId, $category['entity_id']]; + $values[] = [$parentId, $category['entity_id'], $category['store_id']]; } } } if (count($values) > 0) { - $this->connection->insertArray($temporaryName, ['parent_id', 'child_id'], $values); + $this->connection->insertArray($temporaryName, ['parent_id', 'child_id', 'store_id'], $values); } } } From f1960f0247ef21e54942a7631abea82f1f1f3635 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 24 Sep 2018 19:41:45 +0300 Subject: [PATCH 0194/1415] MAGETWO-91753: Results of filters with color and other filters are not showing product results - CR fix --- .../Model/Search/FilterMapper/CustomAttributeFilterTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilterTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilterTest.php index 7d0f9148cd708..d92539396de58 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilterTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilterTest.php @@ -155,7 +155,6 @@ private function getSqlForOneAttributeSearch() $joinConditions = [ '`some_index`.`entity_id` = `field1_filter`.`entity_id`', - '`some_index`.`source_id` = `field1_filter`.`source_id`', sprintf('`field1_filter`.`attribute_id` = %s', $firstAttribute->getId()), sprintf('`field1_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId()) ]; @@ -182,14 +181,12 @@ private function getSqlForTwoAttributeSearch() $joinConditions1 = [ '`some_index`.`entity_id` = `field1_filter`.`entity_id`', - '`some_index`.`source_id` = `field1_filter`.`source_id`', sprintf('`field1_filter`.`attribute_id` = %s', $firstAttribute->getId()), sprintf('`field1_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId()) ]; $joinConditions2 = [ '`some_index`.`entity_id` = `field2_filter`.`entity_id`', - '`some_index`.`source_id` = `field2_filter`.`source_id`', sprintf('`field2_filter`.`attribute_id` = %s', $secondAttribute->getId()), sprintf('`field2_filter`.`store_id` = %s', (int) $this->storeManager->getStore()->getId()) ]; From bc2f6f5f25f45ad043f4daaf4882960c45f68213 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 24 Sep 2018 11:53:02 -0500 Subject: [PATCH 0195/1415] MAGETWO-90280: Could not create customer via API without store_id - fix static tests --- app/code/Magento/Customer/Model/AccountManagement.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 3d88aeaef767b..94c18b2cd56f8 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -956,6 +956,8 @@ protected function createPasswordHash($password) } /** + * Get EAV validator + * * @return Backend */ private function getEavValidator() @@ -1154,6 +1156,8 @@ protected function getWebsiteStoreId($customer, $defaultStoreId = null) } /** + * Get template types + * * @return array * @deprecated 100.1.0 */ From 5a38724d165ffd0c325d015cffaf7732834b7157 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 24 Sep 2018 20:00:27 +0300 Subject: [PATCH 0196/1415] MAGETWO-91650: Translation not working for product alerts - Add store id for product alert --- .../ProductAlert/Controller/Add/Price.php | 16 +++--- .../ProductAlert/Controller/Add/Stock.php | 28 ++++++++--- app/code/Magento/ProductAlert/Model/Email.php | 49 +++++++++++++------ .../Magento/ProductAlert/Model/Observer.php | 19 +++++++ app/code/Magento/ProductAlert/Model/Price.php | 10 ++++ app/code/Magento/ProductAlert/Model/Stock.php | 10 ++++ .../Magento/ProductAlert/etc/db_schema.xml | 16 ++++++ .../ProductAlert/etc/db_schema_whitelist.json | 20 +++++--- 8 files changed, 133 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/ProductAlert/Controller/Add/Price.php b/app/code/Magento/ProductAlert/Controller/Add/Price.php index 04e623105e645..fbaff109fd15a 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Price.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Price.php @@ -6,6 +6,7 @@ namespace Magento\ProductAlert\Controller\Add; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\ProductAlert\Controller\Add as AddController; use Magento\Framework\App\Action\Context; use Magento\Customer\Model\Session as CustomerSession; @@ -16,7 +17,10 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\NoSuchEntityException; -class Price extends AddController +/** + * Controller for notifying about price. + */ +class Price extends AddController implements HttpPostActionInterface { /** * @var \Magento\Store\Model\StoreManagerInterface @@ -62,6 +66,8 @@ protected function isInternal($url) } /** + * Method for adding info about product alert price. + * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() @@ -75,6 +81,7 @@ public function execute() return $resultRedirect; } + $store = $this->storeManager->getStore(); try { /* @var $product \Magento\Catalog\Model\Product */ $product = $this->productRepository->getById($productId); @@ -83,11 +90,8 @@ public function execute() ->setCustomerId($this->customerSession->getCustomerId()) ->setProductId($product->getId()) ->setPrice($product->getFinalPrice()) - ->setWebsiteId( - $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getWebsiteId() - ); + ->setWebsiteId($store->getWebsiteId()) + ->setStoreId($store->getId()); $model->save(); $this->messageManager->addSuccess(__('You saved the alert subscription.')); } catch (NoSuchEntityException $noEntityException) { diff --git a/app/code/Magento/ProductAlert/Controller/Add/Stock.php b/app/code/Magento/ProductAlert/Controller/Add/Stock.php index 56d052f7e11e2..24cab39d544fc 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Stock.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Stock.php @@ -6,6 +6,7 @@ namespace Magento\ProductAlert\Controller\Add; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\ProductAlert\Controller\Add as AddController; use Magento\Framework\App\Action\Context; use Magento\Customer\Model\Session as CustomerSession; @@ -13,29 +14,44 @@ use Magento\Framework\App\Action\Action; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Store\Model\StoreManagerInterface; -class Stock extends AddController +/** + * Controller for notifying about stock. + */ +class Stock extends AddController implements HttpPostActionInterface { /** * @var \Magento\Catalog\Api\ProductRepositoryInterface */ protected $productRepository; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository + * @param StoreManagerInterface|null $storeManager */ public function __construct( Context $context, CustomerSession $customerSession, - ProductRepositoryInterface $productRepository + ProductRepositoryInterface $productRepository, + StoreManagerInterface $storeManager = null ) { $this->productRepository = $productRepository; parent::__construct($context, $customerSession); + $this->storeManager = $storeManager ?: $this->_objectManager + ->get(\Magento\Store\Model\StoreManagerInterface::class); } /** + * Method for adding info about product alert stock. + * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() @@ -52,15 +68,13 @@ public function execute() try { /* @var $product \Magento\Catalog\Model\Product */ $product = $this->productRepository->getById($productId); + $store = $this->storeManager->getStore(); /** @var \Magento\ProductAlert\Model\Stock $model */ $model = $this->_objectManager->create(\Magento\ProductAlert\Model\Stock::class) ->setCustomerId($this->customerSession->getCustomerId()) ->setProductId($product->getId()) - ->setWebsiteId( - $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getWebsiteId() - ); + ->setWebsiteId($store->getWebsiteId()) + ->setStoreId($store->getId()); $model->save(); $this->messageManager->addSuccess(__('Alert subscription has been saved.')); } catch (NoSuchEntityException $noEntityException) { diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 90d9e261f97d5..18adc54c2d660 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -136,6 +136,11 @@ class Email extends AbstractModel */ protected $_customerHelper; + /** + * @var int + */ + private $storeId = null; + /** * @param Context $context * @param Registry $registry @@ -210,6 +215,18 @@ public function setWebsite(\Magento\Store\Model\Website $website) return $this; } + /** + * Set store id from product alert. + * + * @param int $storeId + * @return $this + */ + public function setStoreId(int $storeId) + { + $this->storeId = $storeId; + return $this; + } + /** * Set website id * @@ -330,29 +347,18 @@ protected function _getStockBlock() */ public function send() { - if ($this->_website === null || $this->_customer === null) { - return false; - } - - if (!$this->_website->getDefaultGroup() || !$this->_website->getDefaultGroup()->getDefaultStore()) { - return false; - } - - if (!in_array($this->_type, ['price', 'stock'])) { + if ($this->_website === null || $this->_customer === null || !$this->isExistDefaultStore()) { return false; } $products = $this->getProducts(); - if (count($products) === 0) { - return false; - } - $templateConfigPath = $this->getTemplateConfigPath(); - if (!$templateConfigPath) { + if (!in_array($this->_type, ['price', 'stock']) || count($products) === 0 || !$templateConfigPath) { return false; } - $store = $this->_website->getDefaultStore(); + $storeId = $this->storeId ?: (int) $this->_customer->getStoreId(); + $store = $this->getStore($storeId); $storeId = $store->getId(); $this->_appEmulation->startEnvironmentEmulation($storeId); @@ -438,4 +444,17 @@ private function getTemplateConfigPath(): string ? self::XML_PATH_EMAIL_PRICE_TEMPLATE : self::XML_PATH_EMAIL_STOCK_TEMPLATE; } + + /** + * Check if exists default store. + * + * @return bool + */ + private function isExistDefaultStore(): bool + { + if (!$this->_website->getDefaultGroup() || !$this->_website->getDefaultGroup()->getDefaultStore()) { + return false; + } + return true; + } } diff --git a/app/code/Magento/ProductAlert/Model/Observer.php b/app/code/Magento/ProductAlert/Model/Observer.php index 1870989f11dc7..addc61d2f49a9 100644 --- a/app/code/Magento/ProductAlert/Model/Observer.php +++ b/app/code/Magento/ProductAlert/Model/Observer.php @@ -218,6 +218,7 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email) $previousCustomer = null; $email->setWebsite($website); foreach ($collection as $alert) { + $this->setAlertStoreId($alert, $email); try { if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) { $customer = $this->customerRepository->getById($alert->getCustomerId()); @@ -311,6 +312,7 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email) $previousCustomer = null; $email->setWebsite($website); foreach ($collection as $alert) { + $this->setAlertStoreId($alert, $email); try { if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) { $customer = $this->customerRepository->getById($alert->getCustomerId()); @@ -427,4 +429,21 @@ public function process() return $this; } + + /** + * Set alert store id. + * + * @param \Magento\ProductAlert\Model\Price|\Magento\ProductAlert\Model\Stock $alert + * @param Email $email + * @return Observer + */ + private function setAlertStoreId($alert, \Magento\ProductAlert\Model\Email $email) : Observer + { + $alertStoreId = $alert->getStoreId(); + if ($alertStoreId) { + $email->setStoreId((int)$alertStoreId); + } + + return $this; + } } diff --git a/app/code/Magento/ProductAlert/Model/Price.php b/app/code/Magento/ProductAlert/Model/Price.php index 0c12b7cfb489e..ecdf4578838aa 100644 --- a/app/code/Magento/ProductAlert/Model/Price.php +++ b/app/code/Magento/ProductAlert/Model/Price.php @@ -26,6 +26,8 @@ * @method \Magento\ProductAlert\Model\Price setSendCount(int $value) * @method int getStatus() * @method \Magento\ProductAlert\Model\Price setStatus(int $value) + * @method int getStoreId() + * @method \Magento\ProductAlert\Model\Stock setStoreId(int $value) * * @author Magento Core Team <core@magentocommerce.com> * @@ -60,6 +62,8 @@ public function __construct( } /** + * Create customer collection. + * * @return void */ protected function _construct() @@ -68,6 +72,8 @@ protected function _construct() } /** + * Create customer collection. + * * @return Collection */ public function getCustomerCollection() @@ -76,6 +82,8 @@ public function getCustomerCollection() } /** + * Load by param. + * * @return $this */ public function loadByParam() @@ -87,6 +95,8 @@ public function loadByParam() } /** + * Method for deleting customer from website. + * * @param int $customerId * @param int $websiteId * @return $this diff --git a/app/code/Magento/ProductAlert/Model/Stock.php b/app/code/Magento/ProductAlert/Model/Stock.php index 4d4dea5c2fe7e..99ba95e633904 100644 --- a/app/code/Magento/ProductAlert/Model/Stock.php +++ b/app/code/Magento/ProductAlert/Model/Stock.php @@ -24,6 +24,8 @@ * @method \Magento\ProductAlert\Model\Stock setSendCount(int $value) * @method int getStatus() * @method \Magento\ProductAlert\Model\Stock setStatus(int $value) + * @method int getStoreId() + * @method \Magento\ProductAlert\Model\Stock setStoreId(int $value) * * @author Magento Core Team <core@magentocommerce.com> * @@ -58,6 +60,8 @@ public function __construct( } /** + * Class constructor. + * * @return void */ protected function _construct() @@ -66,6 +70,8 @@ protected function _construct() } /** + * Create customer collection. + * * @return Collection */ public function getCustomerCollection() @@ -74,6 +80,8 @@ public function getCustomerCollection() } /** + * Load by param. + * * @return $this */ public function loadByParam() @@ -85,6 +93,8 @@ public function loadByParam() } /** + * Method for deleting customer from website. + * * @param int $customerId * @param int $websiteId * @return $this diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index ddf8be8a37e9c..1d145482ea38f 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -18,6 +18,8 @@ comment="Price amount"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website id"/> + <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" + default="0" comment="Store id"/> <column xsi:type="timestamp" name="add_date" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Product alert add date"/> <column xsi:type="timestamp" name="last_send_date" on_update="false" nullable="true" @@ -38,6 +40,9 @@ <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID" + table="product_alert_stock" column="website_id" referenceTable="store" + referenceColumn="store_id" onDelete="CASCADE"/> <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> @@ -47,6 +52,9 @@ <index name="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> + <index name="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> + <column name="store_id"/> + </index> </table> <table name="product_alert_stock" resource="default" engine="innodb" comment="Product Alert Stock"> <column xsi:type="int" name="alert_stock_id" padding="10" unsigned="true" nullable="false" identity="true" @@ -57,6 +65,8 @@ default="0" comment="Product id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website id"/> + <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" + default="0" comment="Store id"/> <column xsi:type="timestamp" name="add_date" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Product alert add date"/> <column xsi:type="timestamp" name="send_date" on_update="false" nullable="true" @@ -71,6 +81,9 @@ <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID" + table="product_alert_stock" column="website_id" referenceTable="store" + referenceColumn="store_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> @@ -86,5 +99,8 @@ <index name="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> + <index name="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> + <column name="store_id"/> + </index> </table> </schema> diff --git a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json index 266d00e04c5bc..234e3d14876e5 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json +++ b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json @@ -9,19 +9,22 @@ "add_date": true, "last_send_date": true, "send_count": true, - "status": true + "status": true, + "store_id": true }, "index": { "PRODUCT_ALERT_PRICE_CUSTOMER_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID": true, - "PRODUCT_ALERT_PRICE_WEBSITE_ID": true + "PRODUCT_ALERT_PRICE_WEBSITE_ID": true, + "PRODUCT_ALERT_PRICE_STORE_ID": true }, "constraint": { "PRIMARY": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, + "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true } }, "product_alert_stock": { @@ -33,19 +36,22 @@ "add_date": true, "send_date": true, "send_count": true, - "status": true + "status": true, + "store_id": true }, "index": { "PRODUCT_ALERT_STOCK_CUSTOMER_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID": true, - "PRODUCT_ALERT_STOCK_WEBSITE_ID": true + "PRODUCT_ALERT_STOCK_WEBSITE_ID": true, + "PRODUCT_ALERT_STOCK_STORE_ID": true }, "constraint": { "PRIMARY": true, "PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, + "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true } } -} \ No newline at end of file +} From 56f0c1b18ddf0e5afd2f32a4d23c2e679f33727a Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Mon, 24 Sep 2018 16:17:12 -0500 Subject: [PATCH 0197/1415] MAGETWO-87333: Broken Mainline Test Magento\Paypal\Controller\ExpressTest::testReturnAction - Unskip test to validate stability on Jenkins --- .../testsuite/Magento/Paypal/Controller/ExpressTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php index 3d30f8366598a..157999224d7b8 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php @@ -140,12 +140,11 @@ public function testStartActionCustomerToQuote() /** * Test return action with configurable product. + * + * @magentoDataFixture Magento/Paypal/_files/quote_express_configurable.php */ public function testReturnAction() { - // Skipped due to MAGETWO-87333 - //@magentoDataFixture Magento/Paypal/_files/quote_express_configurable.php - $this->markTestSkipped('MAGETWO-87333'); $quote = $this->_objectManager->create(Quote::class); $quote->load('test_cart_with_configurable', 'reserved_order_id'); From 2034958405344006414e44804b914dd4cbdb9e46 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 25 Sep 2018 12:58:19 +0400 Subject: [PATCH 0198/1415] MAGETWO-91628: Bundle product price doubled when switching currency - Add automation test --- ...tAddProductToCartFromBundleActionGroup.xml | 24 ++++++ .../Mftf/Section/StorefrontBundledSection.xml | 5 +- ...urrencyChangingBundleProductInCartTest.xml | 77 +++++++++++++++++++ .../Mftf/Page/ConfigCurrencySetupPage.xml | 13 ++++ .../Mftf/Section/CurrencySetupSection.xml | 14 ++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml create mode 100644 app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml new file mode 100644 index 0000000000000..441303e8f1b84 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup"> + <arguments> + <argument name="product"/> + <argument name="currency" type="string" defaultValue="US Dollar"/> + </arguments> + <click selector="{{StorefrontBundledSection.currencyTrigger}}" stepKey="openCurrencyTrigger"/> + <click selector="{{StorefrontBundledSection.currency(currency)}}" stepKey="chooseCurrency"/> + <click selector="{{StorefrontBundledSection.addToCart}}" stepKey="clickCustomize"/> + <waitForPageLoad stepKey="waitForBundleOpen"/> + <checkOption selector="{{StorefrontBundledSection.productInBundle(product.name)}}" stepKey="chooseProduct"/> + <click selector="{{StorefrontBundledSection.addToCartConfigured}}" stepKey="addToCartProduct"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml index f724f9bbfe1bd..5646ecf812a3f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontBundledSection"> <element name="nthBundledOption" type="input" selector=".option:nth-of-type({{numOption}}) .choice:nth-of-type({{numOptionSelect}}) input" parameterized="true"/> <element name="addToCart" type="button" selector="#bundle-slide" timeout="30"/> @@ -24,10 +24,13 @@ <element name="bundleProductName" type="text" selector="//*[@id='maincontent']//span[@itemprop='name']"/> <element name="pageNotFound" type="text" selector="//h1[@class='page-title']//span[contains(., 'Whoops, our bad...')]"/> <element name="dropDownOptionOneProducts" type="select" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//select" parameterized="true"/> + <element name="productInBundle" type="select" selector="//label//span[contains(text(), '{{productName}}')]" parameterized="true"/> <element name="dropDownOptionOneQuantity" type="input" selector="//span[contains(text(), '{{productName}}')]/../..//input" parameterized="true"/> <element name="radioButtonOptionTwoProducts" type="checkbox" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field choice'][{{productNumber}}]/input" parameterized="true"/> <element name="radioButtonOptionTwoQuantity" type="input" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field qty qty-holder']//input" parameterized="true"/> <element name="checkboxOptionThreeProducts" type="checkbox" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field choice'][{{productNumber}}]/input" parameterized="true"/> <element name="multiselectOptionFourProducts" type="multiselect" selector="//label//span[contains(text(), '{{productName}}')]/../..//select[@multiple='multiple']" parameterized="true"/> + <element name="currencyTrigger" type="select" selector="#switcher-currency-trigger" timeout="30"/> + <element name="currency" type="select" selector="//a[text()='{{arg}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml new file mode 100644 index 0000000000000..b7e716dc15ece --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CurrencyChangingBundleProductInCartTest"> + <annotations> + <features value="Bundle"/> + <stories value="Check that after changing currency price of cart is correct when the bundle product added to the cart"/> + <title value="User should be able change the currency and get right price in cart when the bundle product added to the cart"/> + <description value="User should be able change the currency and add one more product in cart and get right price in previous currency"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94467"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <!-- Delete the bundled product --> + <actionGroup stepKey="deleteBundle" ref="deleteProductUsingProductGrid"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <!--Clear Configs--> + <amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdmin"/> + <waitForPageLoad stepKey="waitForAdminLoginPageLoad"/> + <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> + <waitForPageLoad stepKey="waitForConfigCurrencySetupPageForUnselectEuroCurrency"/> + <unselectOption selector="{{CurrencySetupSection.allowCurrencies}}" userInput="Euro" stepKey="unselectEuro"/> + <click stepKey="saveUnselectedConfigs" selector="{{AdminConfigSection.saveButton}}"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="logout"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage"/> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + <actionGroup ref="fillMainBundleProductForm" stepKey="fillMainFieldsForBundle"/> + <!-- Add Option, a "Radio Buttons" type option --> + <actionGroup ref="addBundleOptionWithTwoProducts" stepKey="addBundleOptionWithTwoProducts2"> + <argument name="x" value="0"/> + <argument name="n" value="1"/> + <argument name="prodOneSku" value="$$simpleProduct1.sku$$"/> + <argument name="prodTwoSku" value="$$simpleProduct2.sku$$"/> + <argument name="optionTitle" value="Option"/> + <argument name="inputType" value="radio"/> + </actionGroup> + <checkOption selector="{{AdminProductFormBundleSection.userDefinedQuantity('0', '0')}}" stepKey="userDefinedQuantitiyOptionProduct0"/> + <checkOption selector="{{AdminProductFormBundleSection.userDefinedQuantity('0', '1')}}" stepKey="userDefinedQuantitiyOptionProduct1"/> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> + <waitForPageLoad stepKey="waitForConfigCurrencySetupPage"/> + <selectOption selector="{{CurrencySetupSection.allowCurrencies}}" parameterArray="['Euro', 'US Dollar']" stepKey="selectCurrencies"/> + <click stepKey="saveConfigs" selector="{{AdminConfigSection.saveButton}}"/> + <!-- Go to storefront BundleProduct --> + <amOnPage url="{{BundleProduct.sku}}.html" stepKey="goToStorefront"/> + <waitForPageLoad stepKey="waitForStorefront"/> + <actionGroup ref="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup" stepKey="addProduct1ToCartAndChangeCurrencyToEuro"> + <argument name="product" value="$$simpleProduct1$$"/> + <argument name="currency" value="EUR - Euro"/> + </actionGroup> + <actionGroup ref="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup" stepKey="addProduct2ToCartAndChangeCurrencyToUSD"> + <argument name="product" value="$$simpleProduct2$$"/> + <argument name="currency" value="USD - US Dollar"/> + </actionGroup> + <click stepKey="openMiniCart" selector="{{StorefrontMinicartSection.showCart}}"/> + <waitForPageLoad stepKey="waitForMiniCart"/> + <see stepKey="seeCartSubtotal" userInput="$12,300.00"/> + </test> +</tests> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml new file mode 100644 index 0000000000000..f523cb58d3bb6 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="ConfigCurrencySetupPage" url="admin/system_config/edit/section/currency" area="admin" module="Magento_Config"> + </page> +</pages> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml new file mode 100644 index 0000000000000..16101409ad7e8 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CurrencySetupSection"> + <element name="allowCurrencies" type="select" selector="#currency_options_allow"/> + </section> +</sections> \ No newline at end of file From 25cedef8c15ead70195ec7117f4995fbcd5bddf2 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 25 Sep 2018 13:03:19 +0400 Subject: [PATCH 0199/1415] MAGETWO-91628: Bundle product price doubled when switching currency - Revert xsi --- .../Bundle/Test/Mftf/Section/StorefrontBundledSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml index 5646ecf812a3f..ad74cfff54bd9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="StorefrontBundledSection"> <element name="nthBundledOption" type="input" selector=".option:nth-of-type({{numOption}}) .choice:nth-of-type({{numOptionSelect}}) input" parameterized="true"/> <element name="addToCart" type="button" selector="#bundle-slide" timeout="30"/> From d447ad902a61a3ef6b4b1f2303edfee479d1112e Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 25 Sep 2018 15:29:09 +0400 Subject: [PATCH 0200/1415] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Add automated test --- .../Section/AdminCategoryContentSection.xml | 1 + .../AdminCategoryDisplaySettingsSection.xml | 15 ++ .../AdminCreateBlockWithWidgetActionGroup.xml | 49 ++++++ .../Mftf/Section/CatalogWidgetSection.xml | 25 +++ .../CatalogProductListWidgetOperatorsTest.xml | 156 ++++++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml index 59537274f23c9..742ff4760eada 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml @@ -15,5 +15,6 @@ <element name="uploadImageFile" type="input" selector=".file-uploader-area>input"/> <element name="imageFileName" type="text" selector=".file-uploader-filename"/> <element name="removeImageButton" type="button" selector=".file-uploader-summary .action-remove"/> + <element name="AddCMSBlock" type="select" selector="//*[@name='landing_page']"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml new file mode 100644 index 0000000000000..daa00eb0a27b7 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCategoryDisplaySettingsSection"> + <element name="settingsHeader" type="button" selector="//*[contains(text(),'Display Settings')]" timeout="30"/> + <element name="displayMode" type="button" selector="//*[@name='display_mode']"/> + </section> +</sections> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml b/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml new file mode 100644 index 0000000000000..1f54ff40283b1 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateBlockWithWidget"> + <arguments> + <argument name="addCondition" type="string"/> + <argument name="isCondition" type="string"/> + <argument name="fieldCondition" type="string"/> + </arguments> + + <click stepKey="clickShowHideButton" selector="{{BlockWYSIWYGSection.ShowHideBtn}}"/> + <waitForElementVisible stepKey="waitForInsertWidgetButton" selector="{{CatalogWidgetSection.insertWidgetButton}}"/> + + <selectOption stepKey="selectAllStoreView" userInput="All Store Views" selector="{{CatalogWidgetSection.storeViewOption}}"/> + <fillField selector="{{BlockContentSection.TextArea}}" userInput="" stepKey="makeContentFieldEmpty"/> + + <click selector="{{CatalogWidgetSection.insertWidgetButton}}" stepKey="clickInsertWidgetButton"/> + <waitForElementVisible stepKey="waitForInsertWidgetFrame" selector="{{InsertWidgetSection.widgetTypeDropDown}}" time="10"/> + + <selectOption selector="{{InsertWidgetSection.widgetTypeDropDown}}" userInput="Catalog Products List" stepKey="selectCatalogProductListOption"/> + <waitForElementVisible stepKey="waitForConditionsElementBecomeAvailable" selector="{{InsertWidgetSection.conditionsAddButton}}"/> + + <click selector="{{InsertWidgetSection.conditionsAddButton}}" stepKey="clickToAddCondition"/> + <waitForElementVisible stepKey="waitForSelectBoxOpened" selector="{{InsertWidgetSection.conditionsSelectBox}}"/> + + <selectOption selector="{{InsertWidgetSection.conditionsSelectBox}}" userInput="{{addCondition}}" stepKey="selectConditionsSelectBox"/> + <waitForElementVisible stepKey="seeConditionsAdded" selector="{{InsertWidgetSection.addCondition('1')}}"/> + + <click selector="{{InsertWidgetSection.conditionIs}}" stepKey="clickToConditionIs"/> + <selectOption selector="{{InsertWidgetSection.conditionOperator('1')}}" stepKey="selectOperatorGreaterThan" userInput="{{isCondition}}"/> + + <click selector="{{InsertWidgetSection.addCondition('1')}}" stepKey="clickAddConditionItem"/> + <waitForElementVisible stepKey="waitForConditionFieldOpened" selector="{{InsertWidgetSection.conditionField('1')}}"/> + + <fillField selector="{{InsertWidgetSection.conditionField('1')}}" stepKey="setOperator" userInput="{{fieldCondition}}"/> + <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget"/> + + <waitForElementVisible stepKey="waitForInsertWidgetSaved" selector="{{InsertWidgetSection.save}}"/> + <click stepKey="clickSaveButton" selector="{{InsertWidgetSection.save}}"/> + <see userInput="You saved the block." stepKey="seeSavedBlockMsgOnForm"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml new file mode 100644 index 0000000000000..2957cfdfe6f43 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CatalogWidgetSection"> + <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin"/> + <element name="storeViewOption" type="button" selector="//*[@name='store_id']"/> + </section> + + <section name="InsertWidgetSection"> + <element name="widgetTypeDropDown" type="select" selector="#select_widget_type"/> + <element name="conditionsAddButton" type="button" selector=".rule-param.rule-param-new-child"/> + <element name="conditionsSelectBox" type="button" selector="#conditions__1__new_child"/> + <element name="addCondition" type="button" selector="//*[@id='conditions__1--{{arg1}}__value']/../preceding-sibling::a" parameterized="true"/> + <element name="conditionField" type="button" selector="#conditions__1--{{arg2}}__value" parameterized="true"/> + <element name="save" type="button" selector="#save-button"/> + <element name="conditionIs" type="button" selector="//*[@id='conditions__1--1__attribute']/following-sibling::span[1]"/> + <element name="conditionOperator" type="button" selector="#conditions__1--{{arg3}}__operator" parameterized="true"/> + <element name="checkElementStorefrontByPrice" type="button" selector="//*[@class='product-items widget-product-grid']//*[contains(text(),'${{arg4}}.00')]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml new file mode 100644 index 0000000000000..53a4ccb608a6d --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CatalogProductListWidgetOperatorsTest"> + <annotations> + <features value="CatalogWidget"/> + <stories value="MAGETWO-91609: Problems with operator more/less in the 'catalog Products List' widget"/> + <title value="Checking operator more/less in the 'catalog Products List' widget"/> + <description value="Check 'less than', 'equals or greater than', 'equals or less than' operators"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94479"/> + <group value="CatalogWidget"/> + </annotations> + + <before> + <createData entity="SimpleSubCategory" stepKey="simplecategory"/> + <createData entity="SimpleProduct" stepKey="createFirstProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">10</field> + </createData> + <createData entity="SimpleProduct" stepKey="createSecondProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">50</field> + </createData> + <createData entity="SimpleProduct" stepKey="createThirdProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">100</field> + </createData> + + <createData entity="_defaultBlock" stepKey="createPreReqBlock"/> + <!--User log in on back-end as admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + </before> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage1"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidget"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="greater than"/> + <argument name="fieldCondition" value="20"/> + </actionGroup> + + <!--Go to Catalog > Categories (choose category where created products)--> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryIndexPage"/> + <waitForPageLoad stepKey="waitForCategoryPageLoadAddProducts" after="onCategoryIndexPage"/> + <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickExpandAll" after="waitForCategoryPageLoadAddProducts"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickCategoryLink"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + + <!--Content > Add CMS Block: name saved block--> + <waitForElementVisible selector="{{AdminCategoryContentSection.sectionHeader}}" stepKey="waitForContentSection"/> + <conditionalClick selector="{{AdminCategoryContentSection.sectionHeader}}" dependentSelector="{{AdminCategoryContentSection.uploadButton}}" visible="false" stepKey="openContentSection"/> + <waitForPageLoad stepKey="waitForContentLoad"/> + + <selectOption selector="{{AdminCategoryContentSection.AddCMSBlock}}" stepKey="selectSavedBlock" userInput="{{_defaultBlock.title}}"/> + + <!--Display Settings > Display Mode: Static block only--> + <waitForElementVisible selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" stepKey="waitForDisplaySettingsSection"/> + <conditionalClick selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" dependentSelector="{{AdminCategoryDisplaySettingsSection.displayMode}}" visible="false" stepKey="openDisplaySettingsSection"/> + <waitForPageLoad stepKey="waitForDisplaySettingsLoad"/> + <selectOption stepKey="selectStaticBlockOnlyOption" userInput="Static block only" selector="{{AdminCategoryDisplaySettingsSection.displayMode}}"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> + <waitForPageLoad stepKey="waitForCategorySaved"/> + <see userInput="You saved the category." stepKey="seeSuccessMessage"/> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded"/> + + <!--Check operators Greater than--> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="dontSeeElementByPrice20"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="seeElementByPrice100"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage2"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetLessThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="less than"/> + <argument name="fieldCondition" value="20"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage2"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded2"/> + + <!--Check operators Greater than--> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="seeElementByPrice20"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="dontSeeElementByPrice50"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="dontSeeElementByPrice100"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage3"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetEqualsOrGreaterThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="equals or greater than"/> + <argument name="fieldCondition" value="50"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage3"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded3"/> + + <!--Check operators Greater than--> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="dontSeeElementByPrice20s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="seeElementByPrice100s"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage4"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetEqualsOrLessThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="equals or less than"/> + <argument name="fieldCondition" value="50"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage4"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded4"/> + + <!--Check operators Greater than--> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="seeElementByPrice20s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50t"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="dontSeeElementByPrice100s"/> + + <after> + <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> + <deleteData createDataKey="createPreReqBlock" stepKey="deletePreReqBlock" /> + <deleteData createDataKey="simplecategory" stepKey="deleteSimpleCategory"/> + <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createThirdProduct" stepKey="deleteThirdProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + </test> +</tests> From 99b518a6ce248fc61db7a194a05d477422d71b2e Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Tue, 25 Sep 2018 18:10:16 +0600 Subject: [PATCH 0201/1415] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Added automated test --- .../Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml index e1ec9032e072a..08623da68a8ef 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml @@ -5,8 +5,7 @@ * See COPYING.txt for license details. */ --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="CheckoutTotalsSortOrderInCartTest"> <annotations> <title value="Checkout Totals Sort Order configuration and displaying in cart"/> From 1b8cd089461f20131a8b5e5784238918138e13ae Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 25 Sep 2018 15:25:55 +0300 Subject: [PATCH 0202/1415] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Change index table and temporary table --- .../Category/Product/AbstractAction.php | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index d312b78e74059..a1358c02ce9fc 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -123,6 +123,11 @@ abstract class AbstractAction */ private $queryGenerator; + /** + * @var int + */ + private $currentStoreId = 0; + /** * @param ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -164,6 +169,7 @@ protected function reindex() { foreach ($this->storeManager->getStores() as $store) { if ($this->getPathFromCategoryId($store->getRootCategoryId())) { + $this->currentStoreId = $store->getId(); $this->reindexRootCategory($store); $this->reindexAnchorCategories($store); $this->reindexNonAnchorCategories($store); @@ -499,7 +505,7 @@ protected function createAnchorSelect(Store $store) 'cc2.parent_id = cc.entity_id AND cc.entity_id NOT IN (' . implode( ',', $rootCatIds - ) . ') AND cc2.store_id = ' . $store->getId(), + ) . ')', [] )->joinInner( ['ccp' => $this->getTable('catalog_category_product')], @@ -631,12 +637,6 @@ protected function makeTempCategoryTreeIndex() null, ['nullable' => false, 'unsigned' => true] ); - $temporaryTable->addColumn( - 'store_id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['nullable' => false, 'unsigned' => true] - ); // Each entry will be unique. $temporaryTable->addIndex( 'idx_primary', @@ -649,12 +649,6 @@ protected function makeTempCategoryTreeIndex() ['child_id'], ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] ); - - $temporaryTable->addIndex( - 'store_id', - ['store_id'], - ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] - ); // Drop the temporary table in case it already exists on this (persistent?) connection. $this->connection->dropTemporaryTable($temporaryName); $this->connection->createTemporaryTable($temporaryTable); @@ -684,11 +678,19 @@ protected function fillTempCategoryTreeIndex($temporaryName) ['c' => $this->getTable('catalog_category_entity')], ['entity_id', 'path'] )->joinInner( - ['ccei' => $this->getTable('catalog_category_entity_int')], - 'ccei.' . $categoryLinkField . ' = c.' . $categoryLinkField . - ' AND ccei.attribute_id = ' . $isActiveAttributeId . - ' AND ccei.value = 1', - ['store_id'] + ['ccacd' => $this->getTable('catalog_category_entity_int')], + 'ccacd.' . $categoryLinkField . ' = c.' . $categoryLinkField . ' AND ccacd.store_id = 0' . + ' AND ccacd.attribute_id = ' . $isActiveAttributeId, + [] + )->joinLeft( + ['ccacs' => $this->getTable('catalog_category_entity_int')], + 'ccacs.' . $categoryLinkField . ' = c.' . $categoryLinkField + . ' AND ccacs.attribute_id = ccacd.attribute_id AND ccacs.store_id = ' . + $this->currentStoreId, + [] + )->where( + $this->connection->getIfNullSql('ccacs.value', 'ccacd.value') . ' = ?', + 1 ), 'entity_id' ); @@ -699,13 +701,13 @@ protected function fillTempCategoryTreeIndex($temporaryName) foreach ($this->connection->fetchAll($select) as $category) { foreach (explode('/', $category['path']) as $parentId) { if ($parentId !== $category['entity_id']) { - $values[] = [$parentId, $category['entity_id'], $category['store_id']]; + $values[] = [$parentId, $category['entity_id']]; } } } if (count($values) > 0) { - $this->connection->insertArray($temporaryName, ['parent_id', 'child_id', 'store_id'], $values); + $this->connection->insertArray($temporaryName, ['parent_id', 'child_id'], $values); } } } From d586f100775f12196093534371b833866bd27069 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Tue, 25 Sep 2018 15:40:01 +0300 Subject: [PATCH 0203/1415] MAGETWO-95171: Filtering Category Products using scope selector --- .../ActionGroup/AdminProductActionGroup.xml | 7 +- .../AdminCategoryProductsGridSection.xml | 3 +- ...CategoryProductsUsingScopeSelectorTest.xml | 150 ++++++++++++++++++ 3 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9f8d827b20849..9c5f18c035727 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -257,11 +257,10 @@ <arguments> <argument name="website" type="string"/> </arguments> - <scrollTo selector="{{CreateProductSection.productInWebsite}}" stepKey="ScrollToWebsites"/> - <click selector="{{CreateProductSection.productInWebsite}}" stepKey="ClickTpOpenProductInWebsite"/> + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ClickTpOpenProductInWebsite"/> <waitForPageLoad stepKey="waitForPageOpened"/> - <click selector="{{CreateProductSection.isSelected(website)}}" stepKey="SelectWebsite"/> - <click selector="{{CreateProductSection.saveButton}}" stepKey="clickSaveProduct"/> + <checkOption selector="{{ProductInWebsitesSection.website(website)}}" stepKey="SelectWebsite"/> </actionGroup> <!--Switch to New Store view--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsGridSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsGridSection.xml index 6b754dcc5d482..40ea919226d6e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsGridSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsGridSection.xml @@ -14,5 +14,6 @@ <element name="rowProductSku" type="text" selector="#catalog_category_products_table tbody tr:nth-of-type({{row}}) .col-sku" parameterized="true"/> <element name="rowPrice" type="text" selector="#catalog_category_products_table tbody tr:nth-of-type({{row}}) .col-price" parameterized="true"/> <element name="rowPosition" type="input" selector="#catalog_category_products_table tbody tr:nth-of-type({{row}}) .col-position .position input" timeout="30" parameterized="true"/> + <element name="productGridNameProduct" type="text" selector="//table[@id='catalog_category_products_table']//td[contains(., '{{productName}}')]" parameterized="true"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml new file mode 100644 index 0000000000000..ddc0160d300bd --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminFilteringCategoryProductsUsingScopeSelectorTest"> + <annotations> + <features value="Catalog"/> + <group value="Catalog"/> + <title value="Filtering Category Products using scope selector"/> + <description value="Filtering Category Products using scope selector"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-48850"/> + <group value="catalog"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create website, Sore adn Store View--> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="AdminCreateWebsite"> + <argument name="newWebsiteName" value="secondWebsite"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="AdminCreateStore"> + <argument name="website" value="secondWebsite"/> + <argument name="storeGroupName" value="secondStore"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="AdminCreateStoreView"> + <argument name="StoreGroup" value="customStoreTierPrice"/> + <argument name="customStore" value="customStoreView"/> + </actionGroup> + + <!--Create Simple Product and Category --> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct0"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct1"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct2"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="_defaultProduct" stepKey="createProduct12"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Set filter to product name and product0 not assigned to any website--> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions"> + <argument name="product" value="_defaultProduct"/> + </actionGroup> + + <click selector="{{AdminProductGridSection.productGridNameProduct('$$createProduct0.name$$')}}" + stepKey="clickOpenProductForEdit"/> + <waitForPageLoad time="30" stepKey="waitForProductEditOpen"/> + + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="scrollToWebsitesSection"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="clickToOpenWebsiteSection"/> + <waitForPageLoad stepKey="waitForToOpenedWebsiteSection"/> + <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> + + <!-- Set filter to product name and product2 in website 2 only --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad time="30" stepKey="waitForProductsPageToLoad"/> + <click selector="{{AdminProductGridSection.productGridNameProduct('$$createProduct2.name$$')}}" + stepKey="clickOpenProductForEdit1"/> + <waitForPageLoad time="30" stepKey="waitForProductEditOpen1"/> + + <actionGroup ref="SelectProductInWebsitesActionGroup" stepKey="selectProductInWebsites"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite1"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct1"/> + + <!-- Set filter to product name and product12 assigned to both websites 1 and 2 --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex1"/> + <waitForPageLoad time="30" stepKey="waitForProductsPageToLoad1"/> + <click selector="{{AdminProductGridSection.productGridNameProduct('$$createProduct12.name$$')}}" + stepKey="clickOpenProductForEdit2"/> + <waitForPageLoad time="30" stepKey="waitForProductEditOpen2"/> + + <actionGroup ref="SelectProductInWebsitesActionGroup" stepKey="selectProductInWebsites1"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct2"/> + </before> + <after> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"> + <argument name="websiteName" value="secondWebsite"/> + </actionGroup> + <deleteData createDataKey="createProduct0" stepKey="deleteProduct"/> + <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="createProduct2" stepKey="deleteProduct2"/> + <deleteData createDataKey="createProduct12" stepKey="deleteProduct3"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!-- Step 1-2: Open Category page and Set scope selector to All Store Views--> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="goToCategoryPage"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree($$createCategory.name$$)}}" + stepKey="clickCategoryName"/> + <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}" + userInput="$$createProduct0.name$$" stepKey="seeProductName"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct1.name$$)}}" + userInput="$$createProduct1.name$$" stepKey="seeProductName1"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" + userInput="$$createProduct2.name$$" stepKey="seeProductName2"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" + userInput="$$createProduct12.name$$" stepKey="seeProductName3"/> + + <!-- Step 3: Set scope selector to Website1( Storeview for the Website 1) --> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewDropdownToggle}}" + stepKey="clickStoresList"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad1"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('Default Store View')}}" + stepKey="clickStoreView"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad2"/> + <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection1"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct1.name$$)}}" + userInput="$$createProduct1.name$$" stepKey="seeProductName4"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" + userInput="$$createProduct12.name$$" stepKey="seeProductName5"/> + + <!-- Step 4: Set scope selector to Website2 ( StopreView for Website 2) --> + <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewDropdownToggle}}" + stepKey="clickStoresList1"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad3"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('secondStoreView')}}" + stepKey="clickStoreView1"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="clickActionAccept1"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad4"/> + <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection2"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" + userInput="$$createProduct2.name$$" stepKey="seeProductName6"/> + <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" + userInput="$$createProduct12.name$$" stepKey="seeProductName7"/> + </test> +</tests> From ee75a796a205743ce0e8512635ad7024c98f61b8 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 25 Sep 2018 15:42:26 +0300 Subject: [PATCH 0204/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Update automation test --- .../Test/AssociatedProductToConfigurableOutOfStockTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index f0111ede64c9b..e66ad24fd54e2 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -81,7 +81,6 @@ <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> - <actionGroup ref="StorefrontSignOutActionGroup" stepKey="StorefrontSignOutActionGroup"/> </after> <!-- Login as a customer --> @@ -104,6 +103,9 @@ <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="StorefrontSignOutActionGroup"/> + <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryLoad"/> From 12634b0bc936f92ab8b37dbfec5f781e790551d7 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 25 Sep 2018 15:57:04 +0300 Subject: [PATCH 0205/1415] MAGETWO-95137: [2.3] Return path e-mail variable system/smtp/return_path_email doesn't work --- app/code/Magento/Email/Model/Transport.php | 44 ++++++++++++++-------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Email/Model/Transport.php b/app/code/Magento/Email/Model/Transport.php index 5a4d64e6d6c0e..c270c3086cca9 100644 --- a/app/code/Magento/Email/Model/Transport.php +++ b/app/code/Magento/Email/Model/Transport.php @@ -31,6 +31,23 @@ class Transport implements TransportInterface */ const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email'; + /** + * Configuration of whether return path should be set or no. + * + * Possible values are: + * 0 - no + * 1 - yes (set value as FROM address) + * 2 - use custom value + * + * @var int + */ + private $isSetReturnPath; + + /** + * @var string|null + */ + private $returnPathValue; + /** * @var Sendmail */ @@ -51,25 +68,15 @@ public function __construct( ScopeConfigInterface $scopeConfig, $parameters = null ) { - /* configuration of whether return path should be set or no. Possible values are: - * 0 - no - * 1 - yes (set value as FROM address) - * 2 - use custom value - * @see Magento\Config\Model\Config\Source\Yesnocustom - */ - $isSetReturnPath = $scopeConfig->getValue( + $this->isSetReturnPath = (int) $scopeConfig->getValue( self::XML_PATH_SENDING_SET_RETURN_PATH, ScopeInterface::SCOPE_STORE ); - $returnPathValue = $scopeConfig->getValue( + $this->returnPathValue = $scopeConfig->getValue( self::XML_PATH_SENDING_RETURN_PATH_EMAIL, ScopeInterface::SCOPE_STORE ); - if ($isSetReturnPath == '2' && $returnPathValue !== null) { - $parameters .= ' -f' . \escapeshellarg($returnPathValue); - } - $this->zendTransport = new Sendmail($parameters); $this->message = $message; } @@ -80,9 +87,16 @@ public function __construct( public function sendMessage() { try { - $this->zendTransport->send( - Message::fromString($this->message->getRawMessage()) - ); + $zendMessage = Message::fromString($this->message->getRawMessage()); + if (2 === $this->isSetReturnPath && $this->returnPathValue) { + $zendMessage->setSender($this->returnPathValue); + } elseif (1 === $this->isSetReturnPath && $zendMessage->getFrom()->count()) { + $fromAddressList = $zendMessage->getFrom(); + $fromAddressList->rewind(); + $zendMessage->setSender($fromAddressList->current()->getEmail()); + } + + $this->zendTransport->send($zendMessage); } catch (\Exception $e) { throw new MailException(new Phrase($e->getMessage()), $e); } From ca3f8ba315ec2c810ee077ba1bacf7bcf371026a Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 25 Sep 2018 17:07:29 +0300 Subject: [PATCH 0206/1415] MAGETWO-91628: Bundle product price doubled when switching currency - Fixed unit tests; --- .../Bundle/Test/Unit/Model/Product/TypeTest.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php index 4bbf5641c55d3..9819abf62a273 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php @@ -513,10 +513,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('getSelectionId') ->willReturn(314); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals([$product, $productType], $result); } @@ -737,10 +733,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('prepareForCart') ->willReturn([]); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals('We can\'t add this item to your shopping cart right now.', $result); } @@ -961,10 +953,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('prepareForCart') ->willReturn('string'); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals('string', $result); } From 0b0b141e1bc28f1264b9d1bc9d8244b66d113e77 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 09:49:48 -0500 Subject: [PATCH 0207/1415] MAGETWO-94962: Unable to set default option for swatch attribute - using json serializer to serialize options to not change behavior --- .../Catalog/view/adminhtml/web/js/options.js | 16 ++++------------ .../view/adminhtml/web/js/product-attributes.js | 5 +++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 7c35993670444..563d410a11383 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -187,19 +187,11 @@ define([ if (optionPanel.hasClass(activePanelClass)) { optionContainer.find('input') - .each(function () { - if (this.disabled) { - return; - } - - if (this.type === 'checkbox' || this.type === 'radio') { - if (this.checked) { - optionsValues.push(this.name + '=' + jQuery(this).val()); - } - } else { - optionsValues.push(this.name + '=' + jQuery(this).val()); - } + .serializeArray() + .map(function (el) { + swatchValues.push(el.name + '=' + el.value); }); + jQuery('<input>') .attr({ type: 'hidden', diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index d0eacc94e2c32..af31e48180793 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -447,8 +447,9 @@ define([ if (activePanel.hasClass(activePanelClass)) { optionContainer .find('input') - .each(function () { - swatchValues.push(this.name + '=' + $(this).val()); + .serializeArray() + .map(function (el) { + swatchValues.push(el.name + '=' + el.value); }); $('<input>') From b7264dfc698df3536f82c5403fea685169b71226 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 25 Sep 2018 18:18:27 +0300 Subject: [PATCH 0208/1415] MAGETWO-91596: Making order in admin with grouped product by adding it by sku with empty qty field leads to unability to order - Add automated test --- .../AdminOrderFormItemsOrderedSection.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml new file mode 100644 index 0000000000000..11673f1f0fe26 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderFormItemsOrderedSection"> + <element name="addProductsBySku" type="button" selector="//section[@id='order-items']//span[contains(text(),'Add Products By SKU')]"/> + <element name="configureButtonBySku" type="button" selector="//div[@class='sku-configure-button']//span[contains(text(),'Configure')]"/> + <element name="configureProductOk" type="button" selector="//div[@class='page-main-actions']//span[contains(text(),'OK')]"/> + <element name="configureProductQtyField" type="input" selector="//*[@id='super-product-table']/tbody/tr[{{arg}}]/td[5]/input[1]" parameterized="true"/> + <element name="addProductToOrder" type="input" selector="//*[@title='Add Products to Order']"/> + <element name="itemsOrderedSummaryText" type="textarea" selector="//table[@class='data-table admin__table-primary order-tables']/tfoot/tr"/> + </section> +</sections> \ No newline at end of file From f90a8bd78ab269fcf7d3e1125a4778daeb37086b Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 10:35:13 -0500 Subject: [PATCH 0209/1415] MAGETWO-94962: Unable to set default option for swatch attribute - using improved selector for form elements --- app/code/Magento/Catalog/view/adminhtml/web/js/options.js | 2 +- .../Swatches/view/adminhtml/web/js/product-attributes.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 563d410a11383..b140ea3ea32e3 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -186,7 +186,7 @@ define([ optionContainer = optionPanel.find('table tbody'); if (optionPanel.hasClass(activePanelClass)) { - optionContainer.find('input') + optionContainer.find('input,select,textarea') .serializeArray() .map(function (el) { swatchValues.push(el.name + '=' + el.value); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index af31e48180793..daa73ea7bce79 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -446,7 +446,7 @@ define([ if (activePanel.hasClass(activePanelClass)) { optionContainer - .find('input') + .find('input,select,textarea') .serializeArray() .map(function (el) { swatchValues.push(el.name + '=' + el.value); From 187c51a134a736883e78505bb0923259f3ed3daa Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 12:40:46 -0500 Subject: [PATCH 0210/1415] MAGETWO-94962: Unable to set default option for swatch attribute - fix copy paste variable usage --- app/code/Magento/Catalog/view/adminhtml/web/js/options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index b140ea3ea32e3..dd49be74e6808 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -189,7 +189,7 @@ define([ optionContainer.find('input,select,textarea') .serializeArray() .map(function (el) { - swatchValues.push(el.name + '=' + el.value); + optionsValues.push(el.name + '=' + el.value); }); jQuery('<input>') From 3aec1d71b23328e62b07bdb58ea22d6476bc2599 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 25 Sep 2018 16:35:51 -0500 Subject: [PATCH 0211/1415] MC-4259: Fix Skipped MTF Test CreateWidgetHierarchyNodeLinkTestVariation2_0 - remove page override and update selector to be compatible with core & PB pages --- .../functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml index 22d29eae1656b..1a7adcd531c55 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml @@ -7,6 +7,6 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CmsPage" mca="cms/page" module="Magento_Cms"> - <block name="cmsPageBlock" class="Magento\Cms\Test\Block\Page" locator=".page-main" strategy="css selector" /> + <block name="cmsPageBlock" class="Magento\Cms\Test\Block\Page" locator="#maincontent" strategy="css selector" /> </page> </config> From 073ca97b102143b1ea13bb4a910eb1d426ee78bb Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Tue, 25 Sep 2018 16:37:26 -0500 Subject: [PATCH 0212/1415] MAGETWO-95035: Multi-master splitting works for the core tables (created through declarative schema) but not for tables created with setup scripts --- app/code/Magento/SalesRule/etc/db_schema.xml | 4 ++-- app/code/Magento/Tax/etc/db_schema.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/SalesRule/etc/db_schema.xml b/app/code/Magento/SalesRule/etc/db_schema.xml index 3d882ee2eae67..cdbd50c3f3472 100644 --- a/app/code/Magento/SalesRule/etc/db_schema.xml +++ b/app/code/Magento/SalesRule/etc/db_schema.xml @@ -198,7 +198,7 @@ <column name="attribute_id"/> </index> </table> - <table name="salesrule_coupon_aggregated" resource="default" engine="innodb" comment="Coupon Aggregated"> + <table name="salesrule_coupon_aggregated" resource="sales" engine="innodb" comment="Coupon Aggregated"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Id"/> <column xsi:type="date" name="period" nullable="false" comment="Period"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" @@ -239,7 +239,7 @@ <column name="rule_name"/> </index> </table> - <table name="salesrule_coupon_aggregated_updated" resource="default" engine="innodb" + <table name="salesrule_coupon_aggregated_updated" resource="sales" engine="innodb" comment="Salesrule Coupon Aggregated Updated"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Id"/> <column xsi:type="date" name="period" nullable="false" comment="Period"/> diff --git a/app/code/Magento/Tax/etc/db_schema.xml b/app/code/Magento/Tax/etc/db_schema.xml index 6cc4041f75a6d..6e83a64791969 100644 --- a/app/code/Magento/Tax/etc/db_schema.xml +++ b/app/code/Magento/Tax/etc/db_schema.xml @@ -139,7 +139,7 @@ <column name="store_id"/> </index> </table> - <table name="tax_order_aggregated_created" resource="default" engine="innodb" comment="Tax Order Aggregation"> + <table name="tax_order_aggregated_created" resource="sales" engine="innodb" comment="Tax Order Aggregation"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Id"/> <column xsi:type="date" name="period" comment="Period"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" @@ -168,7 +168,7 @@ <column name="store_id"/> </index> </table> - <table name="tax_order_aggregated_updated" resource="default" engine="innodb" + <table name="tax_order_aggregated_updated" resource="sales" engine="innodb" comment="Tax Order Aggregated Updated"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Id"/> <column xsi:type="date" name="period" comment="Period"/> From b6dd9b34143499b09b2a022a9d75e8fe9ea1a274 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Wed, 26 Sep 2018 11:53:22 +0300 Subject: [PATCH 0213/1415] MAGETWO-95171: Filtering Category Products using scope selector --- .../Mftf/ActionGroup/AdminProductActionGroup.xml | 6 +++--- ...eringCategoryProductsUsingScopeSelectorTest.xml | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9c5f18c035727..82f75a76bc252 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -257,10 +257,10 @@ <arguments> <argument name="website" type="string"/> </arguments> - <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/> - <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ClickTpOpenProductInWebsite"/> + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="scrollToWebsites"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="clickTpOpenProductInWebsite"/> <waitForPageLoad stepKey="waitForPageOpened"/> - <checkOption selector="{{ProductInWebsitesSection.website(website)}}" stepKey="SelectWebsite"/> + <checkOption selector="{{ProductInWebsitesSection.website(website)}}" stepKey="selectWebsite"/> </actionGroup> <!--Switch to New Store view--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index ddc0160d300bd..635d74f3f27fd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -11,7 +11,6 @@ <test name="AdminFilteringCategoryProductsUsingScopeSelectorTest"> <annotations> <features value="Catalog"/> - <group value="Catalog"/> <title value="Filtering Category Products using scope selector"/> <description value="Filtering Category Products using scope selector"/> <severity value="MAJOR"/> @@ -21,16 +20,16 @@ <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create website, Sore adn Store View--> - <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="AdminCreateWebsite"> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="adminCreateWebsite"> <argument name="newWebsiteName" value="secondWebsite"/> <argument name="websiteCode" value="second_website"/> </actionGroup> - <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="AdminCreateStore"> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="adminCreateStore"> <argument name="website" value="secondWebsite"/> <argument name="storeGroupName" value="secondStore"/> <argument name="storeGroupCode" value="second_store"/> </actionGroup> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="AdminCreateStoreView"> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="adminCreateStoreView"> <argument name="StoreGroup" value="customStoreTierPrice"/> <argument name="customStore" value="customStoreView"/> </actionGroup> @@ -64,6 +63,8 @@ <waitForPageLoad stepKey="waitForToOpenedWebsiteSection"/> <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." + stepKey="seeAssertSuccessMessage"/> <!-- Set filter to product name and product2 in website 2 only --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> @@ -77,6 +78,8 @@ </actionGroup> <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite1"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct1"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." + stepKey="seeAssertSuccessMessage1"/> <!-- Set filter to product name and product12 assigned to both websites 1 and 2 --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex1"/> @@ -89,11 +92,14 @@ <argument name="website" value="secondWebsite"/> </actionGroup> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct2"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." + stepKey="seeAssertSuccessMessage2"/> </before> <after> <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"> <argument name="websiteName" value="secondWebsite"/> </actionGroup> + <actionGroup ref="ClearProductsFilterActionGroup" stepKey="clearProductsFilter"/> <deleteData createDataKey="createProduct0" stepKey="deleteProduct"/> <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> <deleteData createDataKey="createProduct2" stepKey="deleteProduct2"/> From bc21a2b2e1822348f9253273ce96938d39252968 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Wed, 26 Sep 2018 12:47:09 +0300 Subject: [PATCH 0214/1415] MAGETWO-95171: Filtering Category Products using scope selector --- .../Test/Mftf/ActionGroup/AdminProductActionGroup.xml | 2 +- ...AdminFilteringCategoryProductsUsingScopeSelectorTest.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 82f75a76bc252..1f6c2ab4bb25f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -258,7 +258,7 @@ <argument name="website" type="string"/> </arguments> <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="scrollToWebsites"/> - <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="clickTpOpenProductInWebsite"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="clickToOpenProductInWebsite"/> <waitForPageLoad stepKey="waitForPageOpened"/> <checkOption selector="{{ProductInWebsitesSection.website(website)}}" stepKey="selectWebsite"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index 635d74f3f27fd..2e34521ebd821 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -64,7 +64,7 @@ <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." - stepKey="seeAssertSuccessMessage"/> + stepKey="seeSuccessMessage"/> <!-- Set filter to product name and product2 in website 2 only --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> @@ -79,7 +79,7 @@ <uncheckOption selector="{{ProductInWebsitesSection.website('Main Website')}}" stepKey="uncheckWebsite1"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct1"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." - stepKey="seeAssertSuccessMessage1"/> + stepKey="seeSuccessMessage1"/> <!-- Set filter to product name and product12 assigned to both websites 1 and 2 --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex1"/> @@ -93,7 +93,7 @@ </actionGroup> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct2"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product." - stepKey="seeAssertSuccessMessage2"/> + stepKey="seeSuccessMessage2"/> </before> <after> <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"> From caab8f7e1a1c213a7a0928b9c88f9760903ae17a Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Wed, 26 Sep 2018 13:12:32 +0300 Subject: [PATCH 0215/1415] MAGETWO-95137: [2.3] Return path e-mail variable system/smtp/return_path_email doesn't work --- app/code/Magento/Email/Model/Transport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Email/Model/Transport.php b/app/code/Magento/Email/Model/Transport.php index c270c3086cca9..28d2d171eecf4 100644 --- a/app/code/Magento/Email/Model/Transport.php +++ b/app/code/Magento/Email/Model/Transport.php @@ -32,7 +32,7 @@ class Transport implements TransportInterface const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email'; /** - * Configuration of whether return path should be set or no. + * Whether return path should be set or no. * * Possible values are: * 0 - no From 77d2386c243125a31788a11e15771ee25e786993 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Wed, 26 Sep 2018 16:18:19 +0400 Subject: [PATCH 0216/1415] MAGETWO-91602: Visual Merchandiser incorrectly displays/sorts configurable product price in Tile view - Add automated test --- .../Section/AdminCreateProductConfigurationsPanelSection.xml | 1 + .../Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml index 99e47baac37d5..7901b6f2290c9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml @@ -35,5 +35,6 @@ <element name="applySingleQuantityToEachSkus" type="radio" selector=".admin__field-label[for='apply-single-inventory-radio']" timeout="30"/> <element name="quantity" type="input" selector="#apply-single-inventory-input"/> <element name="gridLoadingMask" type="text" selector="[data-role='spinner'][data-component*='product_attributes_listing']"/> + <element name="attributeColorCheckbox" type="select" selector="//div[contains(text(),'color') and @class='data-grid-cell-content']/../preceding-sibling::td/label/input"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index 25e03676f6870..b7ed7c05e071e 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -21,5 +21,6 @@ <element name="nthChooseColor" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.colorpicker_handler" parameterized="true"/> <element name="nthUploadFile" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.btn_choose_file_upload" parameterized="true"/> <element name="nthDelete" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) button.delete-option" parameterized="true"/> + <element name="deleteBtn" type="button" selector="#manage-options-panel:nth-of-type({{var}}) button.delete-option" parameterized="true"/> </section> </sections> From 3073ed5e8670ab9b095cc6fb6d29d875d4235ce2 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 26 Sep 2018 14:31:18 +0200 Subject: [PATCH 0217/1415] Shipping method set concept --- .../SetShippingMethodsOnCart.php | 105 ++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 9 +- 2 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php new file mode 100644 index 0000000000000..448bdcbb37a6d --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; + +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; + +class SetShippingMethodsOnCart implements ResolverInterface +{ + /** + * @var CartRepositoryInterface + */ + private $cartRepository; + + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * SetShippingMethodsOnCart constructor. + * @param ArrayManager $arrayManager + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + */ + public function __construct( + ArrayManager $arrayManager, + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + CartRepositoryInterface $cartRepository + ) { + $this->arrayManager = $arrayManager; + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->cartRepository = $cartRepository; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + // TODO: throw an exception + } + + if (!$shippingMethods) { + // TODO: throw an exception? + } + + foreach ($shippingMethods as $shippingMethod) { + if (empty($shippingMethod['cart_address_id'])) { + // TODO: throw input exception + } + + if (empty($shippingMethod['shipping_method_code'])) { + // TODO: throw input exception + } + + // TODO: move to a separate class + // TODO: check current customer can apply operations on specified cart + } + + $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); + $quote = $this->cartRepository->get($quoteId); // TODO: catch no such entity exception + $this->setShippingMethods($shippingMethods, $quote); + + $quote->collectTotals(); + $quote->save(); + //$this->cartRepository->save($quote); + + return 'Success!'; + } + + private function setShippingMethods($shippingMethods, CartInterface $quote) + { + $addresses = $quote->getAllShippingAddresses(); + /** @var \Magento\Quote\Model\Quote\Address $address */ + foreach ($addresses as $address) { + $addressId = $address->getId(); + $shippingMethodForAddress = array_search($addressId, array_column($shippingMethods, 'cart_address_id')); + if ($shippingMethodForAddress !== false) { + $address->setShippingMethod($shippingMethods[$shippingMethodForAddress]['shipping_method_code']); +// $address->setCollectShippingRates(1); + $address->save(); + } + } + // TODO: make sure that shipping method is assigned for all addresses + } +} \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index b10575171781e..027e59c327ebd 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -11,7 +11,7 @@ type Mutation { removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput - setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") } input SetShippingAddressesOnCartInput { @@ -47,11 +47,12 @@ input CartAddressInput { } input SetShippingMethodsOnCartInput { + cart_id: String! shipping_methods: [ShippingMethodForAddressInput!]! } input ShippingMethodForAddressInput { - cart_address_id: String! + cart_address_id: String! # todo: int? shipping_method_code: String! } @@ -64,12 +65,12 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: Cart! + cart: String } # If no address is provided, the system get address assigned to a quote # If there's no address at all - the system returns all shipping methods -type AvailableShippingMethodsOnCartInput { +input AvailableShippingMethodsOnCartInput { cart_id: String! customer_address_id: Int address: CartAddressInput From 9a1775623fd7cfb3d5e9204033bdb70e1f2483aa Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Wed, 26 Sep 2018 16:02:54 +0300 Subject: [PATCH 0218/1415] MAGETWO-94991: [2.3] Magnifier does not work with Windows Chrome/FF --- lib/web/magnifier/magnify.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/web/magnifier/magnify.js b/lib/web/magnifier/magnify.js index 1fb73ea28bff1..9d673092b806c 100644 --- a/lib/web/magnifier/magnify.js +++ b/lib/web/magnifier/magnify.js @@ -35,13 +35,6 @@ define([ allowZoomOut = false, allowZoomIn = true; - if (isTouchEnabled) { - $(element).on('fotorama:showend fotorama:load', function () { - $(magnifierSelector).remove(); - $(magnifierZoomSelector).remove(); - }); - } - (function () { var style = document.documentElement.style, transitionEnabled = style.transition !== undefined || From a1a2b4a1368e79df8e2f8968edb63e05225daee0 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 26 Sep 2018 18:13:05 +0300 Subject: [PATCH 0219/1415] MAGETWO-91756: In Related product section add to wishlist and compare is not displaying for mobile devices portrait view - Fixed issue with missing compare/wishlist buttons on related product listings on mobile view; --- .../blank/Magento_Catalog/web/css/source/module/_listings.less | 1 - .../luma/Magento_Catalog/web/css/source/module/_listings.less | 1 - 2 files changed, 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_listings.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_listings.less index 8b727b0d9c28d..951ca89a07988 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_listings.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_listings.less @@ -63,7 +63,6 @@ } &-actions { - display: none; .actions-secondary { > button.action { diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less index d0382d34d39fc..6bf766b7400a7 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less @@ -68,7 +68,6 @@ } &-actions { - display: none; .actions-secondary { > button.action { From e2370ace78e463a9ae128e4f75b05993f261c25c Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 26 Sep 2018 11:01:03 -0500 Subject: [PATCH 0220/1415] MAGETWO-94819: Swatch validation breaks the whole attribute form - add jquery form validation event to restore options container --- app/code/Magento/Catalog/view/adminhtml/web/js/options.js | 2 +- .../Swatches/view/adminhtml/web/js/product-attributes.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 7c35993670444..1ec47f14fee88 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -210,7 +210,7 @@ define([ } tableBody = optionContainer.detach(); }); - editForm.on('afterValidate.error', function () { + editForm.on('afterValidate.error highlight.validate', function () { if (optionPanel.hasClass(activePanelClass)) { optionPanel.find('table').append(tableBody); jQuery('input[name="serialized_options"]').remove(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index d0eacc94e2c32..1dc833d5901ca 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -463,7 +463,7 @@ define([ tableBody = optionContainer.detach(); }); - editForm.on('afterValidate.error', function () { + editForm.on('afterValidate.error highlight.validate', function () { if (activePanel.hasClass(activePanelClass)) { activePanel.find('table').append(tableBody); $('input[name="serialized_options"]').remove(); From 75ccb2485aa5543f02e8ea2aac8e7f3c93d8c2c8 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Wed, 26 Sep 2018 15:07:58 +0300 Subject: [PATCH 0221/1415] MAGETWO-93394: Table rate shipment is taken from wrong website ID when creating an order through the admin --- .../Magento/Sales/Model/AdminOrder/Create.php | 17 ++- .../_files/tablerates_second_website.php | 40 +++++ .../tablerates_second_website_rollback.php | 13 ++ .../Controller/Adminhtml/Order/CreateTest.php | 137 +++++++++++++++++- .../_files/websites_different_countries.php | 14 +- 5 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index b690395ebab7c..088ad5a61f6c3 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -14,6 +14,7 @@ use Magento\Quote\Model\Quote\Item; use Magento\Sales\Api\Data\OrderAddressInterface; use Magento\Sales\Model\Order; +use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface; /** @@ -242,6 +243,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ */ private $dataObjectConverter; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -273,6 +279,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ * @param array $data * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param ExtensibleDataObjectConverter|null $dataObjectConverter + * @param StoreManagerInterface $storeManager * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -305,7 +312,8 @@ public function __construct( \Magento\Quote\Model\QuoteFactory $quoteFactory, array $data = [], \Magento\Framework\Serialize\Serializer\Json $serializer = null, - ExtensibleDataObjectConverter $dataObjectConverter = null + ExtensibleDataObjectConverter $dataObjectConverter = null, + StoreManagerInterface $storeManager = null ) { $this->_objectManager = $objectManager; $this->_eventManager = $eventManager; @@ -339,6 +347,7 @@ public function __construct( parent::__construct($data); $this->dataObjectConverter = $dataObjectConverter ?: ObjectManager::getInstance() ->get(ExtensibleDataObjectConverter::class); + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); } /** @@ -416,7 +425,8 @@ public function setRecollect($flag) /** * Recollect totals for customer cart. - * Set recollect totals flag for quote + * + * Set recollect totals flag for quote. * * @return $this */ @@ -1333,6 +1343,7 @@ protected function _createCustomerForm(\Magento\Customer\Api\Data\CustomerInterf /** * Set and validate Quote address + * * All errors added to _errors * * @param \Magento\Quote\Model\Quote\Address $address @@ -1536,6 +1547,8 @@ public function resetShippingMethod() */ public function collectShippingRates() { + $store = $this->getQuote()->getStore(); + $this->storeManager->setCurrentStore($store); $this->getQuote()->getShippingAddress()->setCollectShippingRates(true); $this->collectRates(); diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php new file mode 100644 index 0000000000000..52551e6dc96d8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\ResourceConnection; +use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var WebsiteRepositoryInterface $websiteRepository */ +$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class); +$website = $websiteRepository->get('test'); + +/** @var ResourceConnection $resource */ +$resource = $objectManager->get(ResourceConnection::class); +$connection = $resource->getConnection(); +$resourceModel = $objectManager->create(Tablerate::class); +$entityTable = $resourceModel->getTable('shipping_tablerate'); +$data = + [ + 'website_id' => $website->getId(), + 'dest_country_id' => 'US', + 'dest_region_id' => 0, + 'dest_zip' => '*', + 'condition_name' => 'package_qty', + 'condition_value' => 1, + 'price' => 20, + 'cost' => 20 + ]; +$connection->query( + "INSERT INTO {$entityTable} (`website_id`, `dest_country_id`, `dest_region_id`, `dest_zip`, `condition_name`," + . "`condition_value`, `price`, `cost`) VALUES (:website_id, :dest_country_id, :dest_region_id, :dest_zip," + . " :condition_name, :condition_value, :price, :cost);", + $data +); diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php new file mode 100644 index 0000000000000..9606b0eb605fd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class); +$connection = $resource->getConnection(); +$resourceModel = $objectManager->create(\Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate::class); +$entityTable = $resourceModel->getTable('shipping_tablerate'); +$connection->query("DELETE FROM {$entityTable};"); diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index efb1b12fc60ed..a07616474a410 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -6,15 +6,26 @@ namespace Magento\Sales\Controller\Adminhtml\Order; use Magento\Customer\Api\CustomerRepositoryInterface; -use Magento\Backend\Model\Session\Quote; +use Magento\Backend\Model\Session\Quote as SessionQuote; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\Config\MutableScopeConfigInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Quote\Model\Quote; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\Store\Model\ScopeInterface; /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyPublicMethods) */ class CreateTest extends \Magento\TestFramework\TestCase\AbstractBackendController { @@ -70,6 +81,57 @@ public function testLoadBlockActionData() } /** + * Tests that shipping method 'Table rates' shows rates according to selected website. + * + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/Quote/Fixtures/quote_sec_website.php + * @magentoDataFixture Magento/OfflineShipping/_files/tablerates_second_website.php + * @magentoDbIsolation disabled + */ + public function testLoadBlockShippingMethod() + { + $store = $this->getStore('fixture_second_store'); + + /** @var MutableScopeConfigInterface $mutableScopeConfig */ + $mutableScopeConfig = $this->_objectManager->get(MutableScopeConfigInterface::class); + $mutableScopeConfig->setValue( + 'carriers/tablerate/active', + 1, + ScopeInterface::SCOPE_STORE, + $store->getCode() + ); + $mutableScopeConfig->setValue( + 'carriers/tablerate/condition_name', + 'package_qty', + ScopeInterface::SCOPE_STORE, + $store->getCode() + ); + + $website = $this->getWebsite('test'); + $customer = $this->getCustomer('customer.web@example.com', (int)$website->getId()); + $quote = $this->getQuoteById('0000032134'); + $session = $this->_objectManager->get(SessionQuote::class); + $session->setQuoteId($quote->getId()); + + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue( + [ + 'customer_id' => $customer->getId(), + 'collect_shipping_rates' => 1, + 'store_id' => $store->getId(), + 'json' => true + ] + ); + $this->dispatch('backend/sales/order_create/loadBlock/block/shipping_method'); + $body = $this->getResponse()->getBody(); + $expectedTableRatePrice = '<span class=\"price\">$20.00<\/span>'; + + $this->assertContains($expectedTableRatePrice, $body, ''); + } + + /** + * Tests LoadBlock actions. + * * @param string $block Block name. * @param string $expected Contains HTML. * @@ -100,6 +162,8 @@ public function loadBlockActionsDataProvider() } /** + * Tests action items. + * * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ public function testLoadBlockActionItems() @@ -174,6 +238,8 @@ public function testIndexAction() } /** + * Tests ACL. + * * @param string $actionName * @param boolean $reordered * @param string $expectedResult @@ -183,7 +249,7 @@ public function testIndexAction() */ public function testGetAclResource($actionName, $reordered, $expectedResult) { - $this->_objectManager->get(Quote::class)->setReordered($reordered); + $this->_objectManager->get(SessionQuote::class)->setReordered($reordered); $orderController = $this->_objectManager->get( \Magento\Sales\Controller\Adminhtml\Order\Stub\OrderCreateStub::class ); @@ -278,7 +344,7 @@ public function testSyncBetweenQuoteAddresses() $quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class); $quote = $quoteRepository->getActiveForCustomer($customer->getId()); - $session = $this->_objectManager->get(Quote::class); + $session = $this->_objectManager->get(SessionQuote::class); $session->setQuoteId($quote->getId()); $data = [ @@ -314,4 +380,69 @@ public function testSyncBetweenQuoteAddresses() self::assertEquals($data['city'], $shippingAddress->getCity()); self::assertEquals($data['street'], $shippingAddress->getStreet()); } + + /** + * Gets quote entity by reserved order id. + * + * @param string $reservedOrderId + * @return Quote + */ + private function getQuoteById(string $reservedOrderId): Quote + { + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->_objectManager->get(SearchCriteriaBuilder::class); + $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId) + ->create(); + + /** @var CartRepositoryInterface $repository */ + $repository = $this->_objectManager->get(CartRepositoryInterface::class); + $items = $repository->getList($searchCriteria) + ->getItems(); + + return array_pop($items); + } + + /** + * Gets website entity. + * + * @param string $code + * @return WebsiteInterface + * @throws NoSuchEntityException + */ + private function getWebsite(string $code): WebsiteInterface + { + /** @var WebsiteRepositoryInterface $repository */ + $repository = $this->_objectManager->get(WebsiteRepositoryInterface::class); + return $repository->get($code); + } + + /** + * Gets customer entity. + * + * @param string $email + * @param int $websiteId + * @return CustomerInterface + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getCustomer(string $email, int $websiteId): CustomerInterface + { + /** @var CustomerRepositoryInterface $repository */ + $repository = $this->_objectManager->get(CustomerRepositoryInterface::class); + return $repository->get($email, $websiteId); + } + + /** + * Gets store by code. + * + * @param string $code + * @return StoreInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function getStore(string $code): StoreInterface + { + /** @var StoreRepositoryInterface $repository */ + $repository = $this->_objectManager->get(StoreRepositoryInterface::class); + return $repository->get($code); + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php index 04223d1353314..970b1619f0214 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php @@ -10,6 +10,7 @@ use Magento\Store\Model\Store; use Magento\CatalogSearch\Model\Indexer\Fulltext as FulltextIndex; use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Store\Model\Group; $objectManager = Bootstrap::getObjectManager(); //Creating second website with a store. @@ -21,12 +22,23 @@ $website->setData([ 'code' => 'test', 'name' => 'Test Website', - 'default_group_id' => '1', 'is_default' => '0', ]); $website->save(); } +/** + * @var Group $storeGroup + */ +$storeGroup = $objectManager->create(Group::class); +$storeGroup->setCode('some_group') + ->setName('custom store group') + ->setWebsite($website); +$storeGroup->save($storeGroup); + +$website->setDefaultGroupId($storeGroup->getId()); +$website->save($website); + $websiteId = $website->getId(); $store = $objectManager->create(Store::class); $store->load('fixture_second_store', 'code'); From 476f14ff89d6be14d1b3d8c950713c00d5802ec0 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 26 Sep 2018 16:35:20 +0000 Subject: [PATCH 0222/1415] graphQl-44: refactoring of resolver Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../Resolver/Product/ProductTextAttribute.php | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 9c1212667acf3..7649464e2e1ca 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,8 +10,7 @@ use Magento\Catalog\Model\Product; use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -25,26 +24,18 @@ class ProductTextAttribute implements ResolverInterface */ private $formatList; - /** - * @var ValueFactory - */ - private $valueFactory; - /** * @var string */ private $defaultFormat = 'html'; /** - * @param ValueFactory $valueFactory - * @param FormatList $formatFactory + * @param FormatList $formatList */ public function __construct( - ValueFactory $valueFactory, - FormatList $formatFactory + FormatList $formatList ) { - $this->valueFactory = $valueFactory; - $this->formatList = $formatFactory; + $this->formatList = $formatList; } /** @@ -56,10 +47,9 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): Value { + ) { if (!isset($value['model'])) { - $result = []; - return $this->valueFactory->create($result); + throw new GraphQlInputException(__('"model" value should be specified')); } /* @var $product Product */ @@ -69,6 +59,6 @@ public function resolve( $format = $this->formatList->create($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; - return $this->valueFactory->create($result); + return $result; } } From ae2917c58c836a80da13659f50d251de83efadd2 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 26 Sep 2018 22:56:54 +0300 Subject: [PATCH 0223/1415] Fixed the phpdocs issues for failing tests --- app/code/Magento/Catalog/Model/Product.php | 72 +++++++++++++--------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 223db01351d66..f29c6e475f05f 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -497,11 +497,13 @@ protected function _getResource() return parent::_getResource(); } + //@codeCoverageIgnoreStart /** * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for * product will return all product attribute codes * * @return string[] + * //@codeCoverageIgnoreEnd */ protected function getCustomAttributesCodes() { @@ -584,11 +586,12 @@ public function getPrice() } /** - * @codeCoverageIgnoreStart * Get visibility status + * * @see \Magento\Catalog\Model\Product\Visibility * * @return int + * @codeCoverageIgnoreStart */ public function getVisibility() { @@ -824,10 +827,9 @@ public function getStoreIds() } /** - * Retrieve product attributes - * if $groupId is null - retrieve all product attributes + * Retrieve product attributes. If $groupId is null - retrieve all product attributes * - * @param int $groupId Retrieve attributes of the specified group + * @param int|null $groupId Retrieve attributes of the specified group * @param bool $skipSuper Not used * @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -918,10 +920,9 @@ public function beforeSave() } /** - * Check/set if options can be affected when saving product - * If value specified, it will be set. + * Check/set if options can be affected when saving product. If value specified, it will be set. * - * @param bool $value + * @param bool|null $value * @return bool */ public function canAffectOptions($value = null) @@ -1038,10 +1039,10 @@ public function reindex() } /** - * Clear cache related with product and protect delete from not admin - * Register indexing event before delete product + * Clear cache related with product and protect delete from not admin. Register indexing event before delete product * - * @return \Magento\Catalog\Model\Product + * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function beforeDelete() { @@ -1548,12 +1549,13 @@ public function hasGalleryAttribute() /** * Add image to media gallery * - * @param string $file file path of image in file system - * @param string|array $mediaAttribute code of attribute with type 'media_image', - * leave blank if image should be only in gallery - * @param boolean $move if true, it will move source file - * @param boolean $exclude mark image as disabled in product page view - * @return \Magento\Catalog\Model\Product + * @param string $file File path of image in file system + * @param null|string|array $mediaAttribute Code of attribute with type 'media_image' + * Leave blank if image should be only in gallery + * @param bool $move If true, it will move source file + * @param bool $exclude Mark image as disabled in product page view + * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function addImageToMediaGallery($file, $mediaAttribute = null, $move = false, $exclude = true) { @@ -1714,7 +1716,6 @@ public function getIsSalable() /** * Check is a virtual product - * Data helper wrapper * * @return bool */ @@ -1806,9 +1807,9 @@ public function formatUrlKey($str) /** * Save current attribute with code $code and assign new value * - * @param string $code Attribute code - * @param mixed $value New attribute value - * @param int $store Store ID + * @param string $code Attribute code + * @param mixed $value New attribute value + * @param int $store Store ID * @return void */ public function addAttributeUpdate($code, $value, $store) @@ -1878,6 +1879,7 @@ public function getRequestPath() /** * Custom function for other modules + * * @return string */ public function getGiftMessageAvailable() @@ -1996,6 +1998,8 @@ public function getOptions() } /** + * Set Options + * * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options * @return $this */ @@ -2019,10 +2023,10 @@ public function getIsVirtual() /** * Add custom option information to product * - * @param string $code Option code - * @param mixed $value Value of the option - * @param int|Product $product Product ID - * @return $this + * @param string $code Option code + * @param mixed $value Value of the option + * @param int|Product|null $product Product ID + * @return $this */ public function addCustomOption($code, $value, $product = null) { @@ -2215,8 +2219,7 @@ public function getPreconfiguredValues() } /** - * Prepare product custom options. - * To be sure that all product custom options does not has ID and has product instance + * Prepare product custom options.To be sure that all product custom options does not has ID and has product instance * * @return \Magento\Catalog\Model\Product */ @@ -2550,7 +2553,7 @@ public function setTypeId($typeId) } /** - * {@inheritdoc} + * Get Extension Attributes * * @return \Magento\Catalog\Api\Data\ProductExtensionInterface */ @@ -2560,7 +2563,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * Set Extension Attributes * * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes * @return $this @@ -2573,8 +2576,11 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensio //@codeCoverageIgnoreEnd /** + * Convert Image to ProductAttributeMediaGalleryEntryInterface + * * @param array $mediaGallery * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] + * @throws \Magento\Framework\Exception\LocalizedException */ protected function convertToMediaGalleryInterface(array $mediaGallery) { @@ -2590,7 +2596,10 @@ protected function convertToMediaGalleryInterface(array $mediaGallery) } /** + * Get Media Gallery + * * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null + * @throws \Magento\Framework\Exception\LocalizedException */ public function getMediaGalleryEntries() { @@ -2604,8 +2613,11 @@ public function getMediaGalleryEntries() } /** + * Set Media Gallery + * * @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function setMediaGalleryEntries(array $mediaGalleryEntries = null) { @@ -2646,6 +2658,8 @@ public function setId($value) } /** + * Get Product Link Repository + * * @return ProductLinkRepositoryInterface */ private function getLinkRepository() @@ -2658,6 +2672,8 @@ private function getLinkRepository() } /** + * Get Media Gallery Processor + * * @return Product\Gallery\Processor */ private function getMediaGalleryProcessor() From f0b1e02fb4cd9bc8be17a05469f3d10749d2b423 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 26 Sep 2018 15:07:47 -0500 Subject: [PATCH 0224/1415] MC-4277: Address Product Page slowness due to 'product_data_storage' handling --- .../view/frontend/web/js/product/storage/data-storage.js | 2 +- .../view/frontend/web/js/product/storage/ids-storage.js | 6 +----- .../view/frontend/web/js/product/storage/storage-service.js | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js index ab566a70a756d..0059cee60d30f 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js @@ -118,7 +118,7 @@ define([ if (_.isEmpty(data)) { this.localStorage.removeAll(); } else { - this.localStorage.set(data); + window.localStorage.setItem(this.namespace, JSON.stringify(data)); } }, diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js index 7eafbad8299d8..f77bdd0263aa7 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js @@ -94,11 +94,7 @@ define([ * Initializes handler to "data" property update */ internalDataHandler: function (data) { - var localStorage = this.localStorage.get(); - - if (!utils.compare(data, localStorage).equal) { - this.localStorage.set(data); - } + window.localStorage.setItem(this.namespace, JSON.stringify(data)); }, /** diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/storage-service.js b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/storage-service.js index e571baa23e497..b35ab867bb0e7 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/storage-service.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/storage-service.js @@ -47,7 +47,7 @@ define([ * @param {*} data */ add: function (data) { - if (!_.isEmpty(data) && !utils.compare(data, this.data()).equal) { + if (!_.isEmpty(data)) { this.data(_.extend(utils.copy(this.data()), data)); } }, From 9b7f45add2d5fbcf80aff1705ae9c34e7fdd48c1 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Wed, 26 Sep 2018 16:23:08 -0500 Subject: [PATCH 0225/1415] MAGETWO-95232: Can not create an invoice using Safari - Move jQuery no conflict call to ensure it's executed before prototype is loaded --- app/code/Magento/Theme/view/base/requirejs-config.js | 6 ++++++ lib/web/jquery/patches/jquery.js | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index d6006c21c8a15..52e9270952a95 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -64,3 +64,9 @@ var config = { } } }; + +require(['jquery'], function ($) { + 'use strict'; + + $.noConflict(); +}); diff --git a/lib/web/jquery/patches/jquery.js b/lib/web/jquery/patches/jquery.js index 9d733a92159c6..5c741d0832b75 100644 --- a/lib/web/jquery/patches/jquery.js +++ b/lib/web/jquery/patches/jquery.js @@ -22,14 +22,12 @@ define([], function () { return function ($) { var majorVersion = $.fn.jquery.split('.')[0]; - $.noConflict(); - if (majorVersion >= 3) { console.warn('jQuery patch for CVE-2015-9251 is no longer necessary, and should be removed'); } - ajaxResponsePatch(jQuery); + ajaxResponsePatch($); - return jQuery; + return $; }; }); From 488c2dc7b58931093fd8e7ca498343b2737e7a5f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 26 Sep 2018 16:53:33 -0500 Subject: [PATCH 0226/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 45 +++++++++++++++ .../Mftf/Section/CheckoutPaymentSection.xml | 1 + .../Mftf/Test/StorefrontGuestCheckoutTest.xml | 57 +++++++++++++++++++ .../view/frontend/web/js/view/shipping.js | 1 + 4 files changed, 104 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 32d6ad8667029..eef35abcc978a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -38,6 +38,51 @@ <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> </actionGroup> + <!-- Guest checkout filling shipping section without region --> + <actionGroup name="GuestCheckoutFillingShippingSectionWithoutRegionActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <selectOption selector="{{CheckoutShippingSection.country}}" userInput="{{customerAddressVar.country_id}}" stepKey="enterCountry"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + </actionGroup> + + <!-- Guest checkout filling shipping section with unavailable payments--> + <actionGroup name="GuestCheckoutFillingShippingSectionUnavailablePaymentActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <selectOption selector="{{CheckoutShippingSection.region}}" userInput="{{customerAddressVar.state}}" stepKey="selectRegion"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.noQuotes}}" stepKey="waitMessage"/> + <see userInput="No Payment method available." stepKey="checkMessage"/> + </actionGroup> + <!-- Logged in user checkout filling shipping section --> <actionGroup name="LoggedInUserCheckoutFillingShippingSectionActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 7dda1110fd145..846b20ed225dd 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -50,5 +50,6 @@ <element name="shippingAndBillingAddressSame" type="input" selector="#billing-address-same-as-shipping-braintree_cc_vault"/> <element name="addressAction" type="button" selector="//span[text()='{{action}}']" parameterized="true"/> <element name="addressBook" type="button" selector="//a[text()='Address Book']"/> + <element name="noQuotes" type="text" selector=".no-quotes-block"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index a7b82d54afb30..02cc233acc7bc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -68,4 +68,61 @@ <see selector="{{AdminOrderDetailsInformationSection.shippingAddress}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeAdminOrderShippingAddress"/> <see selector="{{AdminOrderDetailsInformationSection.itemsOrdered}}" userInput="$$createProduct.name$$" stepKey="seeAdminOrderProduct"/> </test> + <test name="StorefrontGuestCheckoutTestWithRestrictedCountriesForPayment"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout flow if payment solutions are not available"/> + <title value="Checkout via Guest Checkout with restricted countries for payment"/> + <description value="Should be able to place an order as a Guest with restricted countries for payment."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-42653"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 1" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry GB" /> + + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry ''" /> + </after> + + <!-- Add product to cart --> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <see selector="{{StorefrontMinicartSection.quantity}}" userInput="1" stepKey="seeCartQuantity"/> + + <!-- Go to checkout page --> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="guestGoToCheckoutFromMinicart" /> + + <!-- Fill US Address and verify that no payment available --> + <actionGroup ref="GuestCheckoutFillingShippingSectionUnavailablePaymentActionGroup" stepKey="guestCheckoutFillingShippingSection"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="CustomerAddressSimple" /> + </actionGroup> + + <!-- Fill UK Address and verify that payment available and checkout successful --> + <click selector="{{CheckoutHeaderSection.shippingMethodStep}}" stepKey="goToShipping" /> + <actionGroup ref="GuestCheckoutFillingShippingSectionWithoutRegionActionGroup" stepKey="guestCheckoutFillingShippingSectionUK"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="UK_Not_Default_Address" /> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="guestPlaceorder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + </test> </tests> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index c0f8b5a45fec9..395d15bc02f36 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -247,6 +247,7 @@ define([ */ setShippingInformation: function () { if (this.validateShippingInformation()) { + quote.billingAddress(null); checkoutDataResolver.resolveBillingAddress(); setShippingInformationAction().done( function () { From e068783fef14108cafe169f1639f7e3875875bc4 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Thu, 27 Sep 2018 08:20:11 +0300 Subject: [PATCH 0227/1415] Fixed line exceed errors --- app/code/Magento/Catalog/Model/Product.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index f29c6e475f05f..fe020f450a6ee 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -497,13 +497,11 @@ protected function _getResource() return parent::_getResource(); } - //@codeCoverageIgnoreStart /** * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for - * product will return all product attribute codes + * product will return all product attribute codes * * @return string[] - * //@codeCoverageIgnoreEnd */ protected function getCustomAttributesCodes() { @@ -665,7 +663,7 @@ public function getStatus() /** * Retrieve type instance of the product. - * Type instance implements product type depended logic and is a singleton shared by all products of the same type. + * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType */ @@ -2219,7 +2217,8 @@ public function getPreconfiguredValues() } /** - * Prepare product custom options.To be sure that all product custom options does not has ID and has product instance + * Prepare product custom options.To be sure that all product custom options does not has ID and has product + * instance * * @return \Magento\Catalog\Model\Product */ From 38dbbe2b4653a6372bb68ca90686b39927614d40 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Wed, 26 Sep 2018 15:46:24 +0300 Subject: [PATCH 0228/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - Fixed discounts deltas calculation --- .../Model/Order/Creditmemo/Total/Shipping.php | 11 ++- .../Model/Order/Creditmemo/Total/Tax.php | 13 ++-- .../Sales/Model/Order/Invoice/Total/Tax.php | 28 +++++--- .../Sales/Model/Service/CreditmemoService.php | 16 +++-- .../Model/Service/CreditmemoServiceTest.php | 70 +++++++++++-------- 5 files changed, 79 insertions(+), 59 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php index f00334f496b2a..f644d0c3a5a63 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php @@ -37,6 +37,8 @@ public function __construct( } /** + * Collects credit memo shipping totals. + * * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @throws \Magento\Framework\Exception\LocalizedException @@ -55,12 +57,10 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) $orderShippingInclTax = $order->getShippingInclTax(); $orderBaseShippingInclTax = $order->getBaseShippingInclTax(); $allowedTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); - $baseAllowedTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); $allowedAmountInclTax = $allowedAmount + $allowedTaxAmount; - $baseAllowedAmountInclTax = $baseAllowedAmount + $baseAllowedTaxAmount; - - // for the credit memo - $shippingAmount = $baseShippingAmount = $shippingInclTax = $baseShippingInclTax = 0; + $baseAllowedAmountInclTax = $orderBaseShippingInclTax + - $order->getBaseShippingRefunded() + - $order->getBaseShippingTaxRefunded(); // Check if the desired shipping amount to refund was specified (from invoice or another source). if ($creditmemo->hasBaseShippingAmount()) { @@ -128,7 +128,6 @@ private function isSuppliedShippingAmountInclTax($order) /** * Get the Tax Config. - * In a future release, will become a constructor parameter. * * @return \Magento\Tax\Model\Config * diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php index a842c0470ad85..5ab9469441bef 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -5,9 +5,14 @@ */ namespace Magento\Sales\Model\Order\Creditmemo\Total; +/** + * Collects credit memo taxes. + */ class Tax extends AbstractTotal { /** + * Collects credit memo taxes. + * * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @@ -79,18 +84,10 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) $totalDiscountTaxCompensation += $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; $baseTotalDiscountTaxCompensation += $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; - $shippingDiscountTaxCompensationAmount = - $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor; - $baseShippingDiscountTaxCompensationAmount = - $invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor; $shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base'); $totalDiscountTaxCompensation = $creditmemo->roundPrice($totalDiscountTaxCompensation); $baseTotalDiscountTaxCompensation = $creditmemo->roundPrice($baseTotalDiscountTaxCompensation, 'base'); - $shippingDiscountTaxCompensationAmount = - $creditmemo->roundPrice($shippingDiscountTaxCompensationAmount); - $baseShippingDiscountTaxCompensationAmount = - $creditmemo->roundPrice($baseShippingDiscountTaxCompensationAmount, 'base'); if ($taxFactor < 1 && $invoice->getShippingTaxAmount() > 0) { $isPartialShippingRefunded = true; } diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Total/Tax.php b/app/code/Magento/Sales/Model/Order/Invoice/Total/Tax.php index fd5c015d9db4f..6e12f10f0c679 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/Total/Tax.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/Total/Tax.php @@ -5,6 +5,9 @@ */ namespace Magento\Sales\Model\Order\Invoice\Total; +/** + * Collects invoice taxes. + */ class Tax extends AbstractTotal { /** @@ -69,11 +72,24 @@ public function collect(\Magento\Sales\Model\Order\Invoice $invoice) } } + $taxDiscountCompensationAmt = $totalDiscountTaxCompensation; + $baseTaxDiscountCompensationAmt = $baseTotalDiscountTaxCompensation; + $allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationAmount() - + $order->getDiscountTaxCompensationInvoiced(); + $allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationAmount() - + $order->getBaseDiscountTaxCompensationInvoiced(); + if ($this->_canIncludeShipping($invoice)) { $totalTax += $order->getShippingTaxAmount(); $baseTotalTax += $order->getBaseShippingTaxAmount(); $totalDiscountTaxCompensation += $order->getShippingDiscountTaxCompensationAmount(); $baseTotalDiscountTaxCompensation += $order->getBaseShippingDiscountTaxCompensationAmnt(); + + $allowedDiscountTaxCompensation += $order->getShippingDiscountTaxCompensationAmount() - + $order->getShippingDiscountTaxCompensationInvoiced(); + $allowedBaseDiscountTaxCompensation += $order->getBaseShippingDiscountTaxCompensationAmnt() - + $order->getBaseShippingDiscountTaxCompensationInvoiced(); + $invoice->setShippingTaxAmount($order->getShippingTaxAmount()); $invoice->setBaseShippingTaxAmount($order->getBaseShippingTaxAmount()); $invoice->setShippingDiscountTaxCompensationAmount($order->getShippingDiscountTaxCompensationAmount()); @@ -81,14 +97,6 @@ public function collect(\Magento\Sales\Model\Order\Invoice $invoice) } $allowedTax = $order->getTaxAmount() - $order->getTaxInvoiced(); $allowedBaseTax = $order->getBaseTaxAmount() - $order->getBaseTaxInvoiced(); - $allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationAmount() + - $order->getShippingDiscountTaxCompensationAmount() - - $order->getDiscountTaxCompensationInvoiced() - - $order->getShippingDiscountTaxCompensationInvoiced(); - $allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationAmount() + - $order->getBaseShippingDiscountTaxCompensationAmnt() - - $order->getBaseDiscountTaxCompensationInvoiced() - - $order->getBaseShippingDiscountTaxCompensationInvoiced(); if ($invoice->isLast()) { $totalTax = $allowedTax; @@ -107,8 +115,8 @@ public function collect(\Magento\Sales\Model\Order\Invoice $invoice) $invoice->setTaxAmount($totalTax); $invoice->setBaseTaxAmount($baseTotalTax); - $invoice->setDiscountTaxCompensationAmount($totalDiscountTaxCompensation); - $invoice->setBaseDiscountTaxCompensationAmount($baseTotalDiscountTaxCompensation); + $invoice->setDiscountTaxCompensationAmount($taxDiscountCompensationAmt); + $invoice->setBaseDiscountTaxCompensationAmount($baseTaxDiscountCompensationAmt); $invoice->setGrandTotal($invoice->getGrandTotal() + $totalTax + $totalDiscountTaxCompensation); $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $baseTotalTax + $baseTotalDiscountTaxCompensation); diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php index e8f2e6e5305f7..a1bff966753f0 100644 --- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php +++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php @@ -178,6 +178,8 @@ public function refund( } /** + * Checks if credit memo is available for refund. + * * @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo * @return bool * @throws \Magento\Framework\Exception\LocalizedException @@ -200,7 +202,7 @@ protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface throw new \Magento\Framework\Exception\LocalizedException( __( 'The most money available to refund is %1.', - $creditmemo->getOrder()->formatBasePrice($baseAvailableRefund) + $creditmemo->getOrder()->formatPriceTxt($baseAvailableRefund) ) ); } @@ -208,8 +210,9 @@ protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface } /** - * @return \Magento\Sales\Model\Order\RefundAdapterInterface + * Initializes RefundAdapterInterface dependency. * + * @return \Magento\Sales\Model\Order\RefundAdapterInterface * @deprecated 100.1.3 */ private function getRefundAdapter() @@ -222,8 +225,9 @@ private function getRefundAdapter() } /** - * @return \Magento\Framework\App\ResourceConnection|mixed + * Initializes ResourceConnection dependency. * + * @return \Magento\Framework\App\ResourceConnection|mixed * @deprecated 100.1.3 */ private function getResource() @@ -236,8 +240,9 @@ private function getResource() } /** - * @return \Magento\Sales\Api\OrderRepositoryInterface + * Initializes OrderRepositoryInterface dependency. * + * @return \Magento\Sales\Api\OrderRepositoryInterface * @deprecated 100.1.3 */ private function getOrderRepository() @@ -250,8 +255,9 @@ private function getOrderRepository() } /** - * @return \Magento\Sales\Api\InvoiceRepositoryInterface + * Initializes InvoiceRepositoryInterface dependency. * + * @return \Magento\Sales\Api\InvoiceRepositoryInterface * @deprecated 100.1.3 */ private function getInvoiceRepository() diff --git a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php index 2e668f0b0d6f1..68681c6c5a66b 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php @@ -3,10 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Test\Unit\Model\Service; use Magento\Sales\Model\Order; +use Magento\Sales\Api\Data\CreditmemoInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + /** * Class CreditmemoServiceTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -14,34 +19,34 @@ class CreditmemoServiceTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Sales\Api\CreditmemoRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Api\CreditmemoRepositoryInterface|MockObject */ protected $creditmemoRepositoryMock; /** - * @var \Magento\Sales\Api\CreditmemoCommentRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Api\CreditmemoCommentRepositoryInterface|MockObject */ protected $creditmemoCommentRepositoryMock; /** - * @var \Magento\Framework\Api\SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Api\SearchCriteriaBuilder|MockObject */ protected $searchCriteriaBuilderMock; /** - * @var \Magento\Framework\Api\FilterBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Api\FilterBuilder|MockObject */ protected $filterBuilderMock; /** - * @var \Magento\Sales\Model\Order\CreditmemoNotifier|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Model\Order\CreditmemoNotifier|MockObject */ protected $creditmemoNotifierMock; /** - * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\PriceCurrencyInterface|MockObject */ - private $priceCurrencyMock; + private $priceCurrency; /** * @var \Magento\Sales\Model\Service\CreditmemoService @@ -79,7 +84,7 @@ protected function setUp() ['setField', 'setValue', 'setConditionType', 'create'] ); $this->creditmemoNotifierMock = $this->createMock(\Magento\Sales\Model\Order\CreditmemoNotifier::class); - $this->priceCurrencyMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceCurrencyInterface::class) + $this->priceCurrency = $this->getMockBuilder(\Magento\Framework\Pricing\PriceCurrencyInterface::class) ->getMockForAbstractClass(); $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -91,7 +96,7 @@ protected function setUp() 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock, 'filterBuilder' => $this->filterBuilderMock, 'creditmemoNotifier' => $this->creditmemoNotifierMock, - 'priceCurrency' => $this->priceCurrencyMock, + 'priceCurrency' => $this->priceCurrency, ] ); } @@ -187,7 +192,7 @@ public function testRefund() $orderMock->expects($this->once())->method('getBaseTotalPaid')->willReturn(10); $creditMemoMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(10); - $this->priceCurrencyMock->expects($this->any()) + $this->priceCurrency->expects($this->any()) ->method('round') ->willReturnArgument(0); @@ -259,7 +264,7 @@ public function testRefundPendingCreditMemo() $orderMock->expects($this->once())->method('getBaseTotalPaid')->willReturn(10); $creditMemoMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(10); - $this->priceCurrencyMock->expects($this->any()) + $this->priceCurrency->expects($this->any()) ->method('round') ->willReturnArgument(0); @@ -324,27 +329,32 @@ public function testRefundExpectsMoneyAvailableToReturn() $baseGrandTotal = 10; $baseTotalRefunded = 9; $baseTotalPaid = 10; - $creditMemoMock = $this->getMockBuilder(\Magento\Sales\Api\Data\CreditmemoInterface::class) - ->setMethods(['getId', 'getOrder', 'formatBasePrice']) + /** @var CreditmemoInterface|MockObject $creditMemo */ + $creditMemo = $this->getMockBuilder(CreditmemoInterface::class) + ->setMethods(['getId', 'getOrder']) ->getMockForAbstractClass(); - $creditMemoMock->expects($this->once())->method('getId')->willReturn(null); - $orderMock = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock(); - $creditMemoMock->expects($this->atLeastOnce())->method('getOrder')->willReturn($orderMock); - $creditMemoMock->expects($this->once())->method('getBaseGrandTotal')->willReturn($baseGrandTotal); - $orderMock->expects($this->atLeastOnce())->method('getBaseTotalRefunded')->willReturn($baseTotalRefunded); - $this->priceCurrencyMock->expects($this->exactly(2))->method('round')->withConsecutive( - [$baseTotalRefunded + $baseGrandTotal], - [$baseTotalPaid] - )->willReturnOnConsecutiveCalls( - $baseTotalRefunded + $baseGrandTotal, - $baseTotalPaid - ); - $orderMock->expects($this->atLeastOnce())->method('getBaseTotalPaid')->willReturn($baseTotalPaid); + $creditMemo->method('getId') + ->willReturn(null); + /** @var Order|MockObject $order */ + $order = $this->getMockBuilder(Order::class) + ->disableOriginalConstructor() + ->getMock(); + $creditMemo->method('getOrder') + ->willReturn($order); + $creditMemo->method('getBaseGrandTotal') + ->willReturn($baseGrandTotal); + $order->method('getBaseTotalRefunded') + ->willReturn($baseTotalRefunded); + $this->priceCurrency->method('round') + ->withConsecutive([$baseTotalRefunded + $baseGrandTotal], [$baseTotalPaid]) + ->willReturnOnConsecutiveCalls($baseTotalRefunded + $baseGrandTotal, $baseTotalPaid); + $order->method('getBaseTotalPaid') + ->willReturn($baseTotalPaid); $baseAvailableRefund = $baseTotalPaid - $baseTotalRefunded; - $orderMock->expects($this->once())->method('formatBasePrice')->with( - $baseAvailableRefund - )->willReturn($baseAvailableRefund); - $this->creditmemoService->refund($creditMemoMock, true); + $order->method('formatPriceTxt') + ->with($baseAvailableRefund) + ->willReturn($baseAvailableRefund); + $this->creditmemoService->refund($creditMemo, true); } /** From 345ef5b2d998d9cbc1802ebd300c63f860436111 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Thu, 27 Sep 2018 10:52:57 +0300 Subject: [PATCH 0229/1415] MAGETWO-95171: Filtering Category Products using scope selector --- ...minFilteringCategoryProductsUsingScopeSelectorTest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index 2e34521ebd821..38da50e730d9a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -136,6 +136,10 @@ userInput="$$createProduct1.name$$" stepKey="seeProductName4"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" userInput="$$createProduct12.name$$" stepKey="seeProductName5"/> + <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}" + userInput="$$createProduct0.name$$" stepKey="dontSeeProductName"/> + <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" + userInput="$$createProduct2.name$$" stepKey="dontSeeProductName1"/> <!-- Step 4: Set scope selector to Website2 ( StopreView for Website 2) --> <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> @@ -152,5 +156,9 @@ userInput="$$createProduct2.name$$" stepKey="seeProductName6"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" userInput="$$createProduct12.name$$" stepKey="seeProductName7"/> + <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}" + userInput="$$createProduct0.name$$" stepKey="dontSeeProductName2"/> + <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" + userInput="$$createProduct1.name$$" stepKey="dontSeeProductName3"/> </test> </tests> From a11d530af299310cf453e0781feba92a59fc64f7 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Thu, 27 Sep 2018 02:02:59 -0700 Subject: [PATCH 0230/1415] MAGETWO-95174: Sorting by price for Configurable with Catalog Rule applied --- .../AdminProductAttributeActionGroup.xml | 21 +++ .../StorefrontCategoryActionGroup.xml | 3 +- .../Test/Mftf/Data/FrontendLabelData.xml | 4 + .../CatalogPriceRuleActionGroup.xml | 16 +- .../Test/Mftf/Data/CatalogRuleData.xml | 14 ++ .../AdminNewCatalogPriceRuleSection.xml | 2 +- .../Data/ConfigurableProductOptionData.xml | 7 + .../Test/Mftf/Data/ValueIndexData.xml | 3 + ...ConfigurableWithCatalogRuleAppliedTest.xml | 162 ++++++++++++++++++ 9 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index fd80838692065..92aa55eedda09 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -17,4 +17,25 @@ <click selector="{{AdminProductAttributeGridSection.AttributeCode(ProductAttribute.attribute_code)}}" stepKey="navigateToAttributeEditPage1" /> <waitForPageLoad stepKey="waitForPageLoad2" /> </actionGroup> + <actionGroup name="navigateToEditProductAttribute"> + <arguments> + <argument name="ProductAttribute" type="string"/> + </arguments> + <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <fillField selector="{{AdminProductAttributeGridSection.GridFilterFrontEndLabel}}" userInput="{{ProductAttribute}}" stepKey="navigateToAttributeEditPage1" /> + <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="navigateToAttributeEditPage2" /> + <waitForPageLoad stepKey="waitForPageLoad2" /> + <click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="navigateToAttributeEditPage3" /> + <waitForPageLoad stepKey="waitForPageLoad3" /> + </actionGroup> + <actionGroup name="changeUseForPromoRuleConditionsProductAttribute"> + <arguments> + <argument name="option" type="string"/> + </arguments> + <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="clickStoreFrontPropertiesTab"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <selectOption selector="{{StorefrontPropertiesSection.useForPromoRuleConditions}}" userInput="{{option}}" stepKey="changeOption"/> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="saveAttribute"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index c980c43b8f3af..301bd4b7a5745 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -15,9 +15,10 @@ <argument name="mode" type="string"/> <argument name="numOfProductsPerPage" type="string"/> <argument name="sortBy" type="string" defaultValue="position"/> + <argument name="sort" type="string" defaultValue="asc"/> </arguments> <!-- Go to storefront category page --> - <amOnPage url="{{StorefrontCategoryPage.url(category)}}?product_list_limit={{numOfProductsPerPage}}&product_list_mode={{mode}}&product_list_order={{sortBy}}" stepKey="onCategoryPage"/> + <amOnPage url="{{StorefrontCategoryPage.url(category)}}?product_list_limit={{numOfProductsPerPage}}&product_list_mode={{mode}}&product_list_order={{sortBy}}&product_list_dir={{sort}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml index a46d40c62c76e..a2bdaa7dbc62f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml @@ -16,4 +16,8 @@ <data key="store_id">0</data> <data key="label" unique="suffix">attributeTwo</data> </entity> + <entity name="ProductAttributeFrontendLabelThree" type="FrontendLabel"> + <data key="store_id">0</data> + <data key="label" unique="suffix">attributeThree</data> + </entity> </entities> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index bfc059ccb247b..cfd41f2ab970c 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -17,7 +17,6 @@ <amOnPage stepKey="goToPriceRulePage" url="{{CatalogRulePage.url}}"/> <waitForPageLoad stepKey="waitForPriceRulePage"/> <click stepKey="addNewRule" selector="{{AdminGridMainControls.add}}"/> - <waitForPageLoad stepKey="waitForIndividualRulePage"/> <!-- Fill the form according the attributes of the entity --> <fillField stepKey="fillName" selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}"/> @@ -44,4 +43,19 @@ <click stepKey="applyRules" selector="{{AdminCatalogPriceRuleGrid.applyRules}}"/> <see stepKey="assertSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="Updated rules applied."/> </actionGroup> + + <!--Add Catalog Rule Condition With product SKU--> + <actionGroup name="newCatalogPriceRuleByUIWithConditionIsSKU" extends="newCatalogPriceRuleByUI"> + <arguments> + <argument name="productSku"/> + </arguments> + <click selector="{{AdminNewCatalogPriceRule.conditionsTab}}" after="discardSubsequentRules" stepKey="openConditionsTab"/> + <waitForPageLoad after="openConditionsTab" stepKey="waitForConditionTabOpened"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.newCondition}}" after="waitForConditionTabOpened" stepKey="addNewCondition"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.conditionSelect('1')}}" userInput="Magento\CatalogRule\Model\Rule\Condition\Product|sku" after="addNewCondition" stepKey="selectTypeCondition"/> + <waitForPageLoad after="selectTypeCondition" stepKey="waitForConditionChosed"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.targetEllipsis('1')}}" after="waitForConditionChosed" stepKey="clickEllipsis"/> + <fillField selector="{{AdminNewCatalogPriceRuleConditions.targetInput('1', '1')}}" userInput="{{productSku}}" after="clickEllipsis" stepKey="fillProductSku"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.applyButton('1', '1')}}" after="fillProductSku" stepKey="clickApply"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml b/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml index b1cb1920f39f4..71bdfe0613bb7 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml @@ -63,4 +63,18 @@ <data key="simple_action">to_fixed</data> <data key="discount_amount">110.7</data> </entity> + + <entity name="CatalogRuleByPercentWith96Amount" type="catalogRule"> + <data key="name" unique="suffix">CatalogPriceRule</data> + <data key="description">Catalog Price Rule Description</data> + <data key="is_active">1</data> + <array key="customer_group_ids"> + <item>0</item> + </array> + <array key="website_ids"> + <item>1</item> + </array> + <data key="simple_action">by_percent</data> + <data key="discount_amount">96</data> + </entity> </entities> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml index ab2c6eb89d266..7cfb5bf40be55 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml @@ -38,7 +38,7 @@ </section> <section name="AdminNewCatalogPriceRuleConditions"> - <element name="newCondition" type="button" selector="span.rule-param-new-child"/> + <element name="newCondition" type="button" selector=".rule-param.rule-param-new-child"/> <element name="conditionSelect" type="select" selector="select#conditions__{{var}}__new_child" parameterized="true"/> <element name="targetEllipsis" type="button" selector="//li[{{var}}]//a[@class='label'][text() = '...']" parameterized="true"/> <element name="targetInput" type="input" selector="input#conditions__{{var1}}--{{var2}}__value" parameterized="true"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductOptionData.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductOptionData.xml index 7555337db8e02..f231d74b70dad 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductOptionData.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductOptionData.xml @@ -14,4 +14,11 @@ <requiredEntity type="ValueIndex">ValueIndex1</requiredEntity> <requiredEntity type="ValueIndex">ValueIndex2</requiredEntity> </entity> + <entity name="ConfigurableProductThreeOptions" type="ConfigurableProductOption"> + <var key="attribute_id" entityKey="attribute_id" entityType="ProductAttribute" /> + <data key="label">option</data> + <requiredEntity type="ValueIndex">ValueIndex1</requiredEntity> + <requiredEntity type="ValueIndex">ValueIndex2</requiredEntity> + <requiredEntity type="ValueIndex">ValueIndex3</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ValueIndexData.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ValueIndexData.xml index 2e4788823a28b..537ba2bbce086 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ValueIndexData.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ValueIndexData.xml @@ -14,4 +14,7 @@ <entity name="ValueIndex2" type="ValueIndex"> <var key="value_index" entityKey="value" entityType="ProductAttributeOption"/> </entity> + <entity name="ValueIndex3" type="ValueIndex"> + <var key="value_index" entityKey="value" entityType="ProductAttributeOption"/> + </entity> </entities> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml new file mode 100644 index 0000000000000..50e9e01d71131 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontSortingByPriceForConfigurableProductWithCatalogRuleAppliedTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="View soting by price in storefront"/> + <title value="Sorting by price for Configurable with Catalog Rule applied"/> + <description value="Sort by price should be correct if the apply Catalog Rule to child product of configurable product"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-69988"/> + <group value="ConfigurableProduct"/> + </annotations> + <before> + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">5.00</field> + </createData> + <createData entity="SimpleProduct" stepKey="createSimpleProduct2"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">10.00</field> + </createData> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption3" stepKey="createConfigProductAttributeOption3"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="3" stepKey="getConfigAttributeOption3"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <field key="price">15.00</field> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + <field key="price">20.00</field> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct3"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption3"/> + <field key="price">25.00</field> + </createData> + <createData entity="ConfigurableProductThreeOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + <requiredEntity createDataKey="getConfigAttributeOption3"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild3"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct3"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--SKU Product Attribute is enabled for Promo Rule Conditions--> + <actionGroup ref="navigateToEditProductAttribute" stepKey="navigateToSkuProductAttribute"> + <argument name="ProductAttribute" value="sku"/> + </actionGroup> + <actionGroup ref="changeUseForPromoRuleConditionsProductAttribute" stepKey="changeUseForPromoRuleConditionsProductAttributeToYes"> + <argument name="option" value="Yes"/> + </actionGroup> + </before> + + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigChildProduct3" stepKey="deleteConfigChildProduct3"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + + <!--SKU Product Attribute is disable for Promo Rule Conditions--> + <actionGroup ref="navigateToEditProductAttribute" stepKey="navigateToSkuProductAttribute"> + <argument name="ProductAttribute" value="sku"/> + </actionGroup> + <actionGroup ref="changeUseForPromoRuleConditionsProductAttribute" stepKey="changeUseForPromoRuleConditionsProductAttributeToNo"> + <argument name="option" value="No"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + </after> + + <!--Open category with products and Sort by price desc--> + <actionGroup ref="GoToStorefrontCategoryPageByParameters" stepKey="goToStorefrontCategoryPage"> + <argument name="category" value="$$createCategory.custom_attributes[url_key]$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="25"/> + <argument name="sortBy" value="price"/> + <argument name="sort" value="desc"/> + </actionGroup> + <see selector="{{StorefrontCategoryMainSection.lineProductName('1')}}" userInput="$$createConfigProduct.name$$" stepKey="seeConfigurableProduct"/> + <see selector="{{StorefrontCategoryMainSection.lineProductName('2')}}" userInput="$$createSimpleProduct2.name$$" stepKey="seeSimpleProductTwo"/> + <see selector="{{StorefrontCategoryMainSection.lineProductName('3')}}" userInput="$$createSimpleProduct.name$$" stepKey="seeSimpleProduct"/> + + <!--Create and apply catalog price rule--> + <actionGroup ref="newCatalogPriceRuleByUIWithConditionIsSKU" stepKey="createCatalogPriceRule"> + <argument name="catalogRule" value="CatalogRuleByPercentWith96Amount" /> + <argument name="productSku" value="$$createConfigChildProduct3.sku$$" /> + </actionGroup> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="clickSaveAndApplyRules"/> + + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + + <!--Reopen category with products and Sort by price desc--> + <actionGroup ref="GoToStorefrontCategoryPageByParameters" stepKey="goToStorefrontCategoryPage2"> + <argument name="category" value="$$createCategory.custom_attributes[url_key]$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="9"/> + <argument name="sortBy" value="price"/> + <argument name="sort" value="desc"/> + </actionGroup> + <see selector="{{StorefrontCategoryMainSection.lineProductName('1')}}" userInput="$$createSimpleProduct2.name$$" stepKey="seeSimpleProductTwo2"/> + <see selector="{{StorefrontCategoryMainSection.lineProductName('2')}}" userInput="$$createSimpleProduct.name$$" stepKey="seeSimpleProduct2"/> + <see selector="{{StorefrontCategoryMainSection.lineProductName('3')}}" userInput="$$createConfigProduct.name$$" stepKey="seeConfigurableProduct2"/> + + <!-- Delete the rule --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToPriceRulePage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRule"> + <argument name="name" value="{{CatalogRuleByPercentWith96Amount.name}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> + </actionGroup> + </test> +</tests> From d5f6ac4f2e64de9176702b5bd74dd31e9e55b668 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 27 Sep 2018 12:34:25 +0300 Subject: [PATCH 0231/1415] MAGETWO-91495: 'Invalid data provided for linked products' error on 'Save & Duplicate' product action - Fix statics --- app/code/Magento/Catalog/Model/Product/Copier.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index d86118eeca67a..87c5a47a7b85d 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -9,6 +9,9 @@ use Magento\Catalog\Api\Data\ProductInterface; +/** + * The copier creates product duplicates. + */ class Copier { /** @@ -95,6 +98,8 @@ public function copy(\Magento\Catalog\Model\Product $product) } /** + * Returns product option repository. + * * @return Option\Repository * @deprecated 101.0.0 */ @@ -108,6 +113,8 @@ private function getOptionRepository() } /** + * Returns metadata pool. + * * @return \Magento\Framework\EntityManager\MetadataPool * @deprecated 101.0.0 */ From 34672cf96616301faffeb24faacbaf2ddb24c2b5 Mon Sep 17 00:00:00 2001 From: Dmitriy Kogut <kogut.dmitriy@gmail.com> Date: Thu, 27 Sep 2018 12:56:18 +0300 Subject: [PATCH 0232/1415] MAGETWO-94892: Add Gift card to the cart from Requisition List --- .../Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml index 35ec242f05c52..bba73480d2db5 100644 --- a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml +++ b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml @@ -11,5 +11,6 @@ <section name="ModalConfirmationSection"> <element name="CancelButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-dismiss')]"/> <element name="OkButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-accept')]"/> + <element name="saveButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action primary confirm')]" timeout="30"/> </section> </sections> From 1c9295788e084da5ba748474d0170c555f8de82f Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Thu, 27 Sep 2018 13:52:04 +0300 Subject: [PATCH 0233/1415] MAGETWO-91785: Fixed incorrect order returns request flow --- .../Magento/Sales/Controller/AbstractController/Reorder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php index 2cd031c9f1f6e..65cb537e89fec 100644 --- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php +++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php @@ -11,7 +11,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface; /** - * Class Reorder + * Abstract class for controllers Reorder(Customer) and Reorder(Guest) * * @package Magento\Sales\Controller\AbstractController */ From 4a583f15631a04704e7856343576a03e1e778ccc Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 27 Sep 2018 14:05:23 +0300 Subject: [PATCH 0234/1415] MAGETWO-91495: 'Invalid data provided for linked products' error on 'Save & Duplicate' product action - Fix unit test - Refactoring --- app/code/Magento/Catalog/Model/Product.php | 5 +++++ app/code/Magento/Catalog/Model/Product/Copier.php | 7 ++++--- .../Catalog/Test/Unit/Model/Product/CopierTest.php | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 90af9bee270bd..f2d4b570f080a 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -72,6 +72,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements */ const STORE_ID = 'store_id'; + /** + * Product Url path. + */ + const URL_PATH = 'url_path'; + /** * @var string */ diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index 87c5a47a7b85d..ce6b4d98bbc9f 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -8,6 +8,7 @@ namespace Magento\Catalog\Model\Product; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product; /** * The copier creates product duplicates. @@ -52,7 +53,7 @@ public function __construct( * @param \Magento\Catalog\Model\Product $product * @return \Magento\Catalog\Model\Product */ - public function copy(\Magento\Catalog\Model\Product $product) + public function copy(Product $product) { $product->getWebsiteIds(); $product->getCategoryIds(); @@ -81,8 +82,8 @@ public function copy(\Magento\Catalog\Model\Product $product) $urlKey = preg_match('/(.*)-(\d+)$/', $urlKey, $matches) ? $matches[1] . '-' . ($matches[2] + 1) : $urlKey . '-1'; - $duplicate->setUrlKey($urlKey) - ->setUrlPath(null); + $duplicate->setUrlKey($urlKey); + $duplicate->setData(Product::URL_PATH, null); try { $duplicate->save(); $isDuplicateSaved = true; diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php index 31fd0696db320..e9eee5c766883 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php @@ -7,6 +7,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use \Magento\Catalog\Model\Product\Copier; +use Magento\Catalog\Model\Product; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -54,7 +55,7 @@ protected function setUp() \Magento\Catalog\Model\Product\Option\Repository::class ); $this->optionRepositoryMock; - $this->productMock = $this->createMock(\Magento\Catalog\Model\Product::class); + $this->productMock = $this->createMock(Product::class); $this->productMock->expects($this->any())->method('getEntityId')->willReturn(1); $this->metadata = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadata::class) @@ -106,7 +107,7 @@ public function testCopy() $this->productMock->expects($this->once())->method('getResource')->will($this->returnValue($resourceMock)); $duplicateMock = $this->createPartialMock( - \Magento\Catalog\Model\Product::class, + Product::class, [ '__wakeup', 'setData', @@ -147,10 +148,10 @@ public function testCopy() )->with( \Magento\Store\Model\Store::DEFAULT_STORE_ID ); - $duplicateMock->expects($this->once())->method('setData')->with($productData); + $duplicateMock->expects($this->atLeastOnce())->method('setData')->willReturn($duplicateMock); $this->copyConstructorMock->expects($this->once())->method('build')->with($this->productMock, $duplicateMock); $duplicateMock->expects($this->once())->method('getUrlKey')->willReturn('urk-key-1'); - $duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2'); + $duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2')->willReturn($duplicateMock); $duplicateMock->expects($this->once())->method('save'); $this->metadata->expects($this->any())->method('getLinkField')->willReturn('linkField'); From bba7e3525d99eca28f3966af6732b7b41ae01493 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Thu, 27 Sep 2018 15:10:36 +0400 Subject: [PATCH 0235/1415] MAGETWO-91733: Unusual behavior with the persistent shopping cart after the session is expired - Add automated test --- ...ingCartBehaviorAfterSessionExpiredTest.xml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml new file mode 100644 index 0000000000000..c66a2979aa7f5 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CheckShoppingCartBehaviorAfterSessionExpiredTest"> + <annotations> + <features value="Persistent"/> + <stories value="MAGETWO-91733 - Unusual behavior with the persistent shopping cart after the session is expired"/> + <title value="Checking behavior with the persistent shopping cart after the session is expired"/> + <description value="Checking behavior with the persistent shopping cart after the session is expired"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95118"/> + <group value="persistent"/> + </annotations> + <before> + <!--Enable Persistence--> + <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> + <!--Create product--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create new customer --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <!--Add shipping information--> + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!--Roll back configuration--> + <createData entity="PersistentConfigDefault" stepKey="setDefaultPersistentState"/> + <!--Delete product--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + </after> + <!-- Add simple product to cart --> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart1"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToShoppingCartFromMinicart"/> + <!--Reset cookies and refresh the page--> + <resetCookie userInput="PHPSESSID" stepKey="resetCookieForCart"/> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!--Check product exists in cart--> + <see userInput="$$createProduct.name$$" stepKey="ProductExistsInCart"/> + </test> +</tests> From 4c76f9a441a564ade8e904cd99eed0827162ff9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antun=20Matanovi=C4=87?= <antun.matanovic@gmail.com> Date: Thu, 27 Sep 2018 13:15:39 +0200 Subject: [PATCH 0236/1415] save the custom option price when it is 0 --- .../CatalogImportExport/Model/Import/Product/Option.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index c7eb722050303..fa2853c738624 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -1794,7 +1794,8 @@ protected function _getSpecificTypeData(array $rowData, $optionTypeId, $defaultS ]; $priceData = false; - if (!empty($rowData[self::COLUMN_ROW_PRICE])) { + $customOptionRowPrice = $rowData[self::COLUMN_ROW_PRICE]; + if (!empty($customOptionRowPrice) || $customOptionRowPrice === '0') { $priceData = [ 'price' => (double)rtrim($rowData[self::COLUMN_ROW_PRICE], '%'), 'price_type' => 'fixed', From 74ca77ca8023516fea3be1c4eb4714d6f63b791b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antun=20Matanovi=C4=87?= <antun.matanovic@gmail.com> Date: Thu, 27 Sep 2018 13:37:51 +0200 Subject: [PATCH 0237/1415] updated the tests --- .../Magento/CatalogImportExport/Model/Import/ProductTest.php | 2 +- .../Model/Import/_files/product_with_custom_options_new.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index c5e704c2434b5..a33d460a50756 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -431,7 +431,7 @@ public function getBehaviorDataProvider(): array 'Append behavior with new product' => [ 'importFile' => 'product_with_custom_options_new.csv', 'sku' => 'simple_new', - 'expectedOptionsQty' => 4, + 'expectedOptionsQty' => 5, ], ]; } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv index 7fe8832cd5804..f276a96cd1d38 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv @@ -1,2 +1,2 @@ sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,"New Product",,,,1,"Taxable Goods","Catalog, Search",10.0000,,,,new-product,"New Product","New Product","New Product ",,,,,,,"2015-10-20 07:05:38","2015-10-20 07:05:38",,,"Block after Info Column",,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,0,1,1.0000,0,0,0,1,,,,,,,"name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-1-radio,option_title=Option 1|name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-2-radio,option_title=Option 2|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-1-select,option_title=Option 1|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-2-select,option_title=Option2|name=Test Date and Time Title,type=date_time,required=1,price=2.0000,price_type=fixed,sku=2-date|name=Test Field Title,type=field,required=1,price=0.0000,price_type=fixed,sku=1-text,max_characters=10",,,,,, +simple_new,,Default,simple,,base,"New Product",,,,1,"Taxable Goods","Catalog, Search",10.0000,,,,new-product,"New Product","New Product","New Product ",,,,,,,"2015-10-20 07:05:38","2015-10-20 07:05:38",,,"Block after Info Column",,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,0,1,1.0000,0,0,0,1,,,,,,,"name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-1-radio,option_title=Option 1|name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-2-radio,option_title=Option 2|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-1-select,option_title=Option 1|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-2-select,option_title=Option2|name=Test Date and Time Title,type=date_time,required=1,price=2.0000,price_type=fixed,sku=2-date|name=Test Field Title,type=field,required=1,price=0.0000,price_type=fixed,sku=1-text,max_characters=10|name=New Select With Zero Price,type=drop_down,required=1,price=0,price_type=fixed,sku=3-1-select,option_title=Option 1",,,,,, From 1beb99d37ddec7112105303bd98ac8c340ff0d7b Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 27 Sep 2018 14:28:13 +0300 Subject: [PATCH 0238/1415] MAGETWO-59789: Image Swatch size change not working - Add swatch image config size --- .../Swatches/view/frontend/web/js/swatch-renderer.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 853eba3c98df2..802260f0a4085 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -501,7 +501,9 @@ define([ label, width, height, - attr; + attr, + swatchImageWidth, + swatchImageHeight; if (!optionConfig.hasOwnProperty(this.id)) { return ''; @@ -534,6 +536,9 @@ define([ ' thumb-width="' + width + '"' + ' thumb-height="' + height + '"'; + swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30; + swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20; + if (!this.hasOwnProperty('products') || this.products.length <= 0) { attr += ' option-empty="true"'; } @@ -552,7 +557,7 @@ define([ // Image html += '<div class="' + optionClass + ' image" ' + attr + ' style="background: url(' + value + ') no-repeat center; background-size: initial;width:' + - sizeConfig.swatchImage.width + 'px; height:' + sizeConfig.swatchImage.height + 'px">' + '' + + swatchImageWidth + 'px; height:' + swatchImageHeight + 'px">' + '' + '</div>'; } else if (type === 3) { // Clear From a83eb8fef8805c9c1515d768373d233fd758655f Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 27 Sep 2018 12:09:17 +0300 Subject: [PATCH 0239/1415] MAGETWO-91553: Admin user with role scope set to custom is unable to view abandoned carts report - Fix statics --- .../Magento/Reports/Model/ResourceModel/Quote/Collection.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php index 251326415a514..c1c6fb2eaed88 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Quote/Collection.php @@ -8,6 +8,8 @@ use Magento\Store\Model\Store; /** + * Collection of abandoned quotes with reports join. + * * @api * @since 100.0.2 */ From 5d5ae032b48280118d8681a30d9d4abd1d2027fb Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 27 Sep 2018 15:16:51 +0300 Subject: [PATCH 0240/1415] MAGETWO-91679: Bundled SKUs are being assembled based on the product ID number - Fixed an issue with incorrect genereation of dynamic SKU for bundle products; --- app/code/Magento/Bundle/Model/Product/Type.php | 7 +++++-- .../Bundle/Test/Unit/Model/Product/TypeTest.php | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 92bada8094c7e..67441cd944c4f 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -308,8 +308,11 @@ public function getSku($product) $selectionIds = $this->serializer->unserialize($customOption->getValue()); if (!empty($selectionIds)) { $selections = $this->getSelectionsByIds($selectionIds, $product); - foreach ($selections->getItems() as $selection) { - $skuParts[] = $selection->getSku(); + foreach ($selectionIds as $selectionId) { + $entity = $selections->getItemByColumnValue('selection_id', $selectionId); + if ($entity->getEntityId()) { + $skuParts[] = $entity->getSku(); + } } } } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php index 4bbf5641c55d3..1b9cafbe8c198 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php @@ -1595,7 +1595,7 @@ public function testGetSkuWithoutType() ->disableOriginalConstructor() ->getMock(); $selectionItemMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->setMethods(['getSku', '__wakeup']) + ->setMethods(['getSku', 'getEntityId', '__wakeup']) ->disableOriginalConstructor() ->getMock(); @@ -1623,9 +1623,12 @@ public function testGetSkuWithoutType() ->will($this->returnValue($serializeIds)); $selectionMock = $this->getSelectionsByIdsMock($selectionIds, $productMock, 5, 6); $selectionMock->expects(($this->any())) - ->method('getItems') - ->will($this->returnValue([$selectionItemMock])); - $selectionItemMock->expects($this->any()) + ->method('getItemByColumnValue') + ->will($this->returnValue($selectionItemMock)); + $selectionItemMock->expects($this->at(0)) + ->method('getEntityId') + ->will($this->returnValue(1)); + $selectionItemMock->expects($this->once()) ->method('getSku') ->will($this->returnValue($itemSku)); From 8b31f307ac263d6b89c18c440c44acfb3266a868 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 27 Sep 2018 16:00:19 +0300 Subject: [PATCH 0241/1415] MAGETWO-67779: Datetime attribute break fulltextsearch in case of Elasticseach - Fixed static and integration tests --- .../Elasticsearch5/Model/Adapter/FieldType.php | 2 ++ .../Elasticsearch/Model/Adapter/FieldType.php | 2 ++ .../Elasticsearch/SearchAdapter/AdapterTest.php | 13 +++++++++++++ 3 files changed, 17 insertions(+) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index 855ebbb76393c..9bf67954cc28f 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -28,6 +28,8 @@ class FieldType /**#@-*/ /** + * Get field type by attribute + * * @param AbstractAttribute $attribute * @return string * @since 100.1.0 diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 28587bca3cc85..0ad4ad8ec7970 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -27,6 +27,8 @@ class FieldType /**#@-*/ /** + * Get field type by attribute + * * @param AbstractAttribute $attribute * @return string * @since 100.1.0 diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php index d3fba768e9ff4..38bc35bda39ac 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php @@ -358,4 +358,17 @@ private function reindexAll() $indexer->load('catalogsearch_fulltext'); $indexer->reindexAll(); } + + /** + * Date data provider + * + * @return array + */ + public function dateDataProvider() + { + return [ + [['from' => '1999-12-31T00:00:00Z', 'to' => '2000-01-01T00:00:00Z'], 1], + [['from' => '2000-02-01T00:00:00Z', 'to' => ''], 0], + ]; + } } From 27474ec6be80104d0b78231719610dacc5de7f2b Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 25 Sep 2018 15:17:21 +0300 Subject: [PATCH 0242/1415] MAGETWO-91764: Frontend base url https results in admin too many redirects #8800 - Fixed an issue with cyclic redirects when using 'custom admin url' and 'secure urls in admin'. --- .../Magento/Backend/Model/AdminPathConfig.php | 38 ++++++++-------- .../Test/Unit/Model/AdminPathConfigTest.php | 44 +++++++++++++------ 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Backend/Model/AdminPathConfig.php b/app/code/Magento/Backend/Model/AdminPathConfig.php index e7338adca4a2a..0e77835a5134c 100644 --- a/app/code/Magento/Backend/Model/AdminPathConfig.php +++ b/app/code/Magento/Backend/Model/AdminPathConfig.php @@ -48,10 +48,7 @@ public function __construct( } /** - * {@inheritdoc} - * - * @param \Magento\Framework\App\RequestInterface $request - * @return string + * @inheritdoc */ public function getCurrentSecureUrl(\Magento\Framework\App\RequestInterface $request) { @@ -59,28 +56,29 @@ public function getCurrentSecureUrl(\Magento\Framework\App\RequestInterface $req } /** - * {@inheritdoc} - * - * @param string $path - * @return bool + * @inheritdoc */ public function shouldBeSecure($path) { - return parse_url( - (string)$this->coreConfig->getValue(Store::XML_PATH_UNSECURE_BASE_URL, 'default'), - PHP_URL_SCHEME - ) === 'https' - || $this->backendConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML) - && parse_url( - (string)$this->coreConfig->getValue(Store::XML_PATH_SECURE_BASE_URL, 'default'), - PHP_URL_SCHEME - ) === 'https'; + $baseUrl = (string)$this->coreConfig->getValue(Store::XML_PATH_UNSECURE_BASE_URL, 'default'); + if (parse_url($baseUrl, PHP_URL_SCHEME) === 'https') { + return true; + } + + if ($this->backendConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML)) { + if ($this->backendConfig->isSetFlag('admin/url/use_custom')) { + $adminBaseUrl = (string)$this->coreConfig->getValue('admin/url/custom', 'default'); + } else { + $adminBaseUrl = (string)$this->coreConfig->getValue(Store::XML_PATH_SECURE_BASE_URL, 'default'); + } + return parse_url($adminBaseUrl, PHP_URL_SCHEME) === 'https'; + } + + return false; } /** - * {@inheritdoc} - * - * @return string + * @inheritdoc */ public function getDefaultPath() { diff --git a/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php b/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php index 4911dc1e9968e..b373459b7864d 100644 --- a/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php +++ b/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php @@ -76,17 +76,35 @@ public function testGetCurrentSecureUrl() * @param $unsecureBaseUrl * @param $useSecureInAdmin * @param $secureBaseUrl + * @param $useCustomUrl + * @param $customUrl * @param $expected * @dataProvider shouldBeSecureDataProvider */ - public function testShouldBeSecure($unsecureBaseUrl, $useSecureInAdmin, $secureBaseUrl, $expected) - { - $coreConfigValueMap = [ + public function testShouldBeSecure( + $unsecureBaseUrl, + $useSecureInAdmin, + $secureBaseUrl, + $useCustomUrl, + $customUrl, + $expected + ) { + $coreConfigValueMap = $this->returnValueMap([ [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, 'default', null, $unsecureBaseUrl], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, 'default', null, $secureBaseUrl], - ]; - $this->coreConfig->expects($this->any())->method('getValue')->will($this->returnValueMap($coreConfigValueMap)); - $this->backendConfig->expects($this->any())->method('isSetFlag')->willReturn($useSecureInAdmin); + ['admin/url/custom', 'default', null, $customUrl], + ]); + $backendConfigFlagsMap = $this->returnValueMap([ + [\Magento\Store\Model\Store::XML_PATH_SECURE_IN_ADMINHTML, $useSecureInAdmin], + ['admin/url/use_custom', $useCustomUrl], + ]); + $this->coreConfig->expects($this->atLeast(1))->method('getValue') + ->will($coreConfigValueMap); + $this->coreConfig->expects($this->atMost(2))->method('getValue') + ->will($coreConfigValueMap); + + $this->backendConfig->expects($this->atMost(2))->method('isSetFlag') + ->will($backendConfigFlagsMap); $this->assertEquals($expected, $this->adminPathConfig->shouldBeSecure('')); } @@ -96,13 +114,13 @@ public function testShouldBeSecure($unsecureBaseUrl, $useSecureInAdmin, $secureB public function shouldBeSecureDataProvider() { return [ - ['http://localhost/', false, 'default', false], - ['http://localhost/', true, 'default', false], - ['https://localhost/', false, 'default', true], - ['https://localhost/', true, 'default', true], - ['http://localhost/', false, 'https://localhost/', false], - ['http://localhost/', true, 'https://localhost/', true], - ['https://localhost/', true, 'https://localhost/', true], + ['http://localhost/', false, 'default', false, '', false], + ['http://localhost/', true, 'default', false, '', false], + ['https://localhost/', false, 'default', false, '', true], + ['https://localhost/', true, 'default', false, '', true], + ['http://localhost/', false, 'https://localhost/', false, '', false], + ['http://localhost/', true, 'https://localhost/', false, '', true], + ['https://localhost/', true, 'https://localhost/', false, '', true], ]; } From 3d34a3c74d78929d76bdaa3944b6e371be147d09 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 27 Sep 2018 17:03:01 +0300 Subject: [PATCH 0243/1415] MAGETWO-94989: [2.3] Magnifier function does not disappear after mouse-off the image from the bottom --- lib/web/magnifier/magnifier.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index 150c8adf0b22b..55646aa9b4af2 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -554,6 +554,15 @@ thumbObj.src = thumb.src; } + /** + * Hide magnifier when mouse exceeds image bounds. + */ + function onMouseLeave() { + onThumbLeave(); + isOverThumb = false; + $magnifierPreview.addClass(MagnifyCls.magnifyHidden); + } + function onMousemove(e) { pos.x = e.clientX; pos.y = e.clientY; @@ -564,20 +573,13 @@ isOverThumb = inBounds; } - if (inBounds && isOverThumb) { - if(gMode === 'outside'){ - $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); - } + if (inBounds && isOverThumb && gMode === 'outside') { + $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); move(); - } else { - onThumbLeave(); - isOverThumb = false; - $magnifierPreview.addClass(MagnifyCls.magnifyHidden); } } function onScroll() { - if (curThumb !== null) { setThumbData(curThumb, magnifierOptions); } @@ -589,6 +591,8 @@ }); $box.on('mousemove', onMousemove); + $box.on('mouseleave', onMouseLeave); + _init($box, customUserOptions); } }(jQuery)); From 32058c748731348e7d38cffa7a6c56113e17b3d8 Mon Sep 17 00:00:00 2001 From: David Alger <davidmalger@gmail.com> Date: Thu, 27 Sep 2018 10:44:27 -0500 Subject: [PATCH 0244/1415] Update colinmollenhour/cache-backend-redis from version 1.10.5 to 1.10.6 See colinmollenhour/Cm_Cache_Backend_Redis#134 for details on updates to library --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index e2a646275d98b..dfd7bfb5aa9ec 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "lib-libxml": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", - "colinmollenhour/cache-backend-redis": "1.10.5", + "colinmollenhour/cache-backend-redis": "1.10.6", "colinmollenhour/credis": "1.10.0", "colinmollenhour/php-redis-session-abstract": "~1.4.0", "composer/composer": "^1.6", diff --git a/composer.lock b/composer.lock index 2550f70f0be81..849366434dbf4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18982aa4d36bcfd22cf073dfb578efdb", + "content-hash": "dcecc6ef5197bb32c59c7ba1f5d136ac", "packages": [ { "name": "braintree/braintree_php", @@ -88,16 +88,16 @@ }, { "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.5", + "version": "1.10.6", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b" + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/91d949e28d939e607484a4bbf9307cff5afa689b", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/cc941a5f4cc017e11d3eab9061811ba9583ed6bf", + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2018-05-15T16:02:25+00:00" + "time": "2018-09-24T16:02:07+00:00" }, { "name": "colinmollenhour/credis", From 33bda6c97d29ff0d3aa4ceb9acfc575ab085aed3 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 27 Sep 2018 11:07:21 -0500 Subject: [PATCH 0245/1415] MC-4277: Address Product Page slowness due to 'product_data_storage' handling - fix tests --- .../js/product/storage/data-storage.test.js | 9 ++++++--- .../js/product/storage/ids-storage.test.js | 15 ++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/data-storage.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/data-storage.test.js index fdd0b70997f35..0ab6b5fdf2b99 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/data-storage.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/data-storage.test.js @@ -49,6 +49,7 @@ define([ injector.clean(); injector.remove(); } catch (e) {} + window.localStorage.clear(); }); describe('Magento_Catalog/js/product/storage/data-storage', function () { @@ -88,18 +89,20 @@ define([ }; }); + afterEach(function () { + window.localStorage.clear(); + }); + it('check calls "dataHandler" method with data', function () { var data = { property: 'value' }; obj.dataHandler(data); - expect(obj.localStorage.set).toHaveBeenCalledWith(data); - expect(obj.localStorage.removeAll).not.toHaveBeenCalled(); + expect(window.localStorage.getItem(obj.namespace)).toBe(JSON.stringify(data)); }); it('check calls "dataHandler" method with empty data', function () { obj.dataHandler({}); - expect(obj.localStorage.set).not.toHaveBeenCalled(); expect(obj.localStorage.removeAll).toHaveBeenCalled(); }); }); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/ids-storage.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/ids-storage.test.js index c394a2463f5e2..624b159163bcb 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/ids-storage.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/frontend/js/product/storage/ids-storage.test.js @@ -27,6 +27,7 @@ define([ injector.clean(); injector.remove(); } catch (e) {} + window.localStorage.clear(); }); describe('Magento_Catalog/js/product/storage/ids-storage', function () { @@ -40,13 +41,6 @@ define([ expect(obj.localStorage.get).toHaveBeenCalled(); }); }); - describe('"cachesDataFromLocalStorage" method', function () { - it('check calls localStorage get method', function () { - obj.getDataFromLocalStorage = jasmine.createSpy().and.returnValue({}); - - expect(obj.localStorage.get).toHaveBeenCalled(); - }); - }); describe('"initLocalStorage" method', function () { it('check returned value', function () { obj.namespace = 'test'; @@ -80,17 +74,16 @@ define([ it('check calls with data that equal with data in localStorage', function () { obj.internalDataHandler(data); - expect(obj.localStorage.get).toHaveBeenCalled(); - expect(obj.localStorage.set).not.toHaveBeenCalled(); + expect(window.localStorage.getItem(obj.namespace)).toBe(JSON.stringify(data)); }); it('check calls with data that not equal with data in localStorage', function () { var emptyData = {}; + obj.internalDataHandler(data); obj.internalDataHandler(emptyData); - expect(obj.localStorage.get).toHaveBeenCalled(); - expect(obj.localStorage.set).toHaveBeenCalledWith(emptyData); + expect(window.localStorage.getItem(obj.namespace)).toBe(JSON.stringify(emptyData)); }); }); describe('"externalDataHandler" method', function () { From 5aab5421697039e56993f84d88e2b6db4a2242da Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 26 Sep 2018 21:12:12 +0300 Subject: [PATCH 0246/1415] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Provide information from database to set to browser local storage if local storage is empty. --- .../Checkout/Model/DefaultConfigProvider.php | 53 +++++++++++++++++-- .../web/js/model/checkout-data-resolver.js | 13 ++++- .../web/js/view/form/element/email.js | 7 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php index ea6cdd2e51b4a..fd120f0a37a4b 100644 --- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php +++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php @@ -14,6 +14,7 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Customer\Model\Url as CustomerUrlManager; use Magento\Eav\Api\AttributeOptionManagementInterface; +use Magento\Framework\Api\CustomAttributesDataInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Http\Context as HttpContext; use Magento\Framework\App\ObjectManager; @@ -22,9 +23,11 @@ use Magento\Framework\UrlInterface; use Magento\Quote\Api\CartItemRepositoryInterface as QuoteItemRepository; use Magento\Quote\Api\CartTotalRepositoryInterface; +use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\ShippingMethodManagementInterface as ShippingMethodManager; use Magento\Quote\Model\QuoteIdMaskFactory; use Magento\Store\Model\ScopeInterface; +use Magento\Ui\Component\Form\Element\Multiline; /** * Default Config Provider @@ -272,16 +275,28 @@ public function __construct( * * @return array|mixed * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException */ public function getConfig() { - $quoteId = $this->checkoutSession->getQuote()->getId(); + $quote = $this->checkoutSession->getQuote(); + $quoteId = $quote->getId(); + $email = $quote->getShippingAddress()->getEmail(); $output['formKey'] = $this->formKey->getFormKey(); $output['customerData'] = $this->getCustomerData(); $output['quoteData'] = $this->getQuoteData(); $output['quoteItemData'] = $this->getQuoteItemData(); $output['isCustomerLoggedIn'] = $this->isCustomerLoggedIn(); $output['selectedShippingMethod'] = $this->getSelectedShippingMethod(); + if ($email && !$this->isCustomerLoggedIn()) { + $shippingAddressFromData = $this->getAddressFromData($quote->getShippingAddress()); + $billingAddressFromData = $this->getAddressFromData($quote->getBillingAddress()); + $output['shippingAddressFromData'] = $shippingAddressFromData; + if ($shippingAddressFromData != $billingAddressFromData) { + $output['billingAddressFromData'] = $billingAddressFromData; + } + $output['validatedEmailValue'] = $email; + } $output['storeCode'] = $this->getStoreCode(); $output['isGuestCheckoutAllowed'] = $this->isGuestCheckoutAllowed(); $output['isCustomerLoginRequired'] = $this->isCustomerLoginRequired(); @@ -293,11 +308,11 @@ public function getConfig() $output['staticBaseUrl'] = $this->getStaticBaseUrl(); $output['priceFormat'] = $this->localeFormat->getPriceFormat( null, - $this->checkoutSession->getQuote()->getQuoteCurrencyCode() + $quote->getQuoteCurrencyCode() ); $output['basePriceFormat'] = $this->localeFormat->getPriceFormat( null, - $this->checkoutSession->getQuote()->getBaseCurrencyCode() + $quote->getBaseCurrencyCode() ); $output['postCodes'] = $this->postCodesConfig->getPostCodes(); $output['imageData'] = $this->imageProvider->getImages($quoteId); @@ -528,6 +543,38 @@ private function getSelectedShippingMethod() return $shippingMethodData; } + /** + * Create address data appropriate to fill checkout address form + * + * @param AddressInterface $address + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getAddressFromData(AddressInterface $address) + { + $addressData = []; + $attributesMetadata = $this->addressMetadata->getAllAttributesMetadata(); + foreach ($attributesMetadata as $attributeMetadata) { + if (!$attributeMetadata->isVisible()) { + continue; + } + $attributeCode = $attributeMetadata->getAttributeCode(); + $attributeData = $address->getData($attributeCode); + if ($attributeData) { + if ($attributeMetadata->getFrontendInput() === Multiline::NAME) { + $attributeData = \is_array($attributeData) ? $attributeData : explode("\n", $attributeData); + $attributeData = (object)$attributeData; + } + if ($attributeMetadata->isUserDefined()) { + $addressData[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][$attributeCode] = $attributeData; + continue; + } + $addressData[$attributeCode] = $attributeData; + } + } + return $addressData; + } + /** * Retrieve store code * diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 73f4df567903c..25abe3c4ed3a0 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -60,13 +60,18 @@ define([ this.resolveBillingAddress(); } } - }, /** * Resolve shipping address. Used local storage */ resolveShippingAddress: function () { + if (!checkoutData.getShippingAddressFromData() && + window.checkoutConfig.shippingAddressFromData + ) { + checkoutData.setShippingAddressFromData(window.checkoutConfig.shippingAddressFromData); + } + var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); if (newCustomerShippingAddress) { @@ -196,6 +201,12 @@ define([ * Resolve billing address. Used local storage */ resolveBillingAddress: function () { + if (!checkoutData.getBillingAddressFromData() && + window.checkoutConfig.billingAddressFromData + ) { + checkoutData.setBillingAddressFromData(window.checkoutConfig.billingAddressFromData); + } + var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 4a25778e754c7..6c0075fca6d51 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -17,6 +17,13 @@ define([ ], function ($, Component, ko, customer, checkEmailAvailability, loginAction, quote, checkoutData, fullScreenLoader) { 'use strict'; + if (!checkoutData.getValidatedEmailValue() && + window.checkoutConfig.validatedEmailValue + ) { + checkoutData.setInputFieldEmailValue(window.checkoutConfig.validatedEmailValue); + checkoutData.setValidatedEmailValue(window.checkoutConfig.validatedEmailValue); + } + var validatedEmail = checkoutData.getValidatedEmailValue(); if (validatedEmail && !customer.isLoggedIn()) { From 77ec759a758eb80aceb28a67ab65d46846e38d78 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Thu, 27 Sep 2018 21:14:23 +0300 Subject: [PATCH 0247/1415] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Changed behaviour for "skip-errors" processing during import shceduling --- .../CatalogImportExport/Model/Import/Product.php | 7 +++++-- app/code/Magento/ImportExport/Model/Import.php | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index b755d91e403ff..d85c64327be60 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1623,8 +1623,11 @@ protected function _saveProducts() continue; } if ($this->getErrorAggregator()->hasToBeTerminated()) { - $this->getErrorAggregator()->addRowToSkip($rowNum); - continue; + $validationStrategy = $this->_parameters[Import::FIELD_NAME_VALIDATION_STRATEGY]; + if (ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS !== $validationStrategy) { + $this->getErrorAggregator()->addRowToSkip($rowNum); + continue; + } } $rowScope = $this->getRowScope($rowData); diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index b5e8220e0e9b0..064c696ad0a84 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -181,7 +181,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel * @param Source\Import\Behavior\Factory $behaviorFactory * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry * @param History $importHistoryModel - * @param \Magento\Framework\Stdlib\DateTime\DateTime + * @param \Magento\Framework\Stdlib\DateTime\DateTime $localeDate * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -443,6 +443,8 @@ public function importSource() } /** + * Processing of import. + * * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ @@ -462,6 +464,8 @@ public function isImportAllowed() } /** + * Get error aggregator instance. + * * @return ProcessingErrorAggregatorInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -585,6 +589,11 @@ public function validateSource(\Magento\ImportExport\Model\Import\AbstractSource $this->addLogComment($messages); $result = !$errorAggregator->getErrorsCount(); + $validationStrategy = $this->getData(self::FIELD_NAME_VALIDATION_STRATEGY); + if ($validationStrategy === ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS) { + $result = true; + } + if ($result) { $this->addLogComment(__('Import data validation is complete.')); } @@ -710,9 +719,9 @@ public function isReportEntityType($entity = null) /** * Create history report * + * @param string $sourceFileRelative * @param string $entity * @param string $extension - * @param string $sourceFileRelative * @param array $result * @return $this * @throws \Magento\Framework\Exception\LocalizedException From b76a01a15360dbd8f5b3c284fd32098d7d298200 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 17 Sep 2018 16:53:28 -0500 Subject: [PATCH 0248/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fix functional tests --- ...OrderCancelMassActionPartialFailMessage.php} | 17 +++++++++++++---- .../Test/TestCase/MassOrdersUpdateTest.xml | 12 ++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) rename dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/{AssertOrderCancelMassActionFailMessage.php => AssertOrderCancelMassActionPartialFailMessage.php} (60%) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php similarity index 60% rename from dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php rename to dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php index fffb0746d4967..6aed5cd39aaad 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php @@ -10,15 +10,20 @@ use Magento\Mtf\Constraint\AbstractConstraint; /** - * Class AssertOrderCancelMassActionFailMessage + * Class AssertOrderCancelAndSuccessMassActionFailMessage * Assert cancel fail message is displayed on order index page */ -class AssertOrderCancelMassActionFailMessage extends AbstractConstraint +class AssertOrderCancelMassActionPartialFailMessage extends AbstractConstraint { + /** + * Message displayed after cancel order from archive + */ + const SUCCESS_MESSAGE = 'We canceled 1 order(s).'; + /** * Text value to be checked */ - const FAIL_CANCEL_MESSAGE = 'You cannot cancel the order(s).'; + const FAIL_CANCEL_MESSAGE = '1 order(s) cannot be canceled.'; /** * Assert cancel fail message is displayed on order index page @@ -32,6 +37,10 @@ public function processAssert(OrderIndex $orderIndex) self::FAIL_CANCEL_MESSAGE, $orderIndex->getMessagesBlock()->getErrorMessage() ); + \PHPUnit\Framework\Assert::assertEquals( + self::SUCCESS_MESSAGE, + $orderIndex->getMessagesBlock()->getSuccessMessage() + ); } /** @@ -41,6 +50,6 @@ public function processAssert(OrderIndex $orderIndex) */ public function toString() { - return 'Cancel fail message is displayed on order index page.'; + return 'Cancel and success fail message is displayed on order index page.'; } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml index e6ab0ff5026b6..31d5c30d25fc7 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml @@ -18,12 +18,12 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation2"> - <data name="description" xsi:type="string">try to cancel orders in status Complete, Closed</data> + <data name="description" xsi:type="string">try to cancel orders in status Complete, Canceled</data> <data name="steps" xsi:type="string">invoice, shipment|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> - <data name="resultStatuses" xsi:type="string">Complete,Processing</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionFailMessage" /> + <data name="resultStatuses" xsi:type="string">Complete,Canceled</data> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionPartialFailMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation3"> @@ -31,8 +31,8 @@ <data name="steps" xsi:type="string">invoice|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> - <data name="resultStatuses" xsi:type="string">Processing,Closed</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionFailMessage" /> + <data name="resultStatuses" xsi:type="string">Processing,Canceled</data> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionPartialFailMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation4"> @@ -55,7 +55,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation6"> - <data name="description" xsi:type="string">Release order in statuse On Hold</data> + <data name="description" xsi:type="string">Release order in status On Hold</data> <data name="steps" xsi:type="string">on hold</data> <data name="action" xsi:type="string">Unhold</data> <data name="ordersCount" xsi:type="string">1</data> From ed6995c7dfa5d35d57ec4f4df5a39b45b734b3bf Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 27 Sep 2018 16:39:17 -0500 Subject: [PATCH 0249/1415] MC-4277: Address Product Page slowness due to 'product_data_storage' handling - add localStorage support check --- .../web/js/product/storage/data-storage.js | 17 ++++++++++++++++- .../web/js/product/storage/ids-storage.js | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js index 0059cee60d30f..3dc9f3e844516 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/data-storage.js @@ -34,6 +34,21 @@ define([ }; } + /** + * Set data to localStorage with support check. + * + * @param {String} namespace + * @param {Object} data + */ + function setLocalStorageItem(namespace, data) { + try { + window.localStorage.setItem(namespace, JSON.stringify(data)); + } catch (e) { + console.warn('localStorage is unavailable - skipping local caching of product data'); + console.error(e); + } + } + return { /** @@ -118,7 +133,7 @@ define([ if (_.isEmpty(data)) { this.localStorage.removeAll(); } else { - window.localStorage.setItem(this.namespace, JSON.stringify(data)); + setLocalStorageItem(this.namespace, data); } }, diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js index f77bdd0263aa7..ec07c19a2c1b1 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/storage/ids-storage.js @@ -11,6 +11,21 @@ define([ ], function ($, _, ko, utils) { 'use strict'; + /** + * Set data to localStorage with support check. + * + * @param {String} namespace + * @param {Object} data + */ + function setLocalStorageItem(namespace, data) { + try { + window.localStorage.setItem(namespace, JSON.stringify(data)); + } catch (e) { + console.warn('localStorage is unavailable - skipping local caching of product data'); + console.error(e); + } + } + return { /** @@ -94,7 +109,7 @@ define([ * Initializes handler to "data" property update */ internalDataHandler: function (data) { - window.localStorage.setItem(this.namespace, JSON.stringify(data)); + setLocalStorageItem(this.namespace, data); }, /** From 4d19cd1964f51963aadc2a197853da3e4a70dd36 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Thu, 27 Sep 2018 22:25:27 -0700 Subject: [PATCH 0250/1415] MAGETWO-95174: Sorting by price for Configurable with Catalog Rule applied --- .../Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 + ...tSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 92aa55eedda09..c0a3c65d84d8a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -37,5 +37,6 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <selectOption selector="{{StorefrontPropertiesSection.useForPromoRuleConditions}}" userInput="{{option}}" stepKey="changeOption"/> <click selector="{{AttributePropertiesSection.Save}}" stepKey="saveAttribute"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the product attribute." stepKey="successMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml index 50e9e01d71131..a87780365c913 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml @@ -16,7 +16,7 @@ <description value="Sort by price should be correct if the apply Catalog Rule to child product of configurable product"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69988"/> - <group value="ConfigurableProduct"/> + <group value="сonfigurable_product"/> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategory"/> From 312449eb5672f67dd09f6804f1ddd61e714069d2 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Fri, 28 Sep 2018 13:27:10 +0600 Subject: [PATCH 0251/1415] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Added automated test --- .../ActionGroup/AdminCategoryActionGroup.xml | 24 ++++++- .../StorefrontCategoryActionGroup.xml | 15 +++++ ...iteStoreLevelUrlKeyOfChildCategoryTest.xml | 67 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml index 7c04e9bd83d56..b5b69cefff9a6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml @@ -237,8 +237,30 @@ </arguments> <amOnPage url="{{AdminCategoryPage.page}}" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(Category.Name)}}" stepKey="navigateToCreatedCategory" /> + <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandAll"/> <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(Category.Name)}}" stepKey="navigateToCreatedCategory" /> <waitForLoadingMaskToDisappear stepKey="waitForSpinner" /> </actionGroup> + + <actionGroup name="ChangeSeoUrlKey"> + <arguments> + <argument name="value" type="string"/> + </arguments> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{value}}" stepKey="enterURLKey"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessage"/> + </actionGroup> + + <actionGroup name="ChangeSeoUrlKeyForSubCategory"> + <arguments> + <argument name="value" type="string"/> + </arguments> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckDefaultValue"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{value}}" stepKey="enterURLKey"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index 4376e78242fbd..a8256b2d55937 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -50,4 +50,19 @@ <click selector="{{StorefrontCategoryMainSection.modeListButton}}" stepKey="switchCategoryViewToListMode"/> <waitForElement selector="{{StorefrontCategoryMainSection.CategoryTitle}}" time="30" stepKey="waitForCategoryReload"/> </actionGroup> + + <actionGroup name="GoToSubCategoryPage"> + <arguments> + <argument name="parentCategory"/> + <argument name="subCategory"/> + <argument name="urlPath" type="string"/> + </arguments> + <moveMouseOver selector="{{StorefrontHeaderSection.NavigationCategoryByName(parentCategory.name)}}" stepKey="moveMouseOnMainCategory"/> + <waitForElementVisible selector="{{StorefrontHeaderSection.NavigationCategoryByName(subCategory.name)}}" stepKey="waitForSubCategoryVisible"/> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName(subCategory.name)}}" stepKey="goToCategory"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <seeInCurrentUrl url="{{urlPath}}.html" stepKey="checkUrl"/> + <seeInTitle userInput="{{subCategory.name}}" stepKey="assertCategoryNameInTitle"/> + <see userInput="{{subCategory.name}}" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="assertCategoryName"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml new file mode 100644 index 0000000000000..67870c51140a6 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="RewriteStoreLevelUrlKeyOfChildCategoryTest"> + <annotations> + <title value="Rewriting Store-level URL key of child category"/> + <stories value="MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope"/> + <description value="Rewriting Store-level URL key of child category"/> + <features value="CatalogUrlRewrite"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94934"/> + <group value="CatalogUrlRewrite"/> + </annotations> + + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + + <createData entity="_defaultCategory" stepKey="defaultCategory"/> + <createData entity="SubCategoryWithParent" stepKey="subCategory"> + <requiredEntity createDataKey="defaultCategory"/> + </createData> + </before> + + <actionGroup ref="navigateToCreatedCategory" stepKey="navigateToCreatedSubCategory"> + <argument name="Category" value="$$subCategory$$"/> + </actionGroup> + + <actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchStoreViewForSubCategory"/> + + <actionGroup ref="ChangeSeoUrlKeyForSubCategory" stepKey="changeSeoUrlKeyForSubCategory"> + <argument name="value" value="bags-second"/> + </actionGroup> + + <actionGroup ref="navigateToCreatedCategory" stepKey="navigateToCreatedDefaultCategory"> + <argument name="Category" value="$$defaultCategory$$"/> + </actionGroup> + + <actionGroup ref="ChangeSeoUrlKey" stepKey="changeSeoUrlKeyForDefaultCategory"> + <argument name="value" value="gear-global"/> + </actionGroup> + + <amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToStorefrontPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + + <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="storefrontSwitchStoreView"/> + + <actionGroup ref="GoToSubCategoryPage" stepKey="goToSubCategoryPage"> + <argument name="parentCategory" value="$$defaultCategory$$"/> + <argument name="subCategory" value="$$subCategory$$"/> + <argument name="urlPath" value="gear-global/bags-second"/> + </actionGroup> + + <after> + <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"/> + <actionGroup ref="logout" stepKey="logout"/> + + <deleteData createDataKey="subCategory" stepKey="deleteSubCategory"/> + <deleteData createDataKey="defaultCategory" stepKey="deleteNewRootCategory"/> + </after> + </test> +</tests> From defc2c525c5e1f6df965f5b8460648b3bff5653a Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Fri, 28 Sep 2018 11:49:52 +0300 Subject: [PATCH 0252/1415] MAGETWO-91610: [2.3] Billing Address in Braintree PayPal response is absent - Added check if a billing address is returned by Braintree --- .../Model/Paypal/Helper/QuoteUpdater.php | 2 +- .../Model/Paypal/Helper/QuoteUpdaterTest.php | 214 +++++++++--------- 2 files changed, 107 insertions(+), 109 deletions(-) diff --git a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php index fe5895541543d..aa23fa767d1ed 100644 --- a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php +++ b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php @@ -148,7 +148,7 @@ private function updateBillingAddress(Quote $quote, array $details) { $billingAddress = $quote->getBillingAddress(); - if ($this->config->isRequiredBillingAddress()) { + if ($this->config->isRequiredBillingAddress() && !empty($details['billingAddress'])) { $this->updateAddressData($billingAddress, $details['billingAddress']); } else { $this->updateAddressData($billingAddress, $details['shippingAddress']); diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php index 62452228b6186..a2b5380d2884b 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php @@ -3,23 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Braintree\Test\Unit\Model\Paypal\Helper; -use Magento\Quote\Model\Quote; -use Magento\Quote\Model\Quote\Address; -use Magento\Quote\Model\Quote\Payment; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Braintree\Model\Ui\PayPal\ConfigProvider; -use Magento\Braintree\Observer\DataAssignObserver; use Magento\Braintree\Gateway\Config\PayPal\Config; use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater; +use Magento\Braintree\Model\Ui\PayPal\ConfigProvider; +use Magento\Braintree\Observer\DataAssignObserver; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\CartExtensionInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\Quote\Payment; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class QuoteUpdaterTest * - * @see \Magento\Braintree\Model\Paypal\Helper\QuoteUpdater - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase @@ -27,24 +28,24 @@ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase const TEST_NONCE = '3ede7045-2aea-463e-9754-cd658ffeeb48'; /** - * @var Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|MockObject */ - private $configMock; + private $config; /** - * @var CartRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var CartRepositoryInterface|MockObject */ - private $quoteRepositoryMock; + private $quoteRepository; /** - * @var Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ - private $billingAddressMock; + private $billingAddress; /** - * @var Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ - private $shippingAddressMock; + private $shippingAddress; /** * @var QuoteUpdater @@ -52,17 +53,17 @@ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase private $quoteUpdater; /** - * @return void + * @inheritdoc */ protected function setUp() { - $this->configMock = $this->getMockBuilder(Config::class) + $this->config = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); - $this->quoteRepositoryMock = $this->getMockBuilder(CartRepositoryInterface::class) + $this->quoteRepository = $this->getMockBuilder(CartRepositoryInterface::class) ->getMockForAbstractClass(); - $this->billingAddressMock = $this->getMockBuilder(Address::class) + $this->billingAddress = $this->getMockBuilder(Address::class) ->setMethods( [ 'setLastname', @@ -77,9 +78,10 @@ protected function setUp() 'setShouldIgnoreValidation', 'getEmail' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); - $this->shippingAddressMock = $this->getMockBuilder(Address::class) + $this->shippingAddress = $this->getMockBuilder(Address::class) ->setMethods( [ 'setLastname', @@ -93,61 +95,61 @@ protected function setUp() 'setPostcode', 'setShouldIgnoreValidation' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); $this->quoteUpdater = new QuoteUpdater( - $this->configMock, - $this->quoteRepositoryMock + $this->config, + $this->quoteRepository ); } /** - * @return void + * Checks if quote details can be update by the response from Braintree. + * * @throws \Magento\Framework\Exception\LocalizedException */ - public function testExecute() + public function testExecute(): void { $details = $this->getDetails(); - $quoteMock = $this->getQuoteMock(); - $paymentMock = $this->getPaymentMock(); + $quote = $this->getQuoteMock(); + $payment = $this->getPaymentMock(); - $quoteMock->expects(self::once()) - ->method('getPayment') - ->willReturn($paymentMock); + $quote->method('getPayment') + ->willReturn($payment); - $paymentMock->expects(self::once()) - ->method('setMethod') + $payment->method('setMethod') ->with(ConfigProvider::PAYPAL_CODE); - $paymentMock->expects(self::once()) - ->method('setAdditionalInformation') + $payment->method('setAdditionalInformation') ->with(DataAssignObserver::PAYMENT_METHOD_NONCE, self::TEST_NONCE); - $this->updateQuoteStep($quoteMock, $details); + $this->updateQuoteStep($quote, $details); - $this->quoteUpdater->execute(self::TEST_NONCE, $details, $quoteMock); + $this->quoteUpdater->execute(self::TEST_NONCE, $details, $quote); } /** + * Disables quote's addresses validation. + * * @return void */ - private function disabledQuoteAddressValidationStep() + private function disabledQuoteAddressValidationStep(): void { - $this->billingAddressMock->expects(self::once()) - ->method('setShouldIgnoreValidation') + $this->billingAddress->method('setShouldIgnoreValidation') ->with(true); - $this->shippingAddressMock->expects(self::once()) - ->method('setShouldIgnoreValidation') + $this->shippingAddress->method('setShouldIgnoreValidation') ->with(true); - $this->billingAddressMock->expects(self::once()) - ->method('getEmail') + $this->billingAddress->method('getEmail') ->willReturn('bt_buyer_us@paypal.com'); } /** + * Gets quote's details. + * * @return array */ - private function getDetails() + private function getDetails(): array { return [ 'email' => 'bt_buyer_us@paypal.com', @@ -177,54 +179,51 @@ private function getDetails() } /** + * Updates shipping address details. + * * @param array $details */ - private function updateShippingAddressStep(array $details) + private function updateShippingAddressStep(array $details): void { - $this->shippingAddressMock->expects(self::once()) - ->method('setLastname') + $this->shippingAddress->method('setLastname') ->with($details['lastName']); - $this->shippingAddressMock->expects(self::once()) - ->method('setFirstname') + $this->shippingAddress->method('setFirstname') ->with($details['firstName']); - $this->shippingAddressMock->expects(self::once()) - ->method('setEmail') + $this->shippingAddress->method('setEmail') ->with($details['email']); - $this->shippingAddressMock->expects(self::once()) - ->method('setCollectShippingRates') + $this->shippingAddress->method('setCollectShippingRates') ->with(true); - $this->updateAddressDataStep($this->shippingAddressMock, $details['shippingAddress']); + $this->updateAddressDataStep($this->shippingAddress, $details['shippingAddress']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $addressMock + * Updates address details. + * + * @param MockObject $address * @param array $addressData */ - private function updateAddressDataStep(\PHPUnit_Framework_MockObject_MockObject $addressMock, array $addressData) + private function updateAddressDataStep(MockObject $address, array $addressData): void { - $addressMock->expects(self::once()) - ->method('setStreet') + $address->method('setStreet') ->with([$addressData['streetAddress'], $addressData['extendedAddress']]); - $addressMock->expects(self::once()) - ->method('setCity') + $address->method('setCity') ->with($addressData['locality']); - $addressMock->expects(self::once()) - ->method('setRegionCode') + $address->method('setRegionCode') ->with($addressData['region']); - $addressMock->expects(self::once()) - ->method('setCountryId') + $address->method('setCountryId') ->with($addressData['countryCodeAlpha2']); - $addressMock->expects(self::once()) - ->method('setPostcode') + $address->method('setPostcode') ->with($addressData['postalCode']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $quoteMock + * Updates quote's address details. + * + * @param MockObject $quoteMock * @param array $details */ - private function updateQuoteAddressStep(\PHPUnit_Framework_MockObject_MockObject $quoteMock, array $details) + private function updateQuoteAddressStep(MockObject $quoteMock, array $details): void { $quoteMock->expects(self::exactly(2)) ->method('getIsVirtual') @@ -235,64 +234,61 @@ private function updateQuoteAddressStep(\PHPUnit_Framework_MockObject_MockObject } /** + * Updates billing address details. + * * @param array $details */ - private function updateBillingAddressStep(array $details) + private function updateBillingAddressStep(array $details): void { - $this->configMock->expects(self::once()) - ->method('isRequiredBillingAddress') + $this->config->method('isRequiredBillingAddress') ->willReturn(true); - $this->updateAddressDataStep($this->billingAddressMock, $details['billingAddress']); + $this->updateAddressDataStep($this->billingAddress, $details['billingAddress']); - $this->billingAddressMock->expects(self::once()) - ->method('setLastname') + $this->billingAddress->method('setLastname') ->with($details['lastName']); - $this->billingAddressMock->expects(self::once()) - ->method('setFirstname') + $this->billingAddress->method('setFirstname') ->with($details['firstName']); - $this->billingAddressMock->expects(self::once()) - ->method('setEmail') + $this->billingAddress->method('setEmail') ->with($details['email']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $quoteMock + * Updates quote details. + * + * @param MockObject $quote * @param array $details */ - private function updateQuoteStep(\PHPUnit_Framework_MockObject_MockObject $quoteMock, array $details) + private function updateQuoteStep(MockObject $quote, array $details): void { - $quoteMock->expects(self::once()) - ->method('setMayEditShippingAddress') + $quote->method('setMayEditShippingAddress') ->with(false); - $quoteMock->expects(self::once()) - ->method('setMayEditShippingMethod') + $quote->method('setMayEditShippingMethod') ->with(true); - $quoteMock->expects(self::exactly(2)) - ->method('getShippingAddress') - ->willReturn($this->shippingAddressMock); - $quoteMock->expects(self::exactly(2)) + $quote->method('getShippingAddress') + ->willReturn($this->shippingAddress); + $quote->expects(self::exactly(2)) ->method('getBillingAddress') - ->willReturn($this->billingAddressMock); + ->willReturn($this->billingAddress); - $this->updateQuoteAddressStep($quoteMock, $details); + $this->updateQuoteAddressStep($quote, $details); $this->disabledQuoteAddressValidationStep(); - $quoteMock->expects(self::once()) - ->method('collectTotals'); + $quote->method('collectTotals'); - $this->quoteRepositoryMock->expects(self::once()) - ->method('save') - ->with($quoteMock); + $this->quoteRepository->method('save') + ->with($quote); } /** - * @return Quote|\PHPUnit_Framework_MockObject_MockObject + * Creates a mock for Quote object. + * + * @return Quote|MockObject */ - private function getQuoteMock() + private function getQuoteMock(): MockObject { - $quoteMock = $this->getMockBuilder(Quote::class) + $quote = $this->getMockBuilder(Quote::class) ->setMethods( [ 'getIsVirtual', @@ -304,25 +300,27 @@ private function getQuoteMock() 'getBillingAddress', 'getExtensionAttributes' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); - $cartExtensionMock = $this->getMockBuilder(CartExtensionInterface::class) + $cartExtension = $this->getMockBuilder(CartExtensionInterface::class) ->setMethods(['setShippingAssignments']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $quoteMock->expects(self::any()) - ->method('getExtensionAttributes') - ->willReturn($cartExtensionMock); + $quote->method('getExtensionAttributes') + ->willReturn($cartExtension); - return $quoteMock; + return $quote; } /** - * @return Payment|\PHPUnit_Framework_MockObject_MockObject + * Creates a mock for Payment object. + * + * @return Payment|MockObject */ - private function getPaymentMock() + private function getPaymentMock(): MockObject { return $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() From 5ac4cf3e6b9de86dee69e7b1d77574d4515314f8 Mon Sep 17 00:00:00 2001 From: Dmitriy Kogut <kogut.dmitriy@gmail.com> Date: Fri, 28 Sep 2018 14:53:58 +0300 Subject: [PATCH 0253/1415] MAGETWO-94892: Add Gift card to the cart from Requisition List --- .../Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml | 1 + .../Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml index 5aaa78822af08..fe9c14f886f7b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml @@ -15,5 +15,6 @@ <section name="StorefrontProductImageSection" /> <section name="StorefrontMessagesSection" /> <section name="StorefrontProductRelatedProductsSection"/> + <section name="StorefrontCreateRequisitionListSection"/> </page> </pages> diff --git a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml index bba73480d2db5..35ec242f05c52 100644 --- a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml +++ b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml @@ -11,6 +11,5 @@ <section name="ModalConfirmationSection"> <element name="CancelButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-dismiss')]"/> <element name="OkButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-accept')]"/> - <element name="saveButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action primary confirm')]" timeout="30"/> </section> </sections> From f3772212cdc4a7eb34ed7e85e274a0774b6c51de Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Fri, 28 Sep 2018 14:42:08 +0300 Subject: [PATCH 0254/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Update sorting logic - Add sorting widget --- .../Product/Form/Modifier/GroupedTest.php | 2 + .../Product/Form/Modifier/Grouped.php | 34 ++- .../adminhtml/web/css/grouped-product.css | 37 ++++ .../adminhtml/web/js/grouped-product-grid.js | 209 ++++++++++++++++++ .../web/template/components/position.html | 19 ++ 5 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js create mode 100644 app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php index 6ef87117deae2..327b47d4a75d8 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php @@ -34,6 +34,7 @@ class GroupedTest extends AbstractModifierTest const LINKED_PRODUCT_NAME = 'linked'; const LINKED_PRODUCT_QTY = '0'; const LINKED_PRODUCT_POSITION = 1; + const LINKED_PRODUCT_POSITION_CALCULATED = 1; const LINKED_PRODUCT_PRICE = '1'; /** @@ -212,6 +213,7 @@ public function testModifyData() 'price' => null, 'qty' => self::LINKED_PRODUCT_QTY, 'position' => self::LINKED_PRODUCT_POSITION, + 'positionCalculated' => self::LINKED_PRODUCT_POSITION_CALCULATED, 'thumbnail' => null, 'type_id' => null, 'status' => null, diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php index 2d1a1d19757e2..57d9bc78aaf28 100644 --- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php +++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php @@ -133,7 +133,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -143,12 +143,17 @@ public function modifyData(array $data) if ($modelId) { $storeId = $this->locator->getStore()->getId(); $data[$product->getId()]['links'][self::LINK_TYPE] = []; - foreach ($this->productLinkRepository->getList($product) as $linkItem) { + $linkedItems = $this->productLinkRepository->getList($product); + usort($linkedItems, function ($a, $b) { + return $a->getPosition() <=> $b->getPosition(); + }); + foreach ($linkedItems as $index => $linkItem) { if ($linkItem->getLinkType() !== self::LINK_TYPE) { continue; } /** @var \Magento\Catalog\Api\Data\ProductInterface $linkedProduct */ $linkedProduct = $this->productRepository->get($linkItem->getLinkedProductSku(), false, $storeId); + $linkItem->setPosition($index); $data[$modelId]['links'][self::LINK_TYPE][] = $this->fillData($linkedProduct, $linkItem); } $data[$modelId][self::DATA_SOURCE_DEFAULT]['current_store_id'] = $storeId; @@ -175,6 +180,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac 'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())), 'qty' => $linkItem->getExtensionAttributes()->getQty(), 'position' => $linkItem->getPosition(), + 'positionCalculated' => $linkItem->getPosition(), 'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(), 'type_id' => $linkedProduct->getTypeId(), 'status' => $this->status->getOptionText($linkedProduct->getStatus()), @@ -185,7 +191,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -454,7 +460,7 @@ protected function getGrid() 'label' => null, 'renderDefaultRecord' => false, 'template' => 'ui/dynamic-rows/templates/grid', - 'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid', + 'component' => 'Magento_GroupedProduct/js/grouped-product-grid', 'addButton' => false, 'itemTemplate' => 'record', 'dataScope' => 'data.links', @@ -555,6 +561,22 @@ protected function fillMeta() ], ], ], + 'positionCalculated' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'label' => __('Position'), + 'dataType' => Form\Element\DataType\Number::NAME, + 'formElement' => Form\Element\Input::NAME, + 'componentType' => Form\Field::NAME, + 'elementTmpl' => 'Magento_GroupedProduct/components/position', + 'sortOrder' => 90, + 'fit' => true, + 'dataScope' => 'positionCalculated' + ], + ], + ], + ], 'actionDelete' => [ 'arguments' => [ 'data' => [ @@ -563,7 +585,7 @@ protected function fillMeta() 'componentType' => 'actionDelete', 'dataType' => Form\Element\DataType\Text::NAME, 'label' => __('Actions'), - 'sortOrder' => 90, + 'sortOrder' => 100, 'fit' => true, ], ], @@ -577,7 +599,7 @@ protected function fillMeta() 'formElement' => Form\Element\Input::NAME, 'componentType' => Form\Field::NAME, 'dataScope' => 'position', - 'sortOrder' => 100, + 'sortOrder' => 110, 'visible' => false, ], ], diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index 3d723387d23b0..1916f222a499b 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -66,3 +66,40 @@ overflow: hidden; text-overflow: ellipsis; } + + +.position { + width:90px; +} + +.icon-rearrange-position > span { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.icon-forward, +.icon-backward { + -webkit-font-smoothing: antialiased; + font-family: 'Admin Icons'; + font-size: 17px; + speak: none; +} + +.position-widget-input { + text-align: center; + width: 40px; +} + +.icon-forward:before { + content: '\e618'; +} + +.icon-backward:before { + content: '\e619'; +} \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js new file mode 100644 index 0000000000000..0a585eb92958d --- /dev/null +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -0,0 +1,209 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'uiRegistry', + 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid' +], function (_, registry, dynamicRowsGrid) { + 'use strict'; + return dynamicRowsGrid.extend({ + + /** + * Set max element position + * + * @param {Number} position - element position + * @param {Object} elem - instance + */ + setMaxPosition: function (position, elem) { + + if (position || position === 0) { + this.checkMaxPosition(position); + this.sort(position, elem); + if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) { + this.shiftNextPagesPositions(position); + } + } else { + this.maxPosition += 1; + } + }, + + /** + * Shift positions for next page elements + * + * @param position + */ + shiftNextPagesPositions: function (position) { + console.log("todo: shifting positions to right on next pages related data"); + }, + + + /** + * Update position for element after position from another page is entered + * + * @param data + * @param event + */ + updateGridPosition: function (data, event) { + var inputValue = ~~event.target.value, + recordData = this.recordData(), + record, + updatedRecord; + + record = this.elems().find(function (obj) { + return obj.dataScope === data.parentScope + }).data(); + + if (inputValue === ~~record.positionCalculated) { + return false; + } + + this.elems([]); + + updatedRecord = this.getUpdatedRecordIndex(recordData, record.id); + + if (inputValue >= this.recordData().size() - 1) { + recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; + } else { + recordData[updatedRecord].position = inputValue; + recordData.forEach(function (value, index) { + if (~~value.id !== ~~record.id) { + recordData[index].position = (index !== inputValue) ? index : index + 1; + } + }); + } + + this.reloadGridData(recordData); + + }, + + /** + * Get updated record index + * + * @param recordData + * @param recordId + * @return {number} + */ + getUpdatedRecordIndex: function (recordData, recordId) { + return recordData.map(function (o) { + return ~~o.id + }).indexOf(~~recordId); + }, + + /** + * + * @param recordData to reprocess + */ + reloadGridData: function (recordData) { + this.recordData(recordData.sort(function (a, b) { + return ~~a.position - ~~b.position; + })); + this._updateCollection(); + this.reload(); + }, + + /** + * Event handler for "Send to bottom" button + * + * @param positionObj + * @return {boolean} + */ + sendToBottom: function (positionObj) { + + var objectToUpdate = this.getObjectToUpdate(positionObj), + recordData = this.recordData(), + updatedRecord; + + if (~~this.currentPage() === this.pages) { + objectToUpdate.position = this.maxPosition; + } else { + this.elems([]); + updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); + recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; + this.reloadGridData(recordData); + } + + return false; + }, + + /** + * Event handler for "Send to top" button + * + * @param positionObj + * @returns {boolean} + */ + sendToTop: function (positionObj) { + var objectToUpdate = this.getObjectToUpdate(positionObj), + recordData = this.recordData(), + updatedRecord; + + //isFirst + if (~~this.currentPage() === 1) { + objectToUpdate.position = 0; + } else { + this.elems([]); + updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); + recordData.forEach(function (value, index) { + recordData[index].position = (index === updatedRecord) ? 0 : value.position + 1; + }); + this.reloadGridData(recordData); + } + return false; + }, + + /** + * Get element from grid for update + * + * @param object + * @return {*} + */ + getObjectToUpdate: function (object) { + return this.elems().filter(function (item) { + return item.name === object.parentName; + })[0]; + }, + + /** + * Value function for position input + * + * @param data + * @return {number} + */ + getCalculatedPosition: function (data) { + return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); + }, + + /** + * Returns start index for current page + * + * @return {number} + */ + getStartIndex() { + return (~~this.currentPage() - 1) * this.pageSize; + }, + + /** + * Return Page Boundary + * + * @return {number} + */ + getDefaultPageBoundary: function () { + return (~~this.currentPage() * this.pageSize) - 1; + }, + + /** + * Returns position for last element to be moved after + * + * @return {number} + */ + getGlobalMaxPosition() { + return _.max(this.recordData().map(function (r) { + return ~~r.position + })); + } + + + }); +}); \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html new file mode 100644 index 0000000000000..dbfeff2e32c04 --- /dev/null +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html @@ -0,0 +1,19 @@ +<div class="position"> + <a href="#" class="move-top icon-backward icon-rearrange-position" + data-bind=" + click: $parent.sendToTop.bind($parent) + "> + <span>Top</span> + </a> + <input type="text" class="position-widget-input" + data-bind=" + value: $parent.getCalculatedPosition($record()), + event: {blur: $parent.updateGridPosition.bind($parent)} + "/> + <a href="#" class="move-bottom icon-forward icon-rearrange-position" + data-bind=" + click: $parent.sendToBottom.bind($parent) + "> + <span>Bottom</span> + </a> +</div> \ No newline at end of file From 76fd47b8653ff25ebc8f6eee82036364d3d56062 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 18 Sep 2018 08:51:47 -0500 Subject: [PATCH 0255/1415] MAGETWO-94438: AdminAddImageToWYSIWYGProductTest is unstable --- .../Catalog/Test/Mftf/Data/ProductData.xml | 1 + .../Mftf/Section/AdminProductFormSection.xml | 24 ++++---- .../AdminAddImageToWYSIWYGProductTest.xml | 61 ++++++++----------- 3 files changed, 38 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 9ae551b69d388..7c0cc03186c6e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -18,6 +18,7 @@ <data key="urlKey" unique="suffix">testurlkey</data> <data key="status">1</data> <data key="quantity">100</data> + <data key="weight">1</data> <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> </entity> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index a138c9bbac073..e6ed94e0223bd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -105,24 +105,24 @@ <element name="Numlist" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-bullist']" /> <element name="Bullet" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-numlist']" /> <element name="InsertLink" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-link']" /> - <element name="InsertImageIcon" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-image']" /> + <element name="InsertImageIcon" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-image']" timeout="30"/> <element name="InsertTable" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-table']" /> <element name="SpecialCharacter" type="button" selector="//div[@id='editorproduct_form_description']//i[@class='mce-ico mce-i-charmap']" /> - <element name="Browse" type="button" selector=".mce-i-browse"/> - <element name="BrowseUploadImage" type="file" selector=".fileupload" /> + <element name="Browse" type="button" selector=".mce-i-browse" timeout="30"/> + <element name="BrowseUploadImage" type="file" selector=".fileupload" timeout="30"/> <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> - <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> + <element name="OkBtn" type="button" selector="//button//span[text()='Ok']"/> <element name="InsertFile" type="text" selector="#insert_files" timeout="30"/> - <element name="CreateFolder" type="button" selector="#new_folder" /> - <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> - <element name="CancelBtn" type="button" selector="#cancel" /> + <element name="CreateFolder" type="button" selector="#new_folder" timeout="30"/> + <element name="DeleteSelectedBtn" type="text" selector="#delete_files" timeout="30"/> + <element name="CancelBtn" type="button" selector=".page-actions #cancel" /> <element name="FolderName" type="button" selector="input[data-role='promptField']" /> - <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" /> + <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" timeout="30"/> <element name="StorageRootArrow" type="button" selector="#root > .jstree-icon" /> <element name="checkIfArrowExpand" type="button" selector="//li[@id='root' and contains(@class,'jstree-closed')]" /> <element name="WysiwygArrow" type="button" selector="#d3lzaXd5Zw-- > .jstree-icon" /> @@ -143,21 +143,21 @@ <element name="Numlist" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-bullist']" /> <element name="Bullet" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-numlist']" /> <element name="InsertLink" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-link']" /> - <element name="InsertImageIcon" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-image']" /> + <element name="InsertImageIcon" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-image']" timeout="30"/> <element name="InsertTable" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-table']" /> <element name="SpecialCharacter" type="button" selector="//div[@id='editorproduct_form_short_description']//i[@class='mce-ico mce-i-charmap']"/> <element name="Browse" type="button" selector=".mce-i-browse"/> - <element name="BrowseUploadImage" type="file" selector=".fileupload" /> + <element name="BrowseUploadImage" type="file" selector=".fileupload" timeout="30" /> <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> - <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> + <element name="OkBtn" type="button" selector="//span[text()='Ok']" timeout="30"/> <element name="InsertFile" type="text" selector="#insert_files"/> <element name="CreateFolder" type="button" selector="#new_folder" /> - <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> + <element name="DeleteSelectedBtn" type="text" selector="#delete_files" timeout="30"/> <element name="CancelBtn" type="button" selector="#cancel" /> <element name="FolderName" type="button" selector="input[data-role='promptField']" /> <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" /> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml index bd1c057133d83..37c0eb6ea1253 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -16,82 +16,75 @@ <description value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84375"/> - <skip> - <issueId value="MAGETWO-94438"/> - </skip> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> </before> + <after> + <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage url="{{AdminProductCreatePage.url(AddToDefaultSet.attributeSetId, 'simple')}}" stepKey="navigateToNewProduct"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <fillField userInput="{{_defaultProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/> - <fillField userInput="{{_defaultProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> - <fillField userInput="{{_defaultProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> - <fillField userInput="{{_defaultProduct.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/> - <scrollTo selector="{{AdminProductFormSection.productQuantity}}" stepKey="scrollToQty" /> + <waitForPageLoad stepKey="waitForPageLoadProductCreatePage"/> + <actionGroup ref="fillMainProductForm" stepKey="fillBasicProductInfo" /> + <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="waitForDescription" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertImageIcon}}" stepKey="clickInsertImageIcon1" /> - <waitForPageLoad stepKey="waitForPageLoad1" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse1" /> - <waitForPageLoad stepKey="waitForPageLoad2" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading1" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading2" /> + <waitForLoadingMaskToDisappear stepKey="waitForBrowseModal" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn1" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn1" /> - <click selector="{{ProductDescriptionWYSIWYGToolbarSection.CreateFolder}}" stepKey="createFolder1"/> - <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.FolderName}}" stepKey="waitForPopUp1" /> + <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn1" /> + <click selector="{{ProductDescriptionWYSIWYGToolbarSection.CreateFolder}}" stepKey="createFolder1" /> + <waitForElement selector="{{ProductDescriptionWYSIWYGToolbarSection.FolderName}}" stepKey="waitForPopUp1" /> <fillField selector="{{ProductDescriptionWYSIWYGToolbarSection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName1" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.AcceptFolderName}}" stepKey="acceptFolderName11" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> <conditionalClick selector="{{ProductDescriptionWYSIWYGToolbarSection.StorageRootArrow}}" dependentSelector="{{ProductDescriptionWYSIWYGToolbarSection.checkIfArrowExpand}}" stepKey="clickStorageRootArrowIfClosed" visible="true"/> <conditionalClick selector="{{ProductDescriptionWYSIWYGToolbarSection.WysiwygArrow}}" dependentSelector="{{ProductDescriptionWYSIWYGToolbarSection.checkIfWysiwygArrowExpand}}" stepKey="clickWysiwygArrowIfClosed" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder1" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder1" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading4" /> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage1"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading5" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage1" /> <seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.imageSelected(ImageUpload1.value)}}" stepKey="seeImageSelected1" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn1"/> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected1" /> - <waitForText userInput="OK" stepKey="waitForConfirm1" /> - <click selector="{{ProductDescriptionWYSIWYGToolbarSection.confirmDelete}}" stepKey="confirmDelete1" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForConfirmDelete1"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete1" /> <waitForElementNotVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForImageDeleted1" /> <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="dontSeeImage1" /> + <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn2" /> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage2"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading6" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage2" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn1" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading7" /> - <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.OkBtn}}" stepKey="waitForOkBtn1" /> + <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.ImageDescription}}" stepKey="waitForImageDescriptionButton1" /> <fillField selector="{{ProductDescriptionWYSIWYGToolbarSection.ImageDescription}}" userInput="{{ImageUpload1.content}}" stepKey="fillImageDescription1" /> <fillField selector="{{ProductDescriptionWYSIWYGToolbarSection.Height}}" userInput="{{ImageUpload1.height}}" stepKey="fillImageHeight1" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.OkBtn}}" stepKey="clickOkBtn1" /> - <waitForPageLoad stepKey="waitForPageLoad3"/> <scrollTo selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="scrollToTinyMCE4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertImageIcon}}" stepKey="clickInsertImageIcon2" /> - <waitForPageLoad stepKey="waitForPageLoad4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse2" /> - <waitForPageLoad stepKey="waitForPageLoad5" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading8" /> + <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.CancelBtn}}" stepKey="waitForCancelButton2"/> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn2" /> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn2" /> - <dontSeeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn2" /> + <dontSeeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn3" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage3"/> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" /> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage3" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading9" /> - <wait time="3" stepKey="waitMore" /> <waitForElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="waitForDeletebtn" /> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn2"/> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected2" /> - <waitForText userInput="OK" stepKey="waitForConfirm3" /> - <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.confirmDelete}}" stepKey="confirmDelete2" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForConfirm3"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete2" /> + <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn4" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage4"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading10" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" /> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading11" /> @@ -107,9 +100,5 @@ <seeElement selector="{{StorefrontProductInfoMainSection.mediaDescription}}" stepKey="assertMediaDescription"/> <seeElementInDOM selector="{{StorefrontCategoryMainSection.imageSource(ImageUpload3.fileName)}}" stepKey="assertMediaSource3"/> <seeElementInDOM selector="{{StorefrontCategoryMainSection.imageSource(ImageUpload1.fileName)}}" stepKey="assertMediaSource1"/> - <after> - <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> - <actionGroup ref="logout" stepKey="logout"/> - </after> </test> </tests> From c5bf8738d26a07a19a477e14aaf79708ba8052fd Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Fri, 28 Sep 2018 16:59:42 +0400 Subject: [PATCH 0256/1415] MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11 - Add automated test --- .../StorefrontProductInfoMainSection.xml | 4 + .../YoutubeVideoWindowOnProductPageTest.xml | 92 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml diff --git a/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index 564122f71b9f4..c8e1ebcf12d94 100644 --- a/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -10,5 +10,9 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontProductInfoMainSection"> <element name="productVideo" type="text" selector="//*[@class='product-video' and @data-type='{{videoType}}']" parameterized="true"/> + <element name="clickInVideo" type="video" selector="//*[@class='fotorama__stage__shaft']"/> + <element name="videoPausedMode" type="video" selector="//*[contains(@class, 'paused-mode')]"/> + <element name="videoPlayedMode" type="video" selector="//*[contains(@class,'playing-mode')]"/> + <element name="frameVideo" type="video" selector="widget2"/> </section> </sections> diff --git a/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml b/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml new file mode 100644 index 0000000000000..7249a4223503e --- /dev/null +++ b/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="YoutubeVideoWindowOnProductPageTest"> + <annotations> + <features value="ProductVideo"/> + <stories value="MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11"/> + <testCaseId value="MAGETWO-95254"/> + <title value="Youtube video window on the product page"/> + <description value="Check Youtube video window on the product page"/> + <severity value="MAJOR"/> + <group value="ProductVideo"/> + </annotations> + + <before> + <!--Log In--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create category--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <!--Create product--> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Set product video Youtube api key configuration --> + <createData entity="ProductVideoYoutubeApiKeyConfig" stepKey="setStoreConfig" after="loginAsAdmin"/> + </before> + + <!--Open simple product--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openFirstProductForEdit"/> + + <!-- Add product video --> + <actionGroup ref="addProductVideo" stepKey="addProductVideo" after="openFirstProductForEdit"/> + <!-- Assert product video in admin product form --> + <actionGroup ref="assertProductVideoAdminProductPage" stepKey="assertProductVideoAdminProductPage" after="addProductVideo"/> + + <!-- Save the product --> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveFirstProduct"/> + <waitForPageLoad stepKey="waitForFirstProductSaved"/> + + <!-- Assert product video in storefront product page --> + <amOnPage url="$$createProduct.name$$.html" stepKey="goToStorefrontCategoryPage"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded"/> + <actionGroup ref="assertProductVideoStorefrontProductPage" stepKey="assertProductVideoStorefrontProductPage" after="waitForStorefrontPageLoaded"/> + + <!--Click Play video button--> + <click stepKey="clickToPlayVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitFiveSecondToPlayVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="waitForVideoPlayed"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="AssertVideoIsPlayed"/> + <switchToIFrame stepKey="switchBack1"/> + + <!--Click Pause button--> + <click stepKey="clickToStopVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitFiveSecondToStopVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame2"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPausedMode}}" stepKey="waitForVideoPaused"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPausedMode}}" stepKey="AssertVideoIsPaused"/> + <switchToIFrame stepKey="switchBack2"/> + + <!--Click Play video button again. Make sure that Video continued playing--> + <click stepKey="clickAgainToPlayVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitAgainFiveSecondToPlayVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame3"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="waitForVideoPlayedAgain"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="AssertVideoIsPlayedAgain"/> + <switchToIFrame stepKey="switchBack3"/> + + <after> + <deleteData createDataKey="createProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategoryFirst"/> + <!-- Set product video configuration to default --> + <createData entity="DefaultProductVideoConfig" stepKey="setStoreDefaultConfig" before="logout"/> + <!--Log Out--> + <actionGroup ref="logout" stepKey="logout"/> + </after> + </test> +</tests> + From 927fd20c059b626bfd989def516602fc2d6abd56 Mon Sep 17 00:00:00 2001 From: Dmitriy Kogut <kogut.dmitriy@gmail.com> Date: Fri, 28 Sep 2018 16:17:33 +0300 Subject: [PATCH 0257/1415] MAGETWO-94892: Add Gift card to the cart from Requisition List --- .../Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml index fe9c14f886f7b..75e3210cad7d4 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml @@ -8,13 +8,12 @@ <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="StorefrontProductPage" url="/{{var1}}.html" area="storefront" module="Catalog" parameterized="true"> + <page name="StorefrontProductPage" url="/{{var1}}.html" area="storefront" module="Magento_Catalog" parameterized="true"> <section name="StorefrontProductInfoMainSection" /> <section name="StorefrontProductInfoDetailsSection" /> <section name="WYSIWYGToolbarSection"/> <section name="StorefrontProductImageSection" /> <section name="StorefrontMessagesSection" /> <section name="StorefrontProductRelatedProductsSection"/> - <section name="StorefrontCreateRequisitionListSection"/> </page> </pages> From 4ddd759ec29704cfe258006977f20615a0dd9393 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Fri, 28 Sep 2018 16:59:04 +0300 Subject: [PATCH 0258/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Fix integration tests --- .../testsuite/Magento/Authorizenet/Model/DirectpostTest.php | 2 +- .../Controller/Adminhtml/Order/PaymentReviewTest.php | 4 ++-- .../Magento/Paypal/Controller/Payflow/SilentPostTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php index 71105cd844c29..3681dfe8e5bd2 100644 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php +++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php @@ -141,7 +141,7 @@ public function fdsFilterActionDataProvider() [ 'filter_action' => 'report', 'order_id' => '100000004', - 'expected_order_state' => Order::STATE_PROCESSING + 'expected_order_state' => Order::STATE_COMPLETE ], ]; } diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Order/PaymentReviewTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Order/PaymentReviewTest.php index 04bac807637db..bb7b04f53dd6d 100644 --- a/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Order/PaymentReviewTest.php +++ b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Order/PaymentReviewTest.php @@ -70,8 +70,8 @@ public function testExecuteAccept() ); $order = $this->orderRepository->get($orderId); - static::assertEquals(Order::STATE_PROCESSING, $order->getState()); - static::assertEquals(Order::STATE_PROCESSING, $order->getStatus()); + static::assertEquals(Order::STATE_COMPLETE, $order->getState()); + static::assertEquals(Order::STATE_COMPLETE, $order->getStatus()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Payflow/SilentPostTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Payflow/SilentPostTest.php index 2bebb5bd95bb2..81a9587d36f4a 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Payflow/SilentPostTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Payflow/SilentPostTest.php @@ -93,7 +93,7 @@ public function testSuccessfulNotification($resultCode, $orderState, $orderStatu public function responseCodeDataProvider() { return [ - [Payflowlink::RESPONSE_CODE_APPROVED, Order::STATE_PROCESSING, Order::STATE_PROCESSING], + [Payflowlink::RESPONSE_CODE_APPROVED, Order::STATE_COMPLETE, Order::STATE_COMPLETE], [Payflowlink::RESPONSE_CODE_FRAUDSERVICE_FILTER, Order::STATE_PAYMENT_REVIEW, Order::STATUS_FRAUD], ]; } From 8f8fc8d9b868e3e73e2267ccca910efa5fa57378 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Fri, 28 Sep 2018 17:24:18 +0300 Subject: [PATCH 0259/1415] MAGETWO-91751: Apostrophe displays as code in the text field box - Skipping to escape single quote --- app/code/Magento/Widget/Model/Widget.php | 6 +++- .../Widget/Test/Unit/Model/WidgetTest.php | 29 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php index 085e6ec3b2d77..5ba03d008ded0 100644 --- a/app/code/Magento/Widget/Model/Widget.php +++ b/app/code/Magento/Widget/Model/Widget.php @@ -84,6 +84,8 @@ public function __construct( } /** + * Get math random + * * @return \Magento\Framework\Math\Random * * @deprecated 100.1.0 @@ -315,7 +317,7 @@ public function getWidgetDeclaration($type, $params = [], $asIs = true) } } if (isset($value)) { - $directive .= sprintf(' %s="%s"', $name, $this->escaper->escapeQuote($value)); + $directive .= sprintf(' %s="%s"', $name, $this->escaper->escapeHtmlAttr($value, false)); } } @@ -339,6 +341,8 @@ public function getWidgetDeclaration($type, $params = [], $asIs = true) } /** + * Get widget page varname + * * @param array $params * @return string * @throws \Magento\Framework\Exception\LocalizedException diff --git a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php index b85a458ed4121..5c546d7e2435c 100644 --- a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php +++ b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php @@ -32,6 +32,9 @@ class WidgetTest extends \PHPUnit\Framework\TestCase */ private $conditionsHelper; + /** + * @inheritdoc + */ protected function setUp() { $this->dataStorageMock = $this->getMockBuilder(\Magento\Widget\Model\Config\Data::class) @@ -55,6 +58,9 @@ protected function setUp() ); } + /** + * Unit test for getWidget + */ public function testGetWidgets() { $expected = ['val1', 'val2']; @@ -65,6 +71,9 @@ public function testGetWidgets() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetsWithFilter + */ public function testGetWidgetsWithFilter() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -78,6 +87,9 @@ public function testGetWidgetsWithFilter() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetsWithUnknownFilter + */ public function testGetWidgetsWithUnknownFilter() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -90,6 +102,9 @@ public function testGetWidgetsWithUnknownFilter() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetByClassType + */ public function testGetWidgetByClassType() { $widgetOne = ['@' => ['type' => 'type1']]; @@ -101,6 +116,9 @@ public function testGetWidgetByClassType() $this->assertNull($this->widget->getWidgetByClassType('type2')); } + /** + * Unit test for getConfigAsObject + */ public function testGetConfigAsObject() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -135,6 +153,9 @@ public function testGetConfigAsObject() $this->assertSame($supportedContainersExpected, $resultObject->getSupportedContainers()); } + /** + * Unit test for getConfigAsObjectWidgetNoFound + */ public function testGetConfigAsObjectWidgetNoFound() { $this->dataStorageMock->expects($this->once()) @@ -146,6 +167,9 @@ public function testGetConfigAsObjectWidgetNoFound() $this->assertSame([], $resultObject->getData()); } + /** + * Unit test for getWidgetDeclaration + */ public function testGetWidgetDeclaration() { $mathRandomMock = $this->createPartialMock(\Magento\Framework\Math\Random::class, ['getRandomString']); @@ -175,7 +199,7 @@ public function testGetWidgetDeclaration() $this->conditionsHelper->expects($this->once())->method('encode')->with($conditions) ->willReturn('encoded-conditions-string'); $this->escaperMock->expects($this->atLeastOnce()) - ->method('escapeQuote') + ->method('escapeHtmlAttr') ->willReturnMap([ ['my "widget"', false, 'my "widget"'], ['1', false, '1'], @@ -203,6 +227,9 @@ public function testGetWidgetDeclaration() $this->assertContains('type_name=""}}', $result); } + /** + * Unit test for getWidgetDeclarationWithZeroValueParam + */ public function testGetWidgetDeclarationWithZeroValueParam() { $mathRandomMock = $this->createPartialMock(\Magento\Framework\Math\Random::class, ['getRandomString']); From c4c8af6b221a84e5f389a95a29bc60af4fc3ae44 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 28 Sep 2018 18:27:01 +0300 Subject: [PATCH 0260/1415] MAGETWO-70943: Incorrect reset password flow --- app/code/Magento/Customer/Model/AccountManagement.php | 4 ++-- .../view/frontend/email/password_reset_confirmation.html | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 6aee2894f4907..06c1f41c3888c 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -661,7 +661,7 @@ private function handleUnknownTemplate($template) /** * @inheritdoc */ - public function resetPassword($email, $resetToken, $newPassword): bool + public function resetPassword($email, $resetToken, $newPassword) { if (!$email) { $customer = $this->matchCustomerByRpToken($resetToken); @@ -1093,7 +1093,7 @@ public function isCustomerInStore($customerWebsiteId, $storeId) * @throws \Magento\Framework\Exception\NoSuchEntityException If customer doesn't exist * @throws LocalizedException */ - private function validateResetPasswordToken(?int $customerId, ?string $resetPasswordLinkToken) : bool + private function validateResetPasswordToken($customerId, $resetPasswordLinkToken) { if ($customerId !== null && $customerId <= 0) { throw new InputException( diff --git a/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html b/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html index f33350ea48241..59e7f16adfd51 100644 --- a/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html +++ b/app/code/Magento/Customer/view/frontend/email/password_reset_confirmation.html @@ -22,7 +22,6 @@ <tr> <td align="center"> <a href="{{var this.getUrl($store,'customer/account/createPassword/',[_query:[token:$customer.rp_token],_nosid:1])}}" target="_blank">{{trans "Set a New Password"}}</a> - </td> </tr> </table> From 956f36132e3438acfea61a3e4cd41b43e1bd1fc0 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Fri, 28 Sep 2018 12:01:29 -0500 Subject: [PATCH 0261/1415] MAGETWO-95048: Sidebar navigation is broken for Stores > Configuration, All Stores. - Pass frontname to getSecretKey if route not found - Add MFTF test to cover this fix --- app/code/Magento/Backend/Block/Menu.php | 4 +- .../Test/Mftf/Section/AdminMenuSection.xml | 3 +- .../AdminMenuNavigationWithSecretKeysTest.xml | 50 +++++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Backend/Test/Mftf/Test/AdminMenuNavigationWithSecretKeysTest.xml diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index 744c4d06a0d17..3ef4168238b48 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -75,7 +75,7 @@ class Menu extends \Magento\Backend\Block\Template private $anchorRenderer; /** - * @var ConfigInterface + * @var \Magento\Framework\App\Route\ConfigInterface */ private $routeConfig; @@ -216,7 +216,7 @@ protected function _callbackSecretKey($match) { $routeId = $this->routeConfig->getRouteByFrontName($match[1]); return \Magento\Backend\Model\UrlInterface::SECRET_KEY_PARAM_NAME . '/' . $this->_url->getSecretKey( - $routeId, + $routeId ?: $match[1], $match[2], $match[3] ); diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminMenuSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminMenuSection.xml index 9d3182b6236a4..9e4a6d9219526 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminMenuSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminMenuSection.xml @@ -7,9 +7,10 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminMenuSection"> <element name="catalog" type="button" selector="#menu-magento-catalog-catalog"/> + <element name="catalogProducts" type="button" selector="#nav li[data-ui-id='menu-magento-catalog-catalog-products']"/> <element name="customers" type="button" selector="#menu-magento-customer-customer"/> <element name="content" type="button" selector="#menu-magento-backend-content"/> <element name="widgets" type="button" selector="#nav li[data-ui-id='menu-magento-widget-cms-widget-instance']"/> diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminMenuNavigationWithSecretKeysTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminMenuNavigationWithSecretKeysTest.xml new file mode 100644 index 0000000000000..c9a3b8089cc1d --- /dev/null +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminMenuNavigationWithSecretKeysTest.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMenuNavigationWithSecretKeysTest"> + <annotations> + <features value="Backend"/> + <stories value="Menu Navigation"/> + <title value="Admin should be able to navigate between menu options with secret url keys enabled"/> + <description value="Admin should be able to navigate between menu options with secret url keys enabled"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-95349"/> + <group value="menu"/> + </annotations> + <before> + <magentoCLI command="config:set admin/security/use_form_key 1" stepKey="enableUrlSecretKeys"/> + <magentoCLI command="cache:clean config full_page" stepKey="cleanInvalidatedCaches1"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <magentoCLI command="config:set admin/security/use_form_key 0" stepKey="disableUrlSecretKeys"/> + <magentoCLI command="cache:clean config full_page" stepKey="cleanInvalidatedCaches2"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <click selector="{{AdminMenuSection.stores}}" stepKey="clickStoresMenuOption1"/> + <waitForLoadingMaskToDisappear stepKey="waitForStoresMenu1" /> + <click selector="{{AdminMenuSection.configuration}}" stepKey="clickStoresConfigurationMenuOption1"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoad1"/> + <seeCurrentUrlMatches regex="~\/admin\/system_config\/~" stepKey="seeCurrentUrlMatchesConfigPath1"/> + + <click selector="{{AdminMenuSection.catalog}}" stepKey="clickCatalogMenuOption"/> + <waitForLoadingMaskToDisappear stepKey="waitForCatalogMenu1" /> + <click selector="{{AdminMenuSection.catalogProducts}}" stepKey="clickCatalogProductsMenuOption"/> + <waitForPageLoad stepKey="waitForProductsPageLoad"/> + <seeCurrentUrlMatches regex="~\/catalog\/product\/~" stepKey="seeCurrentUrlMatchesProductsPath"/> + + <click selector="{{AdminMenuSection.stores}}" stepKey="clickStoresMenuOption2"/> + <waitForLoadingMaskToDisappear stepKey="waitForStoresMenu2" /> + <click selector="{{AdminMenuSection.configuration}}" stepKey="clickStoresConfigurationMenuOption2"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoad2"/> + <seeCurrentUrlMatches regex="~\/admin\/system_config\/~" stepKey="seeCurrentUrlMatchesConfigPath2"/> + </test> +</tests> From b82bec83167297f80529b9af0e2045fc55ec6b74 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <kopylova@adobe.com> Date: Fri, 28 Sep 2018 13:51:17 -0500 Subject: [PATCH 0262/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted - removed deprecation from generic catalog search classes --- app/code/Magento/CatalogSearch/Block/Advanced/Form.php | 2 -- .../CatalogSearch/Block/Plugin/FrontTabPlugin.php | 4 +--- app/code/Magento/CatalogSearch/Block/Result.php | 2 -- app/code/Magento/CatalogSearch/Block/SearchTermsLog.php | 4 +--- .../Magento/CatalogSearch/Controller/Advanced/Index.php | 4 ---- .../Magento/CatalogSearch/Controller/Advanced/Result.php | 4 ---- .../Magento/CatalogSearch/Controller/Result/Index.php | 4 ---- .../CatalogSearch/Controller/SearchTermsLog/Save.php | 2 -- app/code/Magento/CatalogSearch/Helper/Data.php | 2 -- .../Adapter/Aggregation/Checker/Query/AdvancedSearch.php | 2 -- app/code/Magento/CatalogSearch/Model/Adapter/Options.php | 2 -- .../Model/Adminhtml/System/Config/Backend/Engine.php | 2 -- .../CatalogSearch/Model/Attribute/SearchWeight.php | 3 --- .../CatalogSearch/Model/Autocomplete/DataProvider.php | 4 ---- .../Magento/CatalogSearch/Model/Indexer/Fulltext.php | 2 -- .../Model/Indexer/Fulltext/Action/DataProvider.php | 2 -- .../Model/Indexer/Fulltext/Model/Plugin/Category.php | 3 --- .../Model/Indexer/Fulltext/Plugin/AbstractPlugin.php | 3 --- .../Model/Indexer/Fulltext/Plugin/Attribute.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Category.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Product.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Store/Group.php | 3 --- .../Model/Indexer/Fulltext/Plugin/Store/View.php | 3 --- .../CatalogSearch/Model/Indexer/Fulltext/Processor.php | 2 -- .../CatalogSearch/Model/Indexer/Fulltext/Store.php | 4 ---- .../Model/Indexer/IndexStructureFactory.php | 2 -- .../Model/Indexer/IndexerHandlerFactory.php | 2 -- .../Magento/CatalogSearch/Model/Indexer/Mview/Action.php | 4 ---- .../Model/Layer/Category/ItemCollectionProvider.php | 4 ---- .../CatalogSearch/Model/Layer/Filter/Attribute.php | 2 -- .../CatalogSearch/Model/Layer/Filter/Category.php | 3 --- .../Magento/CatalogSearch/Model/Layer/Filter/Decimal.php | 3 --- .../Magento/CatalogSearch/Model/Layer/Filter/Price.php | 2 -- .../Model/Layer/Search/Plugin/CollectionFilter.php | 4 ---- .../CatalogSearch/Model/Layer/Search/StateKey.php | 4 ---- app/code/Magento/CatalogSearch/Model/Price/Interval.php | 4 ---- .../Model/ResourceModel/EngineInterface.php | 7 +------ .../CatalogSearch/Model/ResourceModel/EngineProvider.php | 9 ++------- .../BaseSelectStrategy/BaseSelectStrategyInterface.php | 1 - .../Model/Search/BaseSelectStrategy/StrategyMapper.php | 1 - app/code/Magento/CatalogSearch/Model/Search/Catalog.php | 3 --- .../Model/Search/CustomAttributeFilterCheck.php | 1 - .../Model/Search/SelectContainer/SelectContainer.php | 1 - app/code/Magento/CatalogSearch/Model/Source/Weight.php | 2 -- .../Magento/CatalogSearch/Plugin/EnableEavIndexer.php | 3 +++ app/code/Magento/Search/Model/Query.php | 1 - 46 files changed, 8 insertions(+), 130 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php index 863165ecf720d..4d1957991d1bf 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php @@ -23,8 +23,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Form extends Template { diff --git a/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php b/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php index be65372725ceb..85ad66013cf32 100644 --- a/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php +++ b/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php @@ -11,9 +11,7 @@ use Magento\Framework\Data\Form\Element\Fieldset; /** - * Plugin for Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Front - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * Add Search Weight field to the product attribute add/edit tab */ class FrontTabPlugin { diff --git a/app/code/Magento/CatalogSearch/Block/Result.php b/app/code/Magento/CatalogSearch/Block/Result.php index ccc8950450dad..f0d899b678c78 100644 --- a/app/code/Magento/CatalogSearch/Block/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Result.php @@ -18,8 +18,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php b/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php index 3679803c04d02..005c7860cfe5f 100644 --- a/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php +++ b/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php @@ -9,9 +9,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; /** - * Class for logging search terms on cached pages - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * Provider of the information on whether the page is cacheable, so that AJAX-based logging of terms can be triggered */ class SearchTermsLog implements ArgumentInterface { diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php index a669016eb6b1b..bc60a5c9b106c 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php @@ -10,10 +10,6 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php index 937175511b1fb..145db146347bc 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php @@ -12,10 +12,6 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\UrlFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Result extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/Result/Index.php b/app/code/Magento/CatalogSearch/Controller/Result/Index.php index 7c3577df452e4..df00e4c7106ba 100644 --- a/app/code/Magento/CatalogSearch/Controller/Result/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Result/Index.php @@ -15,10 +15,6 @@ use Magento\Search\Model\QueryFactory; use Magento\Search\Model\PopularSearchTerms; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php b/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php index f4018ed5b5d0d..a4a843c636cd0 100644 --- a/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php +++ b/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php @@ -15,8 +15,6 @@ /** * Controller for save search terms - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Save extends \Magento\Framework\App\Action\Action { diff --git a/app/code/Magento/CatalogSearch/Helper/Data.php b/app/code/Magento/CatalogSearch/Helper/Data.php index 7ba438ff36a58..6898e33d49f1d 100644 --- a/app/code/Magento/CatalogSearch/Helper/Data.php +++ b/app/code/Magento/CatalogSearch/Helper/Data.php @@ -10,8 +10,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Data extends \Magento\Search\Helper\Data { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php index bb0de00816337..8f1f3fde14240 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php @@ -12,8 +12,6 @@ * Request checker for advanced search. * * Checks advanced search query whether required to collect all attributes for entity. - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class AdvancedSearch implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php index efc955486708c..425e6c0041616 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php @@ -12,8 +12,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Options implements OptionsInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php index 5262316e2ca38..5447ff635f992 100644 --- a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php @@ -8,8 +8,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Engine extends \Magento\Framework\App\Config\Value { diff --git a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php index 139154be9df3a..d6110f4b3b2c9 100644 --- a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php +++ b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php @@ -11,9 +11,6 @@ * which is used to boost matches by specific attributes. * * This is part of search accuracy customization functionality. - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class SearchWeight { diff --git a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php index 82a64923ef702..c1c9997bc83ea 100644 --- a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php @@ -13,10 +13,6 @@ use Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; use Magento\Store\Model\ScopeInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class DataProvider implements DataProviderInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php index ee66a91f395b9..21d8b7297da7d 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php @@ -19,8 +19,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 83058b6f0ad55..a8d46911193a8 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -16,8 +16,6 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @api * @since 100.0.3 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class DataProvider { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php index eee6ac37767ee..ed841996ea07b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php @@ -12,9 +12,6 @@ /** * Perform indexer invalidation after a category delete. - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Category { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php index 61b7075043d29..5d4096a3afab0 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php @@ -10,9 +10,6 @@ /** * Abstract plugin for indexers - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ abstract class AbstractPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php index ae218f65087d4..83ad7acca84dc 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php @@ -7,10 +7,6 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Attribute extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php index 0cf9f04f97613..ca701db7d2a93 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; use Magento\Framework\Model\AbstractModel; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Category extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php index 120a22f60d048..c8dbd89017b7c 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct; use Magento\Framework\Model\AbstractModel; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Product extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php index 27a2bd82a5d7e..73a79f7c87239 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php @@ -12,9 +12,6 @@ /** * Plugin for Magento\Store\Model\ResourceModel\Group - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Group extends AbstractIndexerPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php index 51695fd261d7b..7f0c5fdae6d42 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php @@ -12,9 +12,6 @@ /** * Plugin for Magento\Store\Model\ResourceModel\Store - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class View extends AbstractIndexerPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php index 33881061eb88d..cd3ff62d53682 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php @@ -12,8 +12,6 @@ * Class Processor * @api * @since 100.1.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Processor extends AbstractProcessor { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php index 8b0a18105ec84..e971f59cf10f2 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php @@ -11,10 +11,6 @@ use Magento\Framework\Indexer\ConfigInterface; use Magento\Framework\Event\ObserverInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Store implements ObserverInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php index 4bdd4336c5257..d8b3c19ddb918 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php @@ -12,8 +12,6 @@ /** * @api * @since 100.1.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class IndexStructureFactory { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php index af1839f04ab38..b9b44df6f404f 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php @@ -12,8 +12,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class IndexerHandlerFactory { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php index ba5a16978c59b..47a8681a73c60 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php @@ -9,10 +9,6 @@ use Magento\Framework\Mview\ActionInterface; use Magento\Framework\Indexer\IndexerInterfaceFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Action implements ActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php index 02beeae0f1579..4ce286bf15922 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Layer\ItemCollectionProviderInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class ItemCollectionProvider implements ItemCollectionProviderInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php index 8119d7c5869c5..7aac6e98fc044 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php @@ -9,8 +9,6 @@ /** * Layer attribute filter - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Attribute extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php index 63d9656fea25a..7c15514f211d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php @@ -10,9 +10,6 @@ /** * Layer category filter - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Category extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php index a3b1d76fef151..e61a886a41d6f 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php @@ -9,9 +9,6 @@ /** * Layer decimal filter - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Decimal extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 126a0a7ea3212..108f1b9f4fd8d 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -10,8 +10,6 @@ /** * Layer price filter based on Search API * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Price extends AbstractFilter diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php index 5fbd08c134334..4ffd8ff4ba5ea 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Category; use Magento\Search\Model\QueryFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class CollectionFilter { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php index 16a22aba8db35..4f14b7daba1d5 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Layer\StateKeyInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class StateKey extends \Magento\Catalog\Model\Layer\Category\StateKey implements StateKeyInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Price/Interval.php b/app/code/Magento/CatalogSearch/Model/Price/Interval.php index 69e4b90baf04d..db1d550c3724b 100644 --- a/app/code/Magento/CatalogSearch/Model/Price/Interval.php +++ b/app/code/Magento/CatalogSearch/Model/Price/Interval.php @@ -7,10 +7,6 @@ use Magento\Framework\Search\Dynamic\IntervalInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Interval implements IntervalInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php index 99d34de1830b7..4b9db55105ea9 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php @@ -3,16 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +namespace Magento\CatalogSearch\Model\ResourceModel; /** * CatalogSearch Index Engine Interface * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ -namespace Magento\CatalogSearch\Model\ResourceModel; - -/** * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php index 6faffefde6095..d1259159606d3 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php @@ -4,18 +4,13 @@ * See COPYING.txt for license details. */ -/** - * Catalog Search engine provider - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ namespace Magento\CatalogSearch\Model\ResourceModel; -use Magento\CatalogSearch\Model\ResourceModel\EngineInterface; use Magento\Framework\Search\EngineResolverInterface; /** + * Catalog Search engine provider + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php index 32ecb49714246..1904df9ccd53b 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php @@ -8,7 +8,6 @@ use Magento\CatalogSearch\Model\Search\SelectContainer\SelectContainer; /** - * Interface BaseSelectStrategyInterface * This interface represents strategy that will be used to create base select for search request * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php index 9e954b57f649f..963dd53295430 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php @@ -10,7 +10,6 @@ use Magento\CatalogSearch\Model\Adapter\Mysql\BaseSelectStrategy\BaseSelectAttributesSearchStrategy; /** - * Class StrategyMapper * This class is responsible for deciding which BaseSelectStrategyInterface should be used for passed SelectContainer * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/Catalog.php b/app/code/Magento/CatalogSearch/Model/Search/Catalog.php index 7a39a7bf47824..31ac889b19e69 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/Catalog.php +++ b/app/code/Magento/CatalogSearch/Model/Search/Catalog.php @@ -9,9 +9,6 @@ /** * Search model for backend search - * - * @deprecated 100.2.0 - * @see ElasticSearch module is default search engine starting from 2.3. CatalogSearch would be removed in 2.4 */ class Catalog extends \Magento\Framework\DataObject { diff --git a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php index ce8ce6829a008..bac8c1bb57c11 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php @@ -10,7 +10,6 @@ use Magento\Catalog\Model\Product; /** - * Class CustomAttributeFilterSelector * Checks if FilterInterface is by custom attribute * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php index ffd434251f9f5..e32785a6a17af 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php @@ -10,7 +10,6 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * Class SelectContainer * This class is a container for all data that is required for creating select query by search request * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Source/Weight.php b/app/code/Magento/CatalogSearch/Model/Source/Weight.php index c02d861fda8dd..495e1a4567d63 100644 --- a/app/code/Magento/CatalogSearch/Model/Source/Weight.php +++ b/app/code/Magento/CatalogSearch/Model/Source/Weight.php @@ -9,8 +9,6 @@ * Attribute weight options * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Weight implements \Magento\Framework\Data\OptionSourceInterface { diff --git a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php index c624f9d1c2e52..cb7210813b056 100644 --- a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php +++ b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php @@ -9,6 +9,9 @@ /** * Enable Product EAV indexer in configuration for MySQL search engine + * + * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} + * will replace it as the default search engine. */ class EnableEavIndexer { diff --git a/app/code/Magento/Search/Model/Query.php b/app/code/Magento/Search/Model/Query.php index 365e03b3648a7..b104fd0329795 100644 --- a/app/code/Magento/Search/Model/Query.php +++ b/app/code/Magento/Search/Model/Query.php @@ -5,7 +5,6 @@ */ namespace Magento\Search\Model; -use Magento\Framework\App\ResourceConnection; use Magento\Search\Model\ResourceModel\Query\Collection as QueryCollection; use Magento\Search\Model\ResourceModel\Query\CollectionFactory as QueryCollectionFactory; use Magento\Search\Model\SearchCollectionInterface as Collection; From 19679902520463442d54d8c03a984ae7718c04d3 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <kopylova@adobe.com> Date: Fri, 28 Sep 2018 14:05:20 -0500 Subject: [PATCH 0263/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted - updated message --- app/code/Magento/CatalogSearch/Block/Advanced/Result.php | 4 ++-- .../Model/Adapter/Aggregation/AggregationResolver.php | 4 ++-- .../Model/Adapter/Aggregation/Checker/Query/CatalogView.php | 4 ++-- .../Model/Adapter/Aggregation/RequestCheckerComposite.php | 4 ++-- .../Model/Adapter/Aggregation/RequestCheckerInterface.php | 4 ++-- .../Model/Adapter/Mysql/Aggregation/DataProvider.php | 4 ++-- .../Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php | 4 ++-- .../Aggregation/DataProvider/SelectBuilderForAttribute.php | 4 ++-- .../SelectBuilderForAttribute/ApplyStockConditionToSelect.php | 4 ++-- .../BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php | 4 ++-- .../BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php | 4 ++-- .../Model/Adapter/Mysql/Dynamic/DataProvider.php | 4 ++-- .../CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php | 4 ++-- .../Model/Adapter/Mysql/Filter/AliasResolver.php | 4 ++-- .../CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php | 4 ++-- .../Mysql/Plugin/Aggregation/Category/DataProvider.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Advanced.php | 4 ++-- .../Magento/CatalogSearch/Model/Advanced/Request/Builder.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Fulltext.php | 4 ++-- .../CatalogSearch/Model/Indexer/Fulltext/Action/Full.php | 4 ++-- .../Model/Indexer/Fulltext/Action/IndexIterator.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/IndexStructure.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexStructureProxy.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexSwitcherInterface.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexSwitcherProxy.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/IndexerHandler.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/ProductFieldset.php | 4 ++-- .../CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php | 4 ++-- .../Model/Indexer/Scope/IndexTableNotExistException.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php | 4 ++-- .../CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php | 4 ++-- .../Model/Indexer/Scope/UnknownStateException.php | 4 ++-- .../Magento/CatalogSearch/Model/ResourceModel/Advanced.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Advanced/Collection.php | 4 ++-- app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php | 4 ++-- .../Magento/CatalogSearch/Model/ResourceModel/Fulltext.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Fulltext/Collection.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Search/Collection.php | 4 ++-- .../Search/BaseSelectStrategy/BaseSelectStrategyInterface.php | 4 ++-- .../Model/Search/BaseSelectStrategy/StrategyMapper.php | 4 ++-- .../CatalogSearch/Model/Search/CustomAttributeFilterCheck.php | 4 ++-- .../Model/Search/FilterMapper/CustomAttributeFilter.php | 4 ++-- .../Model/Search/FilterMapper/DimensionsProcessor.php | 4 ++-- .../Model/Search/FilterMapper/ExclusionStrategy.php | 4 ++-- .../CatalogSearch/Model/Search/FilterMapper/FilterContext.php | 4 ++-- .../CatalogSearch/Model/Search/FilterMapper/FilterMapper.php | 4 ++-- .../Model/Search/FilterMapper/FilterStrategyInterface.php | 4 ++-- .../Model/Search/FilterMapper/StaticAttributeStrategy.php | 4 ++-- .../Model/Search/FilterMapper/StockStatusFilter.php | 4 ++-- .../Model/Search/FilterMapper/TermDropdownStrategy.php | 4 ++-- .../TermDropdownStrategy/ApplyStockConditionToSelect.php | 4 ++-- .../FilterMapper/TermDropdownStrategy/SelectBuilder.php | 4 ++-- .../Model/Search/FilterMapper/VisibilityFilter.php | 4 ++-- .../Magento/CatalogSearch/Model/Search/FiltersExtractor.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php | 4 ++-- .../Model/Search/QueryChecker/FullTextSearchCheck.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php | 4 ++-- .../Magento/CatalogSearch/Model/Search/RequestGenerator.php | 4 ++-- .../CatalogSearch/Model/Search/RequestGenerator/Decimal.php | 4 ++-- .../CatalogSearch/Model/Search/RequestGenerator/General.php | 4 ++-- .../Model/Search/RequestGenerator/GeneratorInterface.php | 4 ++-- .../Model/Search/RequestGenerator/GeneratorResolver.php | 4 ++-- .../Model/Search/SelectContainer/SelectContainer.php | 4 ++-- .../Model/Search/SelectContainer/SelectContainerBuilder.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/TableMapper.php | 4 ++-- app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php | 4 ++-- .../Setup/Patch/Data/SetInitialSearchWeightForAttributes.php | 4 ++-- app/code/Magento/CatalogSearch/composer.json | 2 +- 69 files changed, 137 insertions(+), 137 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 65bc7b5fb0c20..79f6024132be7 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -18,8 +18,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php index 2e41183940052..639c0aecb3615 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php @@ -15,8 +15,8 @@ use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class AggregationResolver implements AggregationResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php index 3990587fa8c75..1ac7ad3773740 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php @@ -17,8 +17,8 @@ * Request checker for catalog view. * * Checks catalog view query whether required to collect all attributes for entity. - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CatalogView implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php index 70c076fc21639..7e0ad7c46d6f3 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php @@ -10,8 +10,8 @@ use Magento\Store\Model\StoreManagerInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class RequestCheckerComposite implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php index 5c28db9a3b07a..81b7414380bf1 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php @@ -10,8 +10,8 @@ /** * RequestCheckerInterface provides the interface to work with query checkers. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php index 48a78204774f7..15856bbee7461 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php @@ -18,8 +18,8 @@ use Magento\Framework\Search\Request\BucketInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider implements DataProviderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php index 29238022811c5..26837448f2df2 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php @@ -22,8 +22,8 @@ /** * Attribute query builder * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php index 155dea824cde2..ddb4085fa13d9 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php @@ -22,8 +22,8 @@ /** * Build select for attribute. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectBuilderForAttribute { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php index aa3d82954cfe7..be572793f1ec3 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php @@ -14,8 +14,8 @@ /** * Join stock table with stock condition to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ApplyStockConditionToSelect { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php index 8ee404e9df2ba..27a784f8609bb 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php @@ -19,8 +19,8 @@ * The main idea of this strategy is using eav index table as main table for query * in case when search request requires search by attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class BaseSelectAttributesSearchStrategy implements BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php index b0bf91013af35..bff878122c8c4 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php @@ -18,8 +18,8 @@ * The main idea of this strategy is using fulltext search index table as main table for query * in case when search request does not requires any search by attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class BaseSelectFullTextSearchStrategy implements BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php index bed27c16f3ab8..eb4761adf830c 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php @@ -24,8 +24,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider implements DataProviderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php index 30be62826fc9a..c24acf4610e07 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Resolver implements ResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php index 82bd3d139f35d..bf431396cc0c7 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php @@ -12,8 +12,8 @@ * Purpose of class is to resolve table alias for Search Request filter * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class AliasResolver { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php index c51de6e28b26d..2ffa63098cdee 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php @@ -25,8 +25,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Preprocessor implements PreprocessorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php index 6bf5bb632f02b..a5650cac73395 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php @@ -18,8 +18,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index 81c0ecdb32128..b49809cfc8059 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -43,8 +43,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php index 4584838782a98..be2609ccc338a 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php @@ -10,8 +10,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Builder extends RequestBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Fulltext.php index 2e7eb097af5cf..398d6e9dd18dd 100644 --- a/app/code/Magento/CatalogSearch/Model/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Fulltext.php @@ -22,8 +22,8 @@ * @method string getDataIndex() * @method \Magento\CatalogSearch\Model\Fulltext setDataIndex(string $value) * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 2b4be8369de59..9ea4007c6bde1 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -23,8 +23,8 @@ * @api * @since 100.0.2 * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Full { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php index 1a18b4c05e396..a2c39deff1892 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php @@ -15,8 +15,8 @@ * @api * @since 100.0.3 * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexIterator implements \Iterator { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php index 31916c456f000..0308fda657375 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php @@ -17,8 +17,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexStructure implements IndexStructureInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php index cee6bb9f6488e..f8863aca8db9c 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php @@ -8,8 +8,8 @@ use Magento\Framework\Indexer\IndexStructureInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexStructureProxy implements IndexStructureInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php index 798801187b4e4..1cdd9c5b9fa5e 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php @@ -9,8 +9,8 @@ * Provides a functionality to replace main index with its temporary representation * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php index f3b6399c4d7e2..cd0aa12f9137b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php @@ -12,8 +12,8 @@ /** * Proxy for adapter-specific index switcher * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexSwitcherProxy implements IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php index bbdb1dd7b6502..9f105bd3ea462 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php @@ -18,8 +18,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexerHandler implements IndexerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php b/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php index 426fa69a5fd09..6db063bde7d1e 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php @@ -13,8 +13,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ProductFieldset implements \Magento\Framework\Indexer\FieldsetInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php index 168446e960689..ed2b1be5c7035 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php @@ -12,8 +12,8 @@ /** * Provides a functionality to replace main index with its temporary representation * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexSwitcher implements IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php index fa7bcce8f2274..b01f3c50d5002 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php @@ -14,8 +14,8 @@ * * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexTableNotExistException extends LocalizedException { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php index c96ccf3663b48..02d533d7bcb49 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php @@ -12,8 +12,8 @@ * Implementation of IndexScopeResolverInterface which resolves index scope dynamically * depending on current scope state * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php index f11d8709ba4a3..35f616f109638 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php @@ -19,8 +19,8 @@ * which means that default indexer table should be left unchanged during indexation * and temporary table should be used instead. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class State { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php index 70af9cafd749e..796559d1f7034 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php @@ -12,8 +12,8 @@ /** * Resolves name of a temporary table for indexation * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryResolver implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php index cce195c953ebd..8722cd52b618a 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php @@ -13,8 +13,8 @@ * * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class UnknownStateException extends LocalizedException { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php index 2aab76cb9536f..d88e5627df0e0 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php @@ -11,8 +11,8 @@ * @author Magento Core Team <core@magentocommerce.com> * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 8d097487b1bfe..a660cf62b1ad9 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -23,8 +23,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php index a6a97a89882a2..49caede8c4ac2 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php @@ -8,8 +8,8 @@ /** * CatalogSearch Fulltext Index Engine resource model * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Engine implements EngineInterface { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php index 49d1fe82d8e28..ff9aeb4fb4474 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php @@ -14,8 +14,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 7e0cb306d483b..916bfdd602029 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -24,8 +24,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index e706756515a14..aff558c6d0244 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -12,8 +12,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection implements \Magento\Search\Model\SearchCollectionInterface diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php index 1904df9ccd53b..2d8dfb9222497 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php @@ -10,8 +10,8 @@ /** * This interface represents strategy that will be used to create base select for search request * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php index 963dd53295430..e554d3c774a31 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php @@ -12,8 +12,8 @@ /** * This class is responsible for deciding which BaseSelectStrategyInterface should be used for passed SelectContainer * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StrategyMapper { diff --git a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php index bac8c1bb57c11..bcd4080b30b14 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php @@ -12,8 +12,8 @@ /** * Checks if FilterInterface is by custom attribute * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CustomAttributeFilterCheck { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php index 4431d3d7dab58..a8bb3b2fe281f 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php @@ -19,8 +19,8 @@ * Class CustomAttributeFilter * Applies filters by custom attributes to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CustomAttributeFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php index df314377b5afc..3d2b9eed03761 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php @@ -17,8 +17,8 @@ * Class DimensionsProcessor * Adds dimension conditions to select query * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DimensionsProcessor { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php index e7cf5da09351d..c382569338e29 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php @@ -21,8 +21,8 @@ /** * Strategy which processes exclusions from general rules * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php index 692e199fffa01..67ed66da2a036 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php @@ -15,8 +15,8 @@ * Its responsibility is to choose appropriate strategy to apply passed filter to the Select * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FilterContext implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php index 49a55ddf26e4b..7136fad5b19a9 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php @@ -14,8 +14,8 @@ * Class FilterMapper * This class applies filters to Select based on SelectContainer configuration * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FilterMapper { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php index 7925a619c8095..a61c691c0d5cd 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php @@ -10,8 +10,8 @@ * FilterStrategyInterface provides the interface to work with strategies * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php index 1e35a3c0352b1..3986cc617f06d 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php @@ -13,8 +13,8 @@ /** * This strategy handles static attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StaticAttributeStrategy implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php index f15e313ce06a6..0e3ba0d4e669f 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php @@ -16,8 +16,8 @@ * Class StockStatusFilter * Adds filter by stock status to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StockStatusFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php index bbec04eed0621..9d7e31ee3b6d1 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php @@ -16,8 +16,8 @@ * - The filter for dropdown or multi-select attribute * - The filter is Term filter * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TermDropdownStrategy implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php index 64a2fdc25bb02..c28bc3485cf49 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php @@ -14,8 +14,8 @@ /** * Apply stock condition to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ApplyStockConditionToSelect { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php index 85281ce556889..007647db39b32 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php @@ -17,8 +17,8 @@ /** * Add joins to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php index c73651ad8007d..690ef9115edfe 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php @@ -17,8 +17,8 @@ * Class VisibilityFilter * Applies filter by visibility to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class VisibilityFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php b/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php index 4a654acc920c5..55c8582979912 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php @@ -13,8 +13,8 @@ * Class FiltersExtractor * Extracts filters from QueryInterface * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FiltersExtractor { diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index 8c4e5c432d5bc..906220db28dc1 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -26,8 +26,8 @@ /** * Build base Query for Index * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexBuilder implements IndexBuilderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php b/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php index a70f83d7ac91b..c122bae15cb0c 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php @@ -13,8 +13,8 @@ /** * Class is responsible for checking if fulltext search is required for search query * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FullTextSearchCheck { diff --git a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php index 7256e11b8edbd..916e03f471493 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php +++ b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php @@ -6,8 +6,8 @@ namespace Magento\CatalogSearch\Model\Search; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ReaderPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 8e47a0674e2da..6e6aee08f926e 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -16,8 +16,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class RequestGenerator { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php index 5729b2544b3f4..ceff0ea2e5d17 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Decimal implements GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php index 8db96ad04b20f..4321105a7e8fd 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class General implements GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php index 2eb7d06d31a5c..863f1fb7466c9 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php @@ -11,8 +11,8 @@ /** * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php index 5e4c2e0ff8ad6..68ca546b81919 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php @@ -9,8 +9,8 @@ /** * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class GeneratorResolver { diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php index e32785a6a17af..f0eade4bfbcf5 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php @@ -12,8 +12,8 @@ /** * This class is a container for all data that is required for creating select query by search request * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectContainer { diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php index b6e60aabf484a..d5b7be8bf0106 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php @@ -18,8 +18,8 @@ * Class SelectContainerBuilder * Class is responsible for SelectContainer creation and filling it with all required data * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectContainerBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php index 001f9936c9586..6b18c4307f515 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php @@ -25,8 +25,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TableMapper { diff --git a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php index cb7210813b056..956a1b2360f89 100644 --- a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php +++ b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php @@ -10,8 +10,8 @@ /** * Enable Product EAV indexer in configuration for MySQL search engine * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class EnableEavIndexer { diff --git a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php index 23429dd43e3fe..7f6dbe033e3a5 100644 --- a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php +++ b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php @@ -13,8 +13,8 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SetInitialSearchWeightForAttributes implements DataPatchInterface, PatchVersionInterface { diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index a823867296ffd..7bcb91e945417 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -1,6 +1,6 @@ { "name": "magento/module-catalog-search", - "description": "[Deprecated] CatalogSearch will be removed in 2.4, and ElasticSearch will replace it as the default search engine.", + "description": "Catalog search", "config": { "sort-packages": true }, From 50da0a7fde2b207ecf78c768586db51e70d96898 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Fri, 28 Sep 2018 14:49:53 -0500 Subject: [PATCH 0264/1415] MAGETWO-95048: Sidebar navigation is broken for Stores > Configuration, All Stores. - Fix up docblocks causing code sniff errors --- app/code/Magento/Backend/Block/Menu.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Backend/Block/Menu.php b/app/code/Magento/Backend/Block/Menu.php index 3ef4168238b48..1e2561e2efe05 100644 --- a/app/code/Magento/Backend/Block/Menu.php +++ b/app/code/Magento/Backend/Block/Menu.php @@ -9,12 +9,12 @@ /** * Backend menu block * - * @api - * @method \Magento\Backend\Block\Menu setAdditionalCacheKeyInfo(array $cacheKeyInfo) + * @method $this setAdditionalCacheKeyInfo(array $cacheKeyInfo) * @method array getAdditionalCacheKeyInfo() - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Menu extends \Magento\Backend\Block\Template { @@ -80,16 +80,17 @@ class Menu extends \Magento\Backend\Block\Template private $routeConfig; /** - * @param Template\Context $context + * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Model\UrlInterface $url * @param \Magento\Backend\Model\Menu\Filter\IteratorFactory $iteratorFactory * @param \Magento\Backend\Model\Auth\Session $authSession * @param \Magento\Backend\Model\Menu\Config $menuConfig * @param \Magento\Framework\Locale\ResolverInterface $localeResolver - * @param \Magento\Framework\App\Route\ConfigInterface $routeConfig * @param array $data * @param MenuItemChecker|null $menuItemChecker * @param AnchorRenderer|null $anchorRenderer + * @param \Magento\Framework\App\Route\ConfigInterface|null $routeConfig + * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -141,6 +142,7 @@ protected function _getAnchorLabel($menuItem) /** * Render menu item mouse events + * * @param \Magento\Backend\Model\Menu\Item $menuItem * @return string */ @@ -354,7 +356,7 @@ protected function _columnBrake($items, $limit) * @param \Magento\Backend\Model\Menu\Item $menuItem * @param int $level * @param int $limit - * @param $id int + * @param int|null $id * @return string HTML code */ protected function _addSubMenu($menuItem, $level, $limit, $id = null) From 706fd1b965e1a04a6f7109b3300b24bddeccb19c Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 28 Sep 2018 17:03:01 -0500 Subject: [PATCH 0265/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - updated test --- .../Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index 3fdbb3eae0b19..66316d0af8b60 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -64,6 +64,7 @@ <!--Submit Order and verify information--> <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="seeCorrectGrandTotal"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskTodisappear"/> <waitForPageLoad stepKey="waitForOrderToProcess"/> <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPage" after="clickSubmitOrder"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeSuccessMessage" after="seeViewOrderPage"/> @@ -122,7 +123,8 @@ <!--Update Qty of items to be refunded and submit refund--> <scrollTo selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" stepKey="scrollToItemsToRefund"/> <fillField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" stepKey="fillQtyOfItemsToRefund" after="scrollToItemsToRefund"/> - <click selector="{{AdminCreditMemoItemsSection.updateQty}}" stepKey="updateRefundQty"/> + + <!--<click selector="{{AdminCreditMemoItemsSection.updateQty}}" stepKey="updateRefundQty"/>--> <waitForLoadingMaskToDisappear stepKey="waitForRefundQtyToUpdate"/> <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="seeSubmitRefundBtn"/> <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="submitRefundOffline"/> From 89a14719fb8b223ab607a6a92d90aeb36d7c4222 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Sat, 29 Sep 2018 16:45:27 +0300 Subject: [PATCH 0266/1415] MAGETWO-91532: Schedule update removes tier price - Fix integration test --- .../CatalogRule/Model/Indexer/BatchIndexTest.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/BatchIndexTest.php b/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/BatchIndexTest.php index b71b466714e8e..11556dcfb7e7b 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/BatchIndexTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/BatchIndexTest.php @@ -102,17 +102,20 @@ protected function prepareProducts($price) ->setUrlKey(null) ->setSku(uniqid($this->product->getSku() . '-')) ->setName(uniqid($this->product->getName() . '-')) - ->setWebsiteIds([1]); - $productSecond->save(); - $productSecond->setPrice($price)->save(); + ->setWebsiteIds([1]) + ->save(); + $productSecond->setPrice($price); + $this->productRepository->save($productSecond); $productThird = clone $this->product; $productThird->setId(null) ->setUrlKey(null) - ->setSku(uniqid($this->product->getSku() . '-')) - ->setName(uniqid($this->product->getName() . '-')) + ->setSku(uniqid($this->product->getSku() . '--')) + ->setName(uniqid($this->product->getName() . '--')) ->setWebsiteIds([1]) ->save(); - $productThird->setPrice($price)->save(); + $productThird->setPrice($price); + $this->productRepository->save($productThird); + return [ $productSecond->getEntityId(), $productThird->getEntityId(), From b3420b3147dd1f24ff47c8fa4e1bdd18dc19f23b Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Sat, 29 Sep 2018 18:07:57 +0300 Subject: [PATCH 0267/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Fix static tests --- .../testsuite/Magento/Authorizenet/Model/DirectpostTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php index 3681dfe8e5bd2..5ba513e5de6c6 100644 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php +++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php @@ -19,6 +19,8 @@ /** * Class contains tests for Direct Post integration + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DirectpostTest extends \PHPUnit\Framework\TestCase { From 44d4e3ef6a70dd2f0f7b21fca3ca4b69a4217227 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Sat, 29 Sep 2018 18:32:11 +0300 Subject: [PATCH 0268/1415] MAGETWO-91547: Unable to create Credit memo for order with no payment required - Fix static tests --- .../testsuite/Magento/Authorizenet/Model/DirectpostTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php index 5ba513e5de6c6..ba4c4efd78f1b 100644 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php +++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php @@ -19,7 +19,7 @@ /** * Class contains tests for Direct Post integration - * + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DirectpostTest extends \PHPUnit\Framework\TestCase From a7a43be69cad7ef6ace82ad97756b112ecd6415e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 1 Oct 2018 09:56:38 +0300 Subject: [PATCH 0269/1415] MAGETWO-91650: Translation not working for product alerts - Revert changes --- app/code/Magento/ProductAlert/Model/Email.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 18adc54c2d660..7aee4ca01240d 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -359,7 +359,6 @@ public function send() $storeId = $this->storeId ?: (int) $this->_customer->getStoreId(); $store = $this->getStore($storeId); - $storeId = $store->getId(); $this->_appEmulation->startEnvironmentEmulation($storeId); @@ -408,6 +407,18 @@ public function send() return true; } + /** + * Retrieve the store for the email + * + * @param int $storeId + * @return StoreInterface + * @throws NoSuchEntityException + */ + private function getStore(int $storeId): StoreInterface + { + return $this->_storeManager->getStore($storeId); + } + /** * Retrieve the block for the email based on type * From 7cd36de951ca85bdeab03df32aea0d36e066c49e Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 1 Oct 2018 11:10:08 +0300 Subject: [PATCH 0270/1415] Refactoring the method's description --- app/code/Magento/Catalog/Model/Product.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index fe020f450a6ee..cd68ca9889991 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -498,8 +498,8 @@ protected function _getResource() } /** - * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for - * product will return all product attribute codes + * Get a list of custom attribute codes that belongs to product attribute set. + * If attribute set not specified for product will return all product attribute codes. * * @return string[] */ @@ -663,7 +663,7 @@ public function getStatus() /** * Retrieve type instance of the product. - * Type instance implements product type depended logic and is a singleton shared by all products of the same type. + * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType */ @@ -2217,8 +2217,8 @@ public function getPreconfiguredValues() } /** - * Prepare product custom options.To be sure that all product custom options does not has ID and has product - * instance + * Prepare product custom options. + * To be sure that all product custom options does not has ID and has product instance. * * @return \Magento\Catalog\Model\Product */ From cc00197d13d6244e32201e4c6bf00287e54747c5 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Mon, 1 Oct 2018 13:49:26 +0300 Subject: [PATCH 0271/1415] MAGETWO-91702: Shipping method Table Rates settings gets from wrong store - Fix website id for shipping --- app/code/Magento/Quote/Model/Quote/Address.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 11beffe5711b9..140ace42afae1 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -1003,8 +1003,14 @@ public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractIte /** * Store and website identifiers specified from StoreManager */ - $request->setStoreId($this->getQuote()->getStoreId() ?? $this->storeManager->getStore()->getId()); - $request->setWebsiteId($this->storeManager->getWebsite()->getId()); + if ($this->getQuote()->getStoreId()) { + $storeId = $this->getQuote()->getStoreId(); + $request->setStoreId($storeId); + $request->setWebsiteId($this->storeManager->getStore($storeId)->getWebsiteId()); + } else { + $request->setStoreId($this->storeManager->getStore()->getId()); + $request->setWebsiteId($this->storeManager->getWebsite()->getId()); + } $request->setFreeShipping($this->getFreeShipping()); /** * Currencies need to convert in free shipping From d9ee86dc4d2e7072dd768375ce393f4771c175e6 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 14:40:49 +0300 Subject: [PATCH 0272/1415] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Mftf/Page/AdminUrlRewriteIndexPage.xml | 14 ++++ .../Section/AdminUrlRewriteIndexSection.xml | 16 ++++ ...writesForProductInAnchorCategoriesTest.xml | 81 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml new file mode 100644 index 0000000000000..c7c450a00a0c3 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminUrlRewriteIndexPage" url="admin/url_rewrite/index/" area="admin" module="Magento_UrlRewrite"> + <section name="AdminUrlRewriteIndexSection"/> + </page> +</pages> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml new file mode 100644 index 0000000000000..a7a17482a8ec1 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUrlRewriteIndexSection"> + <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> + <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> + <element name="search" type="button" selector="[data-action='grid-filter-apply']" timeout="10"/> + </section> +</sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml new file mode 100644 index 0000000000000..8591b0f93f926 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUrlRewritesForProductInAnchorCategoriesTest"> + <annotations> + <features value="Url Rewrite"/> + <stories value="Url-rewrites for product in anchor categories"/> + <title value="Url-rewrites for product in anchor categories"/> + <description value="For a product with category that has parent anchor categories, the rewrites is created when the category/product is saved."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-69826"/> + <group value="UrlRewrite"/> + </annotations> + + <!-- Preconditions--> + <!-- Create 3 categories --> + <before> + <createData entity="SimpleSubCategory" stepKey="simpleSubCategory1"/> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory2"> + <requiredEntity createDataKey="simpleSubCategory1"/> + </createData> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory3"> + <requiredEntity createDataKey="simpleSubCategory2"/> + </createData> + <!-- Create Simple product 1 and assign it to Category 3 --> + <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="simpleSubCategory3"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="simpleSubCategory3" stepKey="deletesimpleSubCategory3"/> + <deleteData createDataKey="simpleSubCategory2" stepKey="deletesimpleSubCategory2"/> + <deleteData createDataKey="simpleSubCategory1" stepKey="deletesimpleSubCategory1"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + <!-- Steps --> + <!-- 1. Log in to Admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + + <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> + <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue4"/> + + <!-- 3. Edit Category 1 for DEFAULT Store View: --> + <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView"> + <argument name="Store" value="_defaultStore.name"/> + <argument name="CatName" value="SimpleSubCategory.name"/> + </actionGroup> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection2"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckRedirect2"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new" stepKey="changeURLKey"/> + + <!-- 4. Save Category 1 --> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessageAfterSaved"/> + + <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> + <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> + </test> +</tests> From 16a7f0babc8cfd4420dfea32c35449745449791b Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:05:26 -0300 Subject: [PATCH 0273/1415] Use @inheritdoc and revert back code change --- .../Framework/Stdlib/DateTime/Timezone.php | 125 +++--------------- 1 file changed, 15 insertions(+), 110 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 2bfa465c8268f..fbda76a8e3616 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -85,9 +85,7 @@ public function __construct( } /** - * Return path to default timezone - * - * @return string + * @inheritdoc */ public function getDefaultTimezonePath() { @@ -95,9 +93,7 @@ public function getDefaultTimezonePath() } /** - * Retrieve timezone code - * - * @return string + * @inheritdoc */ public function getDefaultTimezone() { @@ -105,11 +101,7 @@ public function getDefaultTimezone() } /** - * Gets the scope config timezone - * - * @param string $scopeType - * @param string $scopeCode - * @return string + * @inheritdoc */ public function getConfigTimezone($scopeType = null, $scopeCode = null) { @@ -121,10 +113,7 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null) } /** - * Retrieve ISO date format - * - * @param int $type - * @return string + * @inheritdoc */ public function getDateFormat($type = \IntlDateFormatter::SHORT) { @@ -136,9 +125,7 @@ public function getDateFormat($type = \IntlDateFormatter::SHORT) } /** - * Retrieve short date format with 4-digit year - * - * @return string + * @inheritdoc */ public function getDateFormatWithLongYear() { @@ -150,10 +137,7 @@ public function getDateFormatWithLongYear() } /** - * Retrieve ISO time format - * - * @param string $type - * @return string + * @inheritdoc */ public function getTimeFormat($type = \IntlDateFormatter::SHORT) { @@ -165,10 +149,7 @@ public function getTimeFormat($type = \IntlDateFormatter::SHORT) } /** - * Retrieve ISO datetime format - * - * @param string $type - * @return string + * @inheritdoc */ public function getDateTimeFormat($type) { @@ -176,13 +157,7 @@ public function getDateTimeFormat($type) } /** - * Create \DateTime object for current locale - * - * @param mixed $date - * @param string $locale - * @param bool $useTimezone - * @param bool $includeTime - * @return \DateTime + * @inheritdoc */ public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true) { @@ -216,12 +191,7 @@ public function date($date = null, $locale = null, $useTimezone = true, $include } /** - * Create \DateTime object with date converted to scope timezone and scope Locale - * - * @param mixed $scope Information about scope - * @param string|integer|\DateTime|array|null $date date in UTC - * @param boolean $includeTime flag for including time to date - * @return \DateTime + * @inheritdoc */ public function scopeDate($scope = null, $date = null, $includeTime = false) { @@ -234,12 +204,7 @@ public function scopeDate($scope = null, $date = null, $includeTime = false) } /** - * Format date using current locale options and time zone. - * - * @param \DateTime|null $date - * @param int $format - * @param bool $showTime - * @return string + * @inheritdoc */ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $showTime = false) { @@ -253,12 +218,7 @@ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $s } /** - * Get scope timestamp - * - * Timestamp will be built with scope timezone settings - * - * @param mixed $scope - * @return int + * @inheritdoc */ public function scopeTimeStamp($scope = null) { @@ -271,12 +231,7 @@ public function scopeTimeStamp($scope = null) } /** - * Checks if current date of the given scope (in the scope timezone) is within the range - * - * @param int|string|\Magento\Framework\App\ScopeInterface $scope - * @param string|null $dateFrom - * @param string|null $dateTo - * @return bool + * @inheritdoc */ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) { @@ -302,13 +257,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * @param string|\DateTimeInterface $date - * @param int $dateType - * @param int $timeType - * @param string|null $locale - * @param string|null $timezone - * @param string|null $pattern - * @return string + * @inheritdoc */ public function formatDateTime( $date, @@ -344,56 +293,15 @@ public function formatDateTime( } /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @throws LocalizedException - * @return string - * @deprecated + * @inheritdoc */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') - { - return $this->convertConfigTimeToUtcWithPattern($date, $format); - } - - /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @param string $pattern - * @throws LocalizedException - * @return string - * @deprecated - */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = null) { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { - $locale = $this->_localeResolver->getLocale(); - if ($locale === null) { - $pattern = 'Y-M-dd HH:mm:ss'; - } - $formatter = new \IntlDateFormatter( - $locale, - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - $pattern - ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - - $dateUniversal = $dateTime->gmtDate(null, $unixTime); - $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone())); } } else { if ($date->getTimezone()->getName() !== $this->getConfigTimezone()) { @@ -405,13 +313,10 @@ public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s' ); } } - $date->setTimezone(new \DateTimeZone('UTC')); - return $date->format($format); } - /** * Retrieve date with time * From 9315dd6963834ec6299eed8395add8bdb7bb7895 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:07:53 -0300 Subject: [PATCH 0274/1415] Revert back code change to fix BiC --- .../Framework/Stdlib/DateTime/Timezone.php | 16 ++++++++++++++-- .../Stdlib/DateTime/TimezoneInterface.php | 14 -------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index fbda76a8e3616..5dbaf093698a1 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,7 +257,13 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * @inheritdoc + * @param string|\DateTimeInterface $date + * @param int $dateType + * @param int $timeType + * @param string|null $locale + * @param string|null $timezone + * @param string|null $pattern + * @return string */ public function formatDateTime( $date, @@ -293,7 +299,13 @@ public function formatDateTime( } /** - * @inheritdoc + * Convert date from config timezone to Utc. + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date + * @param string $format + * @throws LocalizedException + * @return string */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 17ba759a4d763..e8e20070c55de 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -152,18 +152,4 @@ public function formatDateTime( * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); - - /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @param string $pattern - * @throws LocalizedException - * @return string - * @deprecated - */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From 42cd2282007b0fc191413f8d483c58c6729823fc Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:08:38 -0300 Subject: [PATCH 0275/1415] Revert back @deprecated tag --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index e8e20070c55de..11e9a22d8cea5 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -149,7 +149,6 @@ public function formatDateTime( * @param string $format * @throws LocalizedException * @return string - * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); } From ddeaf36c942f17f720cc720c840aeb844e93efbf Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:09:24 -0300 Subject: [PATCH 0276/1415] Revert back new lines --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 5dbaf093698a1..2bc0b36cb6ef7 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -325,7 +325,9 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') ); } } + $date->setTimezone(new \DateTimeZone('UTC')); + return $date->format($format); } From 6cc903442a668370898ee352871510f48a72bc21 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:10:48 -0300 Subject: [PATCH 0277/1415] Revert back documentation change in API interface --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 2 +- .../Framework/Stdlib/DateTime/TimezoneInterface.php | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 2bc0b36cb6ef7..8534e798481cb 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -327,7 +327,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') } $date->setTimezone(new \DateTimeZone('UTC')); - + return $date->format($format); } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 11e9a22d8cea5..217bf5b7f010d 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,7 +104,6 @@ public function formatDate( /** * Gets the scope config timezone - * * @param string $scopeType * @param string $scopeCode * @return string @@ -122,7 +121,6 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** - * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -141,14 +139,10 @@ public function formatDateTime( ); /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * * @param string|\DateTimeInterface $date * @param string $format - * @throws LocalizedException * @return string + * @since 100.1.0 */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); } From 28617c01e62941eaa68df8b6ea72a958c6f5367c Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:11:51 -0300 Subject: [PATCH 0278/1415] Fix documentation change for code smell --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 217bf5b7f010d..c2ef294daf0c8 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,6 +104,7 @@ public function formatDate( /** * Gets the scope config timezone + * * @param string $scopeType * @param string $scopeCode * @return string From fd0ab037a74cc5d78d02c603adbd5cf10cb92c88 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:12:38 -0300 Subject: [PATCH 0279/1415] Fix documentation --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index c2ef294daf0c8..4aff80161ef80 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,7 +104,7 @@ public function formatDate( /** * Gets the scope config timezone - * + * * @param string $scopeType * @param string $scopeCode * @return string From 94d735e033314f6c384f0eba51647d9219f62ed8 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 17:06:00 +0300 Subject: [PATCH 0280/1415] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 8591b0f93f926..22c27042aad52 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -71,9 +71,9 @@ <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> From 149242f9d23d1a8d352d5c5c532ba0b1be3e5bd9 Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Mon, 1 Oct 2018 17:33:14 +0300 Subject: [PATCH 0281/1415] MAGETWO-91530: Expose Authorize.net Response Codes in Checkout - Propagate payment error message --- .../Payment/view/frontend/templates/transparent/iframe.phtml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml index c127371cb5f47..35dbfe9622bea 100644 --- a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml @@ -40,9 +40,7 @@ $params = $block->getParams(); $(parent).trigger('clearTimeout'); fullScreenLoader.stopLoader(); globalMessageList.addErrorMessage({ - message: $t( - 'A server error stopped your order from being placed. Please try to place your order again.' - ) + message: $t(<?=json_encode($params['error_msg'])?>) }); } ); From 772ae6b8df140d0b88f804c5ddf18266fdc18f13 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 17:34:22 +0300 Subject: [PATCH 0282/1415] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Test/Mftf/Section/AdminUrlRewriteIndexSection.xml | 1 - .../AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml index a7a17482a8ec1..3c445b5cf3e6f 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml @@ -11,6 +11,5 @@ <section name="AdminUrlRewriteIndexSection"> <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> - <element name="search" type="button" selector="[data-action='grid-filter-apply']" timeout="10"/> </section> </sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 22c27042aad52..562d414a63ddb 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -15,7 +15,7 @@ <description value="For a product with category that has parent anchor categories, the rewrites is created when the category/product is saved."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69826"/> - <group value="UrlRewrite"/> + <group value="urlRewrite"/> </annotations> <!-- Preconditions--> @@ -47,7 +47,7 @@ <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> - <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> @@ -69,7 +69,7 @@ <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> - <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> From 720a5c63e11d75615e2f3de6c452f5aa097ba0fe Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Mon, 1 Oct 2018 17:51:19 +0300 Subject: [PATCH 0283/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix CR Issues --- .../GroupedProduct/view/adminhtml/web/css/grouped-product.css | 2 +- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- .../view/adminhtml/web/template/components/position.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index 1916f222a499b..cd0aa25ae1f88 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -102,4 +102,4 @@ .icon-backward:before { content: '\e619'; -} \ No newline at end of file +} diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 0a585eb92958d..7c9563bb1a0ce 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -206,4 +206,4 @@ define([ }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html index dbfeff2e32c04..050fb3c2898ce 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html @@ -16,4 +16,4 @@ "> <span>Bottom</span> </a> -</div> \ No newline at end of file +</div> From b77c7acf6ee5dca25ab9431e83de91bb00b58795 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Mon, 1 Oct 2018 17:59:51 +0300 Subject: [PATCH 0284/1415] MAGETWO-58210: Import Products sets default behaviour as append, need add_update - Added "add_update" behavior for checking by default --- .../ImportExport/Model/Import/Entity/AbstractEntity.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index e965e8ad207fd..96704667bfc61 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -554,6 +554,7 @@ public function getBehavior() $this->_parameters['behavior'] ) || $this->_parameters['behavior'] != ImportExport::BEHAVIOR_APPEND && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_ADD_UPDATE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_REPLACE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_DELETE ) { @@ -828,6 +829,8 @@ public function validateData() } /** + * Get instance of error aggregator. + * * @return ProcessingErrorAggregatorInterface */ public function getErrorAggregator() From 5f1b9a0f4ec9d6276d811c166b5a0345f4e74222 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Mon, 1 Oct 2018 18:16:06 +0200 Subject: [PATCH 0285/1415] MC-4189: IE11 - PageBuilder Does Not Load - Revert changes to es6-collections.js --- lib/web/es6-collections.js | 273 ++++++++++++++++++++++++++++++------- 1 file changed, 227 insertions(+), 46 deletions(-) diff --git a/lib/web/es6-collections.js b/lib/web/es6-collections.js index ed8e80c1fd07e..50ff560e53a8a 100644 --- a/lib/web/es6-collections.js +++ b/lib/web/es6-collections.js @@ -1,46 +1,227 @@ -/* - * Copyright 2012 The Polymer Authors. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -if (typeof WeakMap === 'undefined') { - (function() { - var defineProperty = Object.defineProperty; - var counter = Date.now() % 1e9; - - var WeakMap = function() { - this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); - }; - - WeakMap.prototype = { - set: function(key, value) { - var entry = key[this.name]; - if (entry && entry[0] === key) - entry[1] = value; - else - defineProperty(key, this.name, {value: [key, value], writable: true}); - return this; - }, - get: function(key) { - var entry; - return (entry = key[this.name]) && entry[0] === key ? - entry[1] : undefined; - }, - delete: function(key) { - var entry = key[this.name]; - if (!entry) return false; - var hasValue = entry[0] === key; - entry[0] = entry[1] = undefined; - return hasValue; - }, - has: function(key) { - var entry = key[this.name]; - if (!entry) return false; - return entry[0] === key; - } - }; - - window.WeakMap = WeakMap; - })(); -} \ No newline at end of file +(function (exports) {'use strict'; + //shared pointer + var i; + //shortcuts + var defineProperty = Object.defineProperty, is = function(a,b) { return isNaN(a)? isNaN(b): a === b; }; + + + //Polyfill global objects + if (typeof WeakMap == 'undefined') { + exports.WeakMap = createCollection({ + // WeakMap#delete(key:void*):boolean + 'delete': sharedDelete, + // WeakMap#clear(): + clear: sharedClear, + // WeakMap#get(key:void*):void* + get: sharedGet, + // WeakMap#has(key:void*):boolean + has: mapHas, + // WeakMap#set(key:void*, value:void*):void + set: sharedSet + }, true); + } + + if (typeof Map == 'undefined' || typeof ((new Map).values) !== 'function' || !(new Map).values().next) { + exports.Map = createCollection({ + // WeakMap#delete(key:void*):boolean + 'delete': sharedDelete, + //:was Map#get(key:void*[, d3fault:void*]):void* + // Map#has(key:void*):boolean + has: mapHas, + // Map#get(key:void*):boolean + get: sharedGet, + // Map#set(key:void*, value:void*):void + set: sharedSet, + // Map#keys(void):Iterator + keys: sharedKeys, + // Map#values(void):Iterator + values: sharedValues, + // Map#entries(void):Iterator + entries: mapEntries, + // Map#forEach(callback:Function, context:void*):void ==> callback.call(context, key, value, mapObject) === not in specs` + forEach: sharedForEach, + // Map#clear(): + clear: sharedClear + }); + } + + if (typeof Set == 'undefined' || typeof ((new Set).values) !== 'function' || !(new Set).values().next) { + exports.Set = createCollection({ + // Set#has(value:void*):boolean + has: setHas, + // Set#add(value:void*):boolean + add: sharedAdd, + // Set#delete(key:void*):boolean + 'delete': sharedDelete, + // Set#clear(): + clear: sharedClear, + // Set#keys(void):Iterator + keys: sharedValues, // specs actually say "the same function object as the initial value of the values property" + // Set#values(void):Iterator + values: sharedValues, + // Set#entries(void):Iterator + entries: setEntries, + // Set#forEach(callback:Function, context:void*):void ==> callback.call(context, value, index) === not in specs + forEach: sharedForEach + }); + } + + if (typeof WeakSet == 'undefined') { + exports.WeakSet = createCollection({ + // WeakSet#delete(key:void*):boolean + 'delete': sharedDelete, + // WeakSet#add(value:void*):boolean + add: sharedAdd, + // WeakSet#clear(): + clear: sharedClear, + // WeakSet#has(value:void*):boolean + has: setHas + }, true); + } + + + /** + * ES6 collection constructor + * @return {Function} a collection class + */ + function createCollection(proto, objectOnly){ + function Collection(a){ + if (!this || this.constructor !== Collection) return new Collection(a); + this._keys = []; + this._values = []; + this._itp = []; // iteration pointers + this.objectOnly = objectOnly; + + //parse initial iterable argument passed + if (a) init.call(this, a); + } + + //define size for non object-only collections + if (!objectOnly) { + defineProperty(proto, 'size', { + get: sharedSize + }); + } + + //set prototype + proto.constructor = Collection; + Collection.prototype = proto; + + return Collection; + } + + + /** parse initial iterable argument passed */ + function init(a){ + var i; + //init Set argument, like `[1,2,3,{}]` + if (this.add) + a.forEach(this.add, this); + //init Map argument like `[[1,2], [{}, 4]]` + else + a.forEach(function(a){this.set(a[0],a[1])}, this); + } + + + /** delete */ + function sharedDelete(key) { + if (this.has(key)) { + this._keys.splice(i, 1); + this._values.splice(i, 1); + // update iteration pointers + this._itp.forEach(function(p) { if (i < p[0]) p[0]--; }); + } + // Aurora here does it while Canary doesn't + return -1 < i; + }; + + function sharedGet(key) { + return this.has(key) ? this._values[i] : undefined; + } + + function has(list, key) { + if (this.objectOnly && key !== Object(key)) + throw new TypeError("Invalid value used as weak collection key"); + //NaN or 0 passed + if (key != key || key === 0) for (i = list.length; i-- && !is(list[i], key);){} + else i = list.indexOf(key); + return -1 < i; + } + + function setHas(value) { + return has.call(this, this._values, value); + } + + function mapHas(value) { + return has.call(this, this._keys, value); + } + + /** @chainable */ + function sharedSet(key, value) { + this.has(key) ? + this._values[i] = value + : + this._values[this._keys.push(key) - 1] = value + ; + return this; + } + + /** @chainable */ + function sharedAdd(value) { + if (!this.has(value)) this._values.push(value); + return this; + } + + function sharedClear() { + this._values.length = 0; + } + + /** keys, values, and iterate related methods */ + function sharedKeys() { + return sharedIterator(this._itp, this._keys); + } + + function sharedValues() { + return sharedIterator(this._itp, this._values); + } + + function mapEntries() { + return sharedIterator(this._itp, this._keys, this._values); + } + + function setEntries() { + return sharedIterator(this._itp, this._values, this._values); + } + + function sharedIterator(itp, array, array2) { + var p = [0], done = false; + itp.push(p); + return { + next: function() { + var v, k = p[0]; + if (!done && k < array.length) { + v = array2 ? [array[k], array2[k]]: array[k]; + p[0]++; + } else { + done = true; + itp.splice(itp.indexOf(p), 1); + } + return { done: done, value: v }; + } + }; + } + + function sharedSize() { + return this._values.length; + } + + function sharedForEach(callback, context) { + var it = this.entries(); + for (;;) { + var r = it.next(); + if (r.done) break; + callback.call(context, r.value[1], r.value[0], this); + } + } + +})(typeof exports != 'undefined' && typeof global != 'undefined' ? global : window ); \ No newline at end of file From ec5d9b7f171e76c0285c6e683a4b2da5902c2f78 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 1 Oct 2018 15:31:32 -0300 Subject: [PATCH 0286/1415] #17744 Adding isVirtual mock to quote instance && fixs --- .../view/frontend/web/js/model/checkout-data-resolver.js | 3 +++ .../frontend/js/view/payment/method-renderer/paypal.test.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6f4c99438610b..d75da01b5ded5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -231,13 +231,16 @@ define([ isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { selectBillingAddress(addrs); + return true; } + return false; }); } shippingAddress = quote.shippingAddress(); + if (!isBillingAddressInitialized && shippingAddress && shippingAddress.canUseForBilling() && diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js index 6fabc513da9af..f9475d78607f4 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js @@ -24,7 +24,10 @@ define([ paymentMethod: ko.observable(), totals: ko.observable({ 'base_grand_total': 0 - }) + }), + isVirtual: function () { + return false; + } }, 'Magento_Braintree/js/view/payment/adapter': { config: {}, From e9a4403f89a67818e694fbe0c0d0233b36ec8c4b Mon Sep 17 00:00:00 2001 From: Ji Lu <jilu1@adobe.com> Date: Wed, 19 Sep 2018 11:05:57 -0500 Subject: [PATCH 0287/1415] MQE-1139: cleanup test modules in dev/tests/acceptance --- .../Mftf}/Metadata/image_content-meta.xml | 0 .../Test/StoreFrontMobileViewValidation.xml | 1 + .../Test/StorefrontRedirectToOrderHistory.xml | 1 + .../FunctionalTest/Framework/LICENSE.txt | 48 --- .../FunctionalTest/Framework/LICENSE_AFL.txt | 48 --- .../FunctionalTest/Framework/README.md | 3 - .../ActionGroup/TemplateActionGroupFile.xml | 14 - .../SampleTemplates/Data/TemplateDataFile.xml | 14 - .../SampleTemplates/LICENSE.txt | 48 --- .../SampleTemplates/LICENSE_AFL.txt | 48 --- .../Metadata/TemplateMetaFile.xml | 22 -- .../SampleTemplates/Page/TemplatePageFile.xml | 14 - .../FunctionalTest/SampleTemplates/README.md | 3 - .../Section/TemplateSectionFile.xml | 14 - .../SampleTemplates/Test/TemplateTestFile.xml | 24 -- .../ActionGroup/SampleActionGroup.xml | 24 -- .../SampleTests/Data/SampleData.xml | 32 -- .../FunctionalTest/SampleTests/LICENSE.txt | 48 --- .../SampleTests/LICENSE_AFL.txt | 48 --- .../SampleTests/Page/SamplePage.xml | 14 - .../FunctionalTest/SampleTests/README.md | 3 - .../SampleTests/Section/SampleSection.xml | 20 -- .../SampleTests/Test/AdvancedSampleTest.xml | 54 ---- .../SampleTests/Test/AssertsTest.xml | 79 ----- .../CreateConfigurableProductByApiTest.xml | 77 ----- .../Test/CreateSalesRuleByApiTest.xml | 24 -- .../SampleTests/Test/MinimumTest.xml | 26 -- .../Test/PersistMultipleEntitiesTest.xml | 36 --- .../SampleTests/Test/SampleTest.xml | 298 ------------------ .../Test/SetPaymentConfigurationTest.xml | 31 -- .../Test/UpdateSimpleProductByApiTest.xml | 29 -- 31 files changed, 2 insertions(+), 1143 deletions(-) rename {dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework => app/code/Magento/Catalog/Test/Mftf}/Metadata/image_content-meta.xml (100%) delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE_AFL.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/README.md delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/ActionGroup/TemplateActionGroupFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Data/TemplateDataFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE_AFL.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Metadata/TemplateMetaFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Page/TemplatePageFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/README.md delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Section/TemplateSectionFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Test/TemplateTestFile.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/ActionGroup/SampleActionGroup.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Data/SampleData.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE_AFL.txt delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Page/SamplePage.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/README.md delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Section/SampleSection.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml delete mode 100644 dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/Metadata/image_content-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/image_content-meta.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/Metadata/image_content-meta.xml rename to app/code/Magento/Catalog/Test/Mftf/Metadata/image_content-meta.xml diff --git a/app/code/Magento/Cms/Test/Mftf/Test/StoreFrontMobileViewValidation.xml b/app/code/Magento/Cms/Test/Mftf/Test/StoreFrontMobileViewValidation.xml index d1c44383b4ac1..6165def067ef4 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/StoreFrontMobileViewValidation.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/StoreFrontMobileViewValidation.xml @@ -11,6 +11,7 @@ <test name="StoreFrontMobileViewValidation"> <annotations> <features value="Cms"/> + <stories value="Mobile view page footer should stick to the bottom of page on Store front"/> <title value="Mobile view page footer should stick to the bottom of page on Store front"/> <description value="Mobile view page footer should stick to the bottom of page on Store front"/> <severity value="MAJOR"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml index ec725ad5fe4c5..19bcca985f974 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml @@ -11,6 +11,7 @@ <test name="StorefrontRedirectToOrderHistory"> <annotations> <features value="Redirection Rules"/> + <stories value="Create Invoice"/> <title value="Create Invoice"/> <description value="Check while order printing URL with an id of not relevant order redirects to order history"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE.txt deleted file mode 100644 index 49525fd99da9c..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Open Software License ("OSL") v. 3.0 - -This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Open Software License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE_AFL.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE_AFL.txt deleted file mode 100644 index f39d641b18a19..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/LICENSE_AFL.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Academic Free License ("AFL") v. 3.0 - -This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Academic Free License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/README.md b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/README.md deleted file mode 100644 index 7fbe454f709c2..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Framework/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Magento 2 Functional Tests - -The Functional Tests Module for **Magento_Framework**. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/ActionGroup/TemplateActionGroupFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/ActionGroup/TemplateActionGroupFile.xml deleted file mode 100644 index d1bc251f26321..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/ActionGroup/TemplateActionGroupFile.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name=""> - <!-- ADD TEST STEPS HERE --> - </actionGroup> -</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Data/TemplateDataFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Data/TemplateDataFile.xml deleted file mode 100644 index 6f13f04aef31d..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Data/TemplateDataFile.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="" type=""> - <data key=""></data> - </entity> -</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE.txt deleted file mode 100644 index 49525fd99da9c..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Open Software License ("OSL") v. 3.0 - -This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Open Software License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE_AFL.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE_AFL.txt deleted file mode 100644 index f39d641b18a19..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/LICENSE_AFL.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Academic Free License ("AFL") v. 3.0 - -This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Academic Free License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Metadata/TemplateMetaFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Metadata/TemplateMetaFile.xml deleted file mode 100644 index 7293cea9a9b83..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Metadata/TemplateMetaFile.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> - <operation name="" dataType="" type="" auth="adminOauth" url="" method=""> - <contentType>application/json</contentType> - <param key=""></param> - <object dataType="" key=""> - <field key=""></field> - <array key=""> - <value></value> - </array> - </object> - <field key=""></field> - </operation> -</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Page/TemplatePageFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Page/TemplatePageFile.xml deleted file mode 100644 index 27559a48bef06..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Page/TemplatePageFile.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> - <page name="" url="" area="" module=""> - <section name=""/> - </page> -</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/README.md b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/README.md deleted file mode 100644 index 986c2af6164e9..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Magento 2 Functional Tests - -The Functional Tests Module for **Magento_SampleTemplates** Module. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Section/TemplateSectionFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Section/TemplateSectionFile.xml deleted file mode 100644 index 4c1cd7300cf2f..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Section/TemplateSectionFile.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name=""> - <element name="" type="" selector=""/> - </section> -</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Test/TemplateTestFile.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Test/TemplateTestFile.xml deleted file mode 100644 index d9a98d4baa6cb..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTemplates/Test/TemplateTestFile.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="TemplateTestFile"> - <annotations> - <features value=""/> - <stories value=""/> - </annotations> - <before> - - </before> - <after> - - </after> - <!-- ADD TEST STEPS HERE --> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/ActionGroup/SampleActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/ActionGroup/SampleActionGroup.xml deleted file mode 100644 index 45ec5f3adf218..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/ActionGroup/SampleActionGroup.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="SampleActionGroup"> - <arguments> - <argument name="person" defaultValue="SamplePerson"/> - </arguments> - <fillField selector="#foo" userInput="{{person.foo}}" stepKey="fillField1"/> - <fillField selector="#bar" userInput="{{person.bar}}" stepKey="fillField2"/> - </actionGroup> - <actionGroup name="ValidateSlideOutPanelField"> - <arguments> - <argument name="property" defaultValue=""/> - </arguments> - <see userInput="{{property.name}}" selector="{{ColumnSection.panelFieldLabel(property.section, property.fieldName, property.section, property.name)}}" stepKey="seePropertyLabel"/> - </actionGroup> -</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Data/SampleData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Data/SampleData.xml deleted file mode 100644 index 361f06a6ff333..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Data/SampleData.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="SamplePerson" type="samplePerson"> - <data key="foo">foo</data> - <data key="bar">bar</data> - <data key="lastName">Doe</data> - <data key="email" unique="prefix">.email@gmail.com</data> - </entity> - <entity name="OverrideDefaultPerson" type="samplePerson"> - <data key="foo">fizz</data> - <data key="bar">buzz</data> - </entity> - <entity name="AppearanceMinHeightProperty" type="min_height_property"> - <data key="name">Minimum Height</data> - <data key="section">appearance</data> - <data key="fieldName">min_height</data> - </entity> - <entity name="AssertThis" type="samplePerson"> - <data key="firstname">Well</data> - <data key="lastname">Done</data> - <data key="email" unique="prefix">.email@gmail.com</data> - </entity> -</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE.txt deleted file mode 100644 index 49525fd99da9c..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Open Software License ("OSL") v. 3.0 - -This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Open Software License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE_AFL.txt b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE_AFL.txt deleted file mode 100644 index f39d641b18a19..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/LICENSE_AFL.txt +++ /dev/null @@ -1,48 +0,0 @@ - -Academic Free License ("AFL") v. 3.0 - -This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Academic Free License version 3.0 - - 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: - - 1. to reproduce the Original Work in copies, either alone or as part of a collective work; - - 2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; - - 3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; - - 4. to perform the Original Work publicly; and - - 5. to display the Original Work publicly. - - 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - - 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - - 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - - 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - - 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - - 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - - 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - - 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - - 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - - 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - - 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - - 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - - 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - - 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Page/SamplePage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Page/SamplePage.xml deleted file mode 100644 index 6fd2a54c6014e..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Page/SamplePage.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> - <page name="SamplePage" url="/{{var1}}/{{var2}}.html" area="storefront" module="SampleTests" parameterized="true"> - <section name="SampleSection"/> - </page> -</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/README.md b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/README.md deleted file mode 100644 index f3340b205f1a3..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Magento 2 Functional Tests - -The Functional Tests Module for **Magento_SampleTests** Module. diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Section/SampleSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Section/SampleSection.xml deleted file mode 100644 index 6aa54d2fb9b83..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Section/SampleSection.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="SampleSection"> - <element name="oneParamElement" type="button" selector="#element .{{var1}}" parameterized="true"/> - <element name="twoParamElement" type="button" selector="#{{var1}} .{{var2}}" parameterized="true"/> - <element name="threeParamElement" type="button" selector="#{{var1}}-{{var2}} .{{var3}}" parameterized="true"/> - <element name="timeoutElement" type="button" selector="#foo" timeout="30"/> - </section> - <section name="ColumnSection"> - <element name="panelFieldLabel" type="text" selector='//div[@data-index="{{arg1}}"]/descendant::div[@data-index="{{arg2}}"]/label | //div[@data-index="{{arg3}}"]/descendant::*[@class="admin__field-label"]/span[text()="{{arg4}}"]' parameterized="true" /> - </section> -</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml deleted file mode 100644 index 4fead0e51497e..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdvancedSampleTest"> - <annotations> - <features value="SampleTests"/> - <title value=""/> - <description value=""/> - <severity value="CRITICAL"/> - <testCaseId value="#"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <before> - <createData entity="SamplePerson" stepKey="beforeData"/> - </before> - <after> - - </after> - - <!-- Create an entity that depends on another entity --> - <createData entity="_defaultCategory" stepKey="createCategory"/> - <createData entity="_defaultProduct" stepKey="createProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - - <!-- Parameterized url --> - <amOnPage url="{{SamplePage.url('foo', SamplePerson.bar)}}" stepKey="amOnPage"/> - - <!-- Parameterized selector --> - <grabTextFrom selector="{{SampleSection.twoParamElement(SamplePerson.foo, 'bar')}}" stepKey="grabTextFrom"/> - - <!-- Element with a timeout --> - <click selector="{{SampleSection.timeoutElement}}" stepKey="click"/> - - <!-- ActionGroup --> - <actionGroup ref="SampleActionGroup" stepKey="actionGroup"> - <argument name="person" value="OverrideDefaultPerson"/> - </actionGroup> - - <actionGroup ref="ValidateSlideOutPanelField" stepKey="seeAppearanceMinHeightProperty"> - <argument name="property" value="AppearanceMinHeightProperty"/> - </actionGroup> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml deleted file mode 100644 index 200c52cab797d..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<!-- Test XML Example --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AssertsTest"> - <annotations> - <features value="SampleTests"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - - <createData entity="Simple_US_Customer" stepKey="createData2"/> - <amOnUrl url="https://www.yahoo.com" stepKey="amOnPage"/> - <waitForElementVisible stepKey="wait1" selector="#uh-logo" time="10"/> - <grabTextFrom selector="#uh-logo" stepKey="grabTextFrom1"/> - - <!-- asserts without variable replacement --> - <assertArrayHasKey stepKey="assertArrayHasKey" message="pass"> - <expectedResult type="string">apple</expectedResult> - <actualResult type="const">['orange' => 2, 'apple' => 1]</actualResult> - </assertArrayHasKey> - <assertEquals stepKey="assertEquals1" message="pass"> - <expectedResult type="variable">grabTextFrom1</expectedResult> - <actualResult type="string">Copyright © 2013-2017 Magento, Inc. All rights reserved.</actualResult> - </assertEquals> - <assertFalse stepKey="assertFalse1" message="pass"> - <actualResult type="bool">0</actualResult> - </assertFalse> - <assertGreaterOrEquals stepKey="assertGreaterOrEquals" message="pass"> - <expectedResult type="int">2</expectedResult> - <actualResult type="int">5</actualResult> - </assertGreaterOrEquals> - <assertElementContainsAttribute stepKey="assertElementContainsAttribute1" selector="#username" attribute="class"> - <expectedResult type="string">admin__control-text</expectedResult> - </assertElementContainsAttribute> - - <!-- string type that use created data --> - <assertStringStartsWith stepKey="assert1" message="fail"> - <expectedResult type="string">D</expectedResult> - <actualResult type="string">$$createData1.lastname$$, $$createData1.firstname$$</actualResult> - </assertStringStartsWith> - <assertStringStartsNotWith stepKey="assert2" message="pass"> - <expectedResult type="string">W</expectedResult> - <actualResult type="string">$createData2.firstname$, $createData2.lastname$</actualResult> - </assertStringStartsNotWith> - <assertEquals stepKey="assert5" message="pass"> - <expectedResult type="string">$$createData1.lastname$$</expectedResult> - <actualResult type="string">$$createData1.lastname$$</actualResult> - </assertEquals> - <assertElementContainsAttribute stepKey="assertElementContainsAttribute7" selector="#username" attribute="value"> - <expectedResult type="const">$createData2.firstname$</expectedResult> - </assertElementContainsAttribute> - - <!-- array type that use created data --> - <assertArraySubset stepKey="assert9" message="pass"> - <expectedResult type="array">[$$createData1.lastname$$, $$createData1.firstname$$]</expectedResult> - <actualResult type="array">[$$createData1.lastname$$, $$createData1.firstname$$, 1]</actualResult> - </assertArraySubset> - <assertArraySubset stepKey="assert10" message="pass"> - <expectedResult type="array">[$createData2.firstname$, $createData2.lastname$]</expectedResult> - <actualResult type="array">[$createData2.firstname$, $createData2.lastname$, 1]</actualResult> - </assertArraySubset> - <assertArrayHasKey stepKey="assert3" message="pass"> - <expectedResult type="string">lastname</expectedResult> - <actualResult type="array">['lastname' => $$createData1.lastname$$, 'firstname' => $$createData1.firstname$$]</actualResult> - </assertArrayHasKey> - <assertArrayHasKey stepKey="assert4" message="pass"> - <expectedResult type="string">lastname</expectedResult> - <actualResult type="array">['lastname' => $createData2.lastname$, 'firstname' => $createData2.firstname$]</actualResult> - </assertArrayHasKey> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml deleted file mode 100644 index d759d1ab27498..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="CreateConfigurableProductByApiTest"> - <annotations> - <features value="SampleTests"/> - <stories value="Create a Configurable Product By API"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <before> - <createData stepKey="categoryHandle" entity="SimpleSubCategory" /> - <createData stepKey="baseConfigProductHandle" entity="BaseConfigurableProduct" > - <requiredEntity createDataKey="categoryHandle"/> - </createData> - <createData stepKey="productAttributeHandle" entity="productDropDownAttribute"/> - - <createData stepKey="productAttributeOption1Handle" entity="productAttributeOption1"> - <requiredEntity createDataKey="productAttributeHandle"/> - </createData> - <createData stepKey="productAttributeOption2Handle" entity="productAttributeOption2"> - <requiredEntity createDataKey="productAttributeHandle"/> - </createData> - - <createData stepKey="addToAttributeSetHandle" entity="AddToDefaultSet"> - <requiredEntity createDataKey="productAttributeHandle"/> - </createData> - - <getData stepKey="getAttributeOption1Handle" entity="ProductAttributeOptionGetter" index="1"> - <requiredEntity createDataKey="productAttributeHandle"/> - </getData> - <getData stepKey="getAttributeOption2Handle" entity="ProductAttributeOptionGetter" index="2"> - <requiredEntity createDataKey="productAttributeHandle"/> - </getData> - - <createData stepKey="childProductHandle1" entity="SimpleOne"> - <requiredEntity createDataKey="productAttributeHandle"/> - <requiredEntity createDataKey="getAttributeOption1Handle"/> - </createData> - <createData stepKey="childProductHandle2" entity="SimpleOne"> - <requiredEntity createDataKey="productAttributeHandle"/> - <requiredEntity createDataKey="getAttributeOption2Handle"/> - </createData> - - <createData stepKey="configProductOptionHandle" entity="ConfigurableProductTwoOptions"> - <requiredEntity createDataKey="baseConfigProductHandle"/> - <requiredEntity createDataKey="productAttributeHandle"/> - <requiredEntity createDataKey="getAttributeOption1Handle"/> - <requiredEntity createDataKey="getAttributeOption2Handle"/> - </createData> - - <createData stepKey="configProductHandle1" entity="ConfigurableProductAddChild"> - <requiredEntity createDataKey="childProductHandle1"/> - <requiredEntity createDataKey="baseConfigProductHandle"/> - </createData> - <createData stepKey="configProductHandle2" entity="ConfigurableProductAddChild"> - <requiredEntity createDataKey="childProductHandle2"/> - <requiredEntity createDataKey="baseConfigProductHandle"/> - </createData> - </before> - <after> - <deleteData stepKey="d2" createDataKey="childProductHandle1"/> - <deleteData stepKey="d3" createDataKey="childProductHandle2"/> - <deleteData stepKey="d7" createDataKey="baseConfigProductHandle"/> - <deleteData stepKey="d8" createDataKey="categoryHandle"/> - <deleteData stepKey="d6" createDataKey="productAttributeHandle"/> - </after> - </test> -</tests> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml deleted file mode 100644 index 8cd83fd62067f..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="CreateSalesRuleByApiTest"> - <annotations> - <features value="SampleTests"/> - <stories value="Create a Sales Rule By API"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <before> - <createData stepKey="saleRule" entity="SimpleSalesRule" /> - </before> - <!--see stepKey="test" userInput="$$saleRule.store_labels[0][store_id]$$" selector="test"/--> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml deleted file mode 100644 index f8702eeaf5e0c..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<!-- Test XML Example --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="MinimumTest"> - <annotations> - <features value="SampleTests"/> - <title value="Minimum Test"/> - <description value="Minimum Test"/> - <group value="example"/> - </annotations> - <after> - <seeInCurrentUrl url="/admin/admin/" stepKey="seeInCurrentUrl"/> - </after> - <amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdmin"/> - <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{_ENV.MAGENTO_ADMIN_USERNAME}}" stepKey="fillUsername"/> - <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="fillPassword"/> - <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml deleted file mode 100644 index 6a196c2c32c02..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="PersistMultipleEntitiesTest"> - <annotations> - <features value="SampleTests"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <before> - <createData entity="simplesubcategory" stepKey="simplecategory"/> - <createData entity="simpleproduct" stepKey="simpleproduct1"> - <requiredEntity createDataKey="simplecategory"/> - </createData> - <createData entity="simpleproduct" stepKey="simpleproduct2"> - <requiredEntity createDataKey="categoryLink"/> - </createData> - </before> - <after> - <deleteData createDataKey="simpleproduct1" stepKey="deleteProduct1"/> - <deleteData createDataKey="simpleproduct2" stepKey="deleteProduct2"/> - <deleteData createDataKey="simplecategory" stepKey="deleteCategory"/> - </after> - <amOnPage stepKey="s11" url="/$$simplecategory.name$$.html" /> - <waitForPageLoad stepKey="s33"/> - <see stepKey="s35" selector="{{StorefrontCategoryMainSection.productCount}}" userInput="2"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml deleted file mode 100644 index c107debc1aa62..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml +++ /dev/null @@ -1,298 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<!-- Test XML Example --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="PreAndPostHooksTest"> - <before> - <amOnUrl url="http://127.0.0.1:32772/admin/" stepKey="amOnPage"/> - <createData entity="CustomerEntity1" stepKey="createData1"/> - <createData entity="AssertThis" stepKey="createData2"/> - </before> - <after> - <amOnUrl url="http://127.0.0.1:32772/admin/admin/auth/logout" stepKey="amOnPage"/> - <deleteData createDataKey="createData1" stepKey="deleteData1"/> - <deleteData createDataKey="createData2" stepKey="deleteData2"/> - </after> - </test> - <test name="AllCodeceptionMethodsTest"> - <annotations> - <features value="SampleTests"/> - <title value="Create all Codeception methods"/> - <description value="Exercises the Generator to make sure it creates every Codeception method correctly."/> - <severity value="CRITICAL"/> - <testCaseId value="#"/> - </annotations> - <acceptPopup stepKey="acceptPopup"/> - <amOnPage url="/admin" stepKey="amOnPage"/> - <amOnSubdomain url="admin" stepKey="amOnSubdomain"/> - <amOnUrl url="http://www.google.com/" stepKey="amOnUrl"/> - <appendField userInput="More Words" selector=".stuff" stepKey="appendField"/> - <attachFile userInput="filename.php" selector="#stuff" stepKey="attachFile"/> - <cancelPopup stepKey="cancelPopup"/> - <checkOption selector="#checkbox" stepKey="checkOption"/> - <clearField selector="#field" stepKey="clearField"/> - <click selector="#button" userInput="Context" stepKey="click1"/> - <click selectorArray="['link' => 'Login']" stepKey="click2"/> - <click selectorArray="['link' => 'Login']" userInput="stuff" stepKey="click3"/> - <clickWithLeftButton selector="#clickHere" stepKey="clickWithLeftButton1" x="23" y="324"/> - <clickWithLeftButton selectorArray="['css' => '.checkout']" stepKey="clickWithLeftButton2" x="23" y="324"/> - <clickWithLeftButton stepKey="clickWithLeftButton3" x="23" y="324"/> - <clickWithRightButton selector="#clickHere" stepKey="clickWithRightButton1" x="23" y="324"/> - <clickWithRightButton selectorArray="['css' => '.checkout']" stepKey="clickWithRightButton2" x="23" y="324"/> - <clickWithRightButton stepKey="clickWithRightButton3" x="23" y="324"/> - <closeTab stepKey="closeTab"/> - <comment userInput="This is a Comment." stepKey="comment"/> - <createData entity="CustomerEntity1" stepKey="createData1"/> - <deleteData createDataKey="createData1" stepKey="deleteData1"/> - <dontSee userInput="Text" stepKey="dontSee1"/> - <dontSee userInput="Text" selector=".title" stepKey="dontSee2"/> - <dontSee userInput="Text" selectorArray="['css' => 'body h1']" stepKey="dontSee3"/> - <dontSeeCheckboxIsChecked selector="#checkbox" stepKey="dontSeeCheckboxIsChecked"/> - <dontSeeCookie userInput="cookieName" stepKey="dontSeeCookie1"/> - <dontSeeCookie userInput="cookieName" parameterArray="['domainName' => 'stuff']" stepKey="dontSeeCookie2"/> - <dontSeeCurrentUrlEquals url="/stuff" stepKey="dontSeeCurrentUrlEquals"/> - <dontSeeCurrentUrlMatches regex="~$/users/(\d+)~" stepKey="dontSeeCurrentUrlMatches"/> - <dontSeeElement selector=".error" stepKey="dontSeeElement1"/> - <dontSeeElement selector="input" parameterArray="['name' => 'login']" stepKey="dontSeeElement2"/> - <dontSeeElementInDOM selector="#stuff" stepKey="dontSeeElementInDOM1"/> - <dontSeeElementInDOM selector="#stuff" parameterArray="['name' => 'login']" stepKey="dontSeeElementInDOM2"/> - <dontSeeInCurrentUrl url="/users/" stepKey="dontSeeInCurrentUrl"/> - <dontSeeInField selector=".field" userInput="stuff" stepKey="dontSeeInField1"/> - <dontSeeInField selectorArray="['name' => 'search']" userInput="Comment Here" stepKey="dontSeeInField2"/> - <dontSeeInFormFields selector="form[name=myform]" parameterArray="['input1' => 'non-existent value', 'input2' => 'other non-existent value']" stepKey="dontSeeInFormFields"/> - <dontSeeInPageSource userInput="Stuff in Page Source" stepKey="dontSeeInPageSource"/> - <!--<dontSeeInSource html="<h1></h1>" stepKey="dontSeeInSource"/>--> - <dontSeeInTitle userInput="Title" stepKey="dontSeeInTitle"/> - <dontSeeLink userInput="Logout" stepKey="dontSeeLink1"/> - <dontSeeLink userInput="Checkout" url="/store/cart.php" stepKey="dontSeeLink2"/> - <dontSeeOptionIsSelected selector="#form .stuff" userInput="Option Name" stepKey="dontSeeOptionIsSelected"/> - <doubleClick selector="#click .here" stepKey="doubleClick"/> - <dragAndDrop selector1="#number1" selector2="#number2" stepKey="dragAndDrop"/> - <executeInSelenium function="function(\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {$webdriver->get('http://google.com');}" stepKey="executeInSelenium"/> - <executeJS function="return $('#myField').val()" stepKey="executeJS"/> - <fillField selector="#field" userInput="stuff" stepKey="fillField1"/> - <fillField selectorArray="['name' => 'email']" userInput="stuff" stepKey="fillField2"/> - <grabAttributeFrom selector="#target" userInput="title" stepKey="grabAttributeFrom"/> - <grabCookie userInput="cookie" parameterArray="['domain' => 'www.google.com']" stepKey="grabCookie"/> - <grabFromCurrentUrl regex="~$/user/(\d+)/~" stepKey="grabFromCurrentUrl"/> - <grabMultiple selector="a" userInput="href" stepKey="grabMultiple"/> - <grabPageSource stepKey="grabPageSource1"/> - <grabTextFrom selector="h1" stepKey="grabTextFrom1"/> - <grabValueFrom selector=".form" stepKey="grabValueFrom1"/> - <grabValueFrom selectorArray="['name' => 'username']" stepKey="grabValueFrom2"/> - <loadSessionSnapshot userInput="stuff" stepKey="loadSessionSnapshot1"/> - <loadSessionSnapshot userInput="stuff" stepKey="loadSessionSnapshot2"/> - <makeScreenshot userInput="ScreenshotName" stepKey="makeScreenshot"/> - <maximizeWindow stepKey="maximizeWindow"/> - <moveBack stepKey="moveBack"/> - <moveForward stepKey="moveForward"/> - <moveMouseOver selector="#stuff" stepKey="moveMouseOver1"/> - <moveMouseOver selectorArray="['css' => '.checkout']" stepKey="moveMouseOver2"/> - <moveMouseOver x="5" y="5" stepKey="moveMouseOver3"/> - <moveMouseOver selector="#stuff" x="5" y="5" stepKey="moveMouseOver4"/> - <moveMouseOver selectorArray="['css' => '.checkout']" x="5" y="5" stepKey="moveMouseOver5"/> - <openNewTab stepKey="openNewTab"/> - <pauseExecution stepKey="pauseExecution"/> - <performOn selector=".rememberMe" function="function (WebDriver $I) { $I->see('Remember me next time'); $I->seeElement('#LoginForm_rememberMe'); $I->dontSee('Login'); }" stepKey="performOn1"/> - <performOn selector=".rememberMe" function="ActionSequence::build()->see('Warning')->see('Are you sure you want to delete this?')->click('Yes')" stepKey="performOn2"/> - <pressKey selector="#page" userInput="a" stepKey="pressKey1"/> - <pressKey selector="#page" parameterArray="[['ctrl','a'],'new']" stepKey="pressKey2"/> - <pressKey selector="#page" parameterArray="[['shift','111'],'1','x']" stepKey="pressKey3"/> - <pressKey selector="#page" parameterArray="[['ctrl', 'a'], \Facebook\WebDriver\WebDriverKeys::DELETE]" stepKey="pressKey4"/> - <!--pressKey selector="descendant-or-self::*[@id='page']" userInput="u" stepKey="pressKey5"/--> - <reloadPage stepKey="reloadPage"/> - <resetCookie userInput="cookie" stepKey="resetCookie1"/> - <resetCookie userInput="cookie" parameterArray="['domainName' => 'www.google.com']" stepKey="resetCookie2"/> - <resizeWindow width="800" height="600" stepKey="resizeWindow"/> - <saveSessionSnapshot userInput="stuff" stepKey="saveSessionSnapshot"/> - <scrollTo selector="#place" x="20" y="50" stepKey="scrollTo1"/> - <scrollTo selectorArray="['css' => '.checkout']" x="20" y="50" stepKey="scrollTo2"/> - <see userInput="Stuff" stepKey="see1"/> - <see userInput="More Stuff" selector=".stuff" stepKey="see2"/> - <see userInput="More More Stuff" selectorArray="['css' => 'body h1']" stepKey="see3"/> - <seeCheckboxIsChecked selector="#checkbox" stepKey="seeCheckboxIsChecked"/> - <seeCookie userInput="PHPSESSID" stepKey="seeCookie1"/> - <seeCookie userInput="PHPSESSID" parameterArray="['domainName' => 'www.google.com']" stepKey="seeCookie2"/> - <seeCurrentUrlEquals url="/" stepKey="seeCurrentUrlEquals"/> - <seeCurrentUrlMatches regex="~$/users/(\d+)~" stepKey="seeCurrentUrlMatches"/> - <seeElement selector=".error" stepKey="seeElement1"/> - <seeElement selectorArray="['css' => 'form input']" stepKey="seeElement2"/> - <seeElement selector=".error" parameterArray="['name' => 'login']" stepKey="seeElement3"/> - <seeElement selectorArray="['css' => 'form input']" parameterArray="['name' => 'login']" stepKey="seeElement4"/> - <seeElementInDOM selector="//form/input[type=hidden]" stepKey="seeElementInDOM1"/> - <seeElementInDOM selector="//form/input[type=hidden]" parameterArray="['name' => 'form']" stepKey="seeElementInDOM2"/> - <seeInCurrentUrl url="home" stepKey="seeInCurrentUrl1"/> - <seeInCurrentUrl url="/home/" stepKey="seeInCurrentUrl2"/> - <seeInField userInput="Stuff" selector="#field" stepKey="seeInField1"/> - <seeInField userInput="Stuff" selectorArray="['name' => 'search']" stepKey="seeInField2"/> - <seeInFormFields selector="form[name=myform]" parameterArray="['input1' => 'value','input2' => 'other value']" stepKey="seeInFormFields1"/> - <seeInFormFields selector=".form-class" parameterArray="[['multiselect' => ['value1','value2'],'checkbox[]]' => ['a checked value','another checked value',]]" stepKey="seeInFormFields2"/> - <!--<seeInPageSource html="<h1></h1>" stepKey="seeInPageSource"/>--> - <seeInPopup userInput="Yes in Popup" stepKey="seeInPopup"/> - <!--<seeInSource html="<h1></h1>" stepKey="seeInSource"/>--> - <seeInTitle userInput="In Title" stepKey="seeInTitle"/> - <seeLink userInput="Logout" stepKey="seeLink1"/> - <seeLink userInput="Logout" url="/logout" stepKey="seeLink2"/> - <seeNumberOfElements selector="tr" userInput="10" stepKey="seeNumberOfElements1"/> - <seeNumberOfElements selector="tr" userInput="[0, 10]" stepKey="seeNumberOfElements2"/> - <seeOptionIsSelected selector=".option" userInput="Visa" stepKey="seeOptionIsSelected"/> - <selectOption selector=".dropDown" userInput="Option Name" stepKey="selectOption1"/> - <selectOption selector="//form/select[@name=account]" parameterArray="['Windows','Linux']" stepKey="selectOption2"/> - <selectOption selector="Which OS do you use?" parameterArray="['text' => 'Windows']" stepKey="selectOption3"/> - <setCookie userInput="PHPSESSID" value="stuff" stepKey="setCookie1"/> - <setCookie userInput="PHPSESSID" value="stuff" parameterArray="['domainName' => 'www.google.com']" stepKey="setCookie2"/> - <submitForm selector="#my-form" parameterArray="['field' => ['value','another value',]]" button="#submit" stepKey="submitForm2"/> - <switchToIFrame stepKey="switchToIFrame1"/> - <switchToIFrame userInput="another_frame" stepKey="switchToIFrame2"/> - <switchToNextTab stepKey="switchToNextTab1"/> - <switchToNextTab userInput="2" stepKey="switchToNextTab2"/> - <switchToPreviousTab stepKey="switchToPreviewTab1"/> - <switchToPreviousTab userInput="1" stepKey="switchToPreviewTab2"/> - <switchToWindow stepKey="switchToWindow1"/> - <switchToWindow userInput="another_window" stepKey="switchToWindow2"/> - <typeInPopup userInput="Stuff for popup" stepKey="typeInPopup"/> - <uncheckOption selector="#option" stepKey="uncheckOption"/> - <unselectOption selector="#dropDown" userInput="Option" stepKey="unselectOption"/> - <wait time="15" stepKey="wait"/> - <waitForElement selector="#button" time="10" stepKey="waitForElement"/> - <waitForElementChange selector="#menu" function="function(\WebDriverElement $el) {return $el->isDisplayed();}" time="100" stepKey="waitForElementChange"/> - <waitForElementNotVisible selector="#a_thing .className" time="30" stepKey="waitForElementNotVisible"/> - <waitForElementVisible selector="#a_thing .className" time="15" stepKey="waitForElementVisible"/> - <waitForJS function="return $.active == 0;" time="30" stepKey="waitForJS"/> - <waitForText userInput="foo" time="30" stepKey="waitForText1"/> - <waitForText userInput="foo" selector=".title" time="30" stepKey="waitForText2"/> - </test> - <test name="AllCustomMethodsTest"> - <annotations> - <title value="Create all Custom methods"/> - <description value="Exercises the Generator to make sure it creates every Custom method correctly."/> - <severity value="CRITICAL"/> - <testCaseId value="#"/> - </annotations> - <assertElementContainsAttribute selector="#username" attribute="class" expectedValue="admin__control-text" stepKey="assertElementContainsAttribute1"/> - <assertElementContainsAttribute selector="#username" attribute="type" expectedValue="text" stepKey="assertElementContainsAttribute2"/> - <assertElementContainsAttribute selector="#username" attribute="name" expectedValue="login[username]" stepKey="assertElementContainsAttribute3"/> - <assertElementContainsAttribute selector="#username" attribute="autofocus" expectedValue="" stepKey="assertElementContainsAttribute4"/> - <assertElementContainsAttribute selector="#username" attribute="data-validate" expectedValue="{required:true}" stepKey="assertElementContainsAttribute5"/> - <assertElementContainsAttribute selector="#username" attribute="placeholder" expectedValue="user name" stepKey="assertElementContainsAttribute6"/> - <assertElementContainsAttribute selector="#username" attribute="autocomplete" expectedValue="off" stepKey="assertElementContainsAttribute7"/> - <assertElementContainsAttribute selector=".admin__menu-overlay" attribute="style" expectedValue="display: none;" stepKey="assertElementContainsAttribute8"/> - <assertElementContainsAttribute selector=".admin__menu-overlay" attribute="border" expectedValue="0" stepKey="assertElementContainsAttribute9"/> - <closeAdminNotification stepKey="closeAdminNotification1"/> - <searchAndMultiSelectOption selector="#stuff" parameterArray="['Item 1', 'Item 2']" stepKey="searchAndMultiSelect1"/> - <searchAndMultiSelectOption selector="#stuff" parameterArray="['Item 1', 'Item 2']" requiredAction="true" stepKey="searchAndMultiSelect2"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - <waitForPageLoad time="15" stepKey="waitForPageLoad2"/> - <waitForAjaxLoad stepKey="waitForAjax1"/> - <waitForAjaxLoad time="15" stepKey="waitForAjax2"/> - <dontSeeJsError stepKey="dontSeeJsError"/> - <formatMoney userInput="$300,000" stepKey="formatMoney1"/> - <formatMoney userInput="$300,000" locale="en_US.UTF-8" stepKey="formatMoney2"/> - <mSetLocale userInput="300" locale="en_US.UTF-8" stepKey="mSetLocale1"/> - <mResetLocale stepKey="mResetLocale1"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear1"/> - <scrollToTopOfPage stepKey="scrollToTopOfPage"/> - <parseFloat userInput="300,000.2325" stepKey="parseFloat1"/> - <magentoCLI stepKey="enableMaintenance1" command="maintenance:enable"/> - </test> - <test name="AllVariableMethodsTest"> - <annotations> - <features value="SampleTests"/> - <title value="Create all Methods that support Variables."/> - <description value="Exercises the Generator to make sure it creates every Method that supports a Variable."/> - <severity value="CRITICAL"/> - <testCaseId value="#"/> - </annotations> - <grabFromCurrentUrl stepKey="grabFromCurrentUrl1"/> - <amOnPage url="{$randomStuff}" stepKey="amOnPage1"/> - <amOnSubdomain url="{$randomStuff}" stepKey="amOnSubdomain1"/> - <amOnUrl url="{$randomStuff}" stepKey="amOnUrl1"/> - <appendField userInput="{$randomStuff}" selector="#randomField" stepKey="appendField1"/> - <attachFile userInput="{$randomStuff}" selector="#filePathField" stepKey="attachFile1"/> - <click userInput="{$randomStuff}" stepKey="click1"/> - <dontSee userInput="{$randomStuff}" stepKey="dontSee1"/> - <dontSeeCookie userInput="{$randomStuff}" stepKey="dontSeeCookie1"/> - <dontSeeCurrentUrlEquals url="{$randomStuff}" stepKey="dontSeeCurrentUrlEquals1"/> - <dontSeeCurrentUrlMatches regex="{$randomStuff}" stepKey="dontSeeCurrentUrlMatches1"/> - <dontSeeInCurrentUrl url="{$randomStuff}" stepKey="dontSeeInCurrentUrl1"/> - <dontSeeInField selector="#stuff" userInput="{$randomStuff}" stepKey="dontSeeInField1"/> - <dontSeeInPageSource userInput="{$randomStuff}" stepKey="dontSeeInPageSource1"/> - <dontSeeInTitle userInput="{$randomStuff}" stepKey="dontSeeInTitle1"/> - <dontSeeLink userInput="{$randomStuff}" stepKey="dontSeeLink1"/> - <dontSeeOptionIsSelected selector="#dropdown" userInput="{$randomStuff}" stepKey="dontSeeOptionIsSelected1"/> - <fillField userInput="{$randomStuff}" selector="#field" stepKey="fillField1"/> - <grabAttributeFrom selector="#stuff" userInput="{$randomStuff}" stepKey="grabAttributeFrom1"/> - <grabCookie userInput="{$randomStuff}" stepKey="grabValueFrom1"/> - <grabFromCurrentUrl regex="{$randomStuff}" stepKey="grabFromCurrentUrl"/> - <grabMultiple selector="a" userInput="{$randomStuff}" stepKey="grabMultiple1"/> - <loadSessionSnapshot userInput="{$randomStuff}" stepKey="loadSessionSnapshot"/> - <pressKey selector="a" userInput="{$randomStuff}" stepKey="pressKey1"/> - <saveSessionSnapshot userInput="{$randomStuff}" stepKey="saveSessionSnapshot1"/> - <see userInput="{$randomStuff}" stepKey="see1"/> - <seeCookie userInput="{$randomStuff}" stepKey="seeCookie1"/> - <seeCurrentUrlEquals url="{$randomStuff}" stepKey="seeCurrentUrlEquals1"/> - <seeCurrentUrlMatches regex="{$randomStuff}" stepKey="seeCurrentUrlMatches1"/> - <seeInCurrentUrl url="{$randomStuff}" stepKey="seeInCurrentUrl1"/> - <seeInField selector="a" userInput="{$randomStuff}" stepKey="seeInField1"/> - <seeInPopup userInput="{$randomStuff}" stepKey="seeInPopup"/> - <seeInTitle userInput="{$randomStuff}" stepKey="seeInTitle1"/> - <seeLink userInput="{$randomStuff}" stepKey="seeLink1"/> - <seeNumberOfElements selector="#stuff" userInput="{$randomStuff}" stepKey="seeNumberOfElements1"/> - <seeOptionIsSelected selector="#stuff" userInput="{$randomStuff}" stepKey="seeOptionIsSelected1"/> - <selectOption selector="#stuff" userInput="{$randomStuff}" stepKey="selectOption1"/> - <switchToIFrame userInput="{$randomStuff}" stepKey="switchToIFrame1"/> - <switchToNextTab userInput="{$randomStuff}" stepKey="switchToNextTab2"/> - <switchToPreviousTab userInput="{$randomStuff}" stepKey="switchToPreviousTab1"/> - <switchToNextTab userInput="{$randomStuff}" stepKey="switchToNextTab3"/> - <switchToWindow userInput="{$randomStuff}" stepKey="switchToWindow1"/> - <typeInPopup userInput="{$randomStuff}" stepKey="typeInPopup"/> - <unselectOption selector="#option" userInput="{$randomStuff}" stepKey="unselectOption1"/> - <waitForText userInput="{$randomStuff}" time="5" stepKey="waitForText1"/> - </test> - <test name="AllReplacementTest"> - <annotations> - <features value="SampleTests"/> - <title value="Exercise reference replacement."/> - <description value="Exercises {{foo}}, $foo$, and $$foo$$ replacement."/> - <severity value="CRITICAL"/> - <testCaseId value="#"/> - </annotations> - - <createData entity="CustomerEntity1" stepKey="testScopeData"/> - <createData entity="AssertThis" stepKey="testScopeData2"/> - - <!-- parameterized url that uses literal params --> - <amOnPage url="{{SamplePage.url('success','success2')}}" stepKey="a0"/> - - <!-- url referencing data that was created in this <test> --> - <amOnPage url="$testScopeData.firstname$.html" stepKey="a1"/> - - <!-- url referencing data that was created in a <before> --> - <amOnPage url="$$createData1.firstname$$.html" stepKey="a2"/> - - <!-- parameterized url that uses created data params --> - <amOnPage url="{{SamplePage.url($testScopeData.firstname$,$testScopeData.lastname$)}}" stepKey="a3"/> - <amOnPage url="{{SamplePage.url($$createData1.firstname$$,$$createData1.lastname$$)}}" stepKey="a4"/> - - <!-- parameterized selector that uses literal params --> - <click selector="{{SampleSection.oneParamElement('success')}}" stepKey="c1"/> - <click selector="{{SampleSection.twoParamElement('success','success2')}}" stepKey="c2"/> - - <!-- parameterized selector with literal, static data, and created data --> - <click selector="{{SampleSection.threeParamElement('John', SamplePerson.lastname, $testScopeData.lastname$)}}" stepKey="c3"/> - - <!-- selector that uses created data --> - <click selector="#$testScopeData.firstname$ .$testScopeData.lastname$" stepKey="c4"/> - <click selector="#$$createData1.firstname$$ .$$createData1.lastname$$" stepKey="c5"/> - - <!-- userInput that uses created data --> - <fillField selector="#sample" userInput="Hello $testScopeData.firstname$ $testScopeData.lastname$" stepKey="f1"/> - <fillField selector="#sample" userInput="Hello $$createData1.firstname$$ $$createData1.lastname$$" stepKey="f2"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml deleted file mode 100644 index f908c5cb4572e..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="SetPaypalConfigurationTest"> - <annotations> - <features value="SampleTests"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <createData entity="SamplePaypalConfig" stepKey="createSamplePaypalConfig"/> - <createData entity="DefaultPayPalConfig" stepKey="restoreDefaultPaypalConfig"/> - </test> - <test name="SetBraintreeConfigurationTest"> - <annotations> - <features value="SampleTests"/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <createData entity="SampleBraintreeConfig" stepKey="createSampleBraintreeConfig"/> - <createData entity="DefaultBraintreeConfig" stepKey="restoreDefaultBraintreeConfig"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml deleted file mode 100644 index b18c24050d3a6..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="UpdateSimpleProductByApiTest"> - <annotations> - <features value="SampleTests"/> - <stories value="Update simple product by api test."/> - <skip> - <issueId value="SAMPLE"/> - </skip> - </annotations> - <before> - <createData stepKey="categoryHandle" entity="SimpleSubCategory"/> - <createData stepKey="productHandle" entity="SimpleProduct" > - <requiredEntity createDataKey="categoryHandle"/> - </createData> - <updateData stepKey="updateProduct" entity="NewSimpleProduct" createDataKey="productHandle"/> - </before> - <after> - <deleteData stepKey="delete" createDataKey="updateProduct"/> - </after> - </test> -</tests> \ No newline at end of file From f3bad34fe9156f1fe2d2e2d4a4a7d8a244107085 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 1 Oct 2018 16:55:30 -0300 Subject: [PATCH 0288/1415] #17744 Adding others isVirtual mock and annotations --- .../js/view/payment/method-renderer/cc-form.test.js | 7 ++++++- .../js/view/payment/method-renderer/paypal.test.js | 2 ++ .../method-renderer/paypal-express-abstract.test.js | 6 +++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js index 84db685c02987..8fdef2cbaadbb 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js @@ -19,7 +19,12 @@ define([ billingAddress: ko.observable(), shippingAddress: ko.observable(), paymentMethod: ko.observable(), - totals: ko.observable({}) + totals: ko.observable({}), + + /** Stub */ + isVirtual: function () { + return false; + } }, 'Magento_Braintree/js/view/payment/validator-handler': jasmine.createSpyObj( 'validator-handler', diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js index f9475d78607f4..4fc73caf7e14b 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js @@ -25,6 +25,8 @@ define([ totals: ko.observable({ 'base_grand_total': 0 }), + + /** Stub */ isVirtual: function () { return false; } diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js index f05338ad1e7d2..9950c89ce3c9d 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js @@ -28,8 +28,12 @@ define([ billingAddress: ko.observable(), shippingAddress: ko.observable(), paymentMethod: ko.observable(), - totals: ko.observable({}) + totals: ko.observable({}), + /** Stub */ + isVirtual: function () { + return false; + } }, 'Magento_Checkout/js/action/set-payment-information': setPaymentMock, 'Magento_Checkout/js/model/payment/additional-validators': { From e12044867b9d59bf44b5baedec539e79f9a2c020 Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Mon, 1 Oct 2018 22:33:31 +0200 Subject: [PATCH 0289/1415] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 7240707f642c2..6add4e8cb3ad1 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,8 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'); + // HTTP_X_FORWARDED_PROTO to check whether a webserver using HTTP is behind a load balancer serving HTTPS + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; $url = ($isSecure ? 'https://' : 'http://') . $host; if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443]) From 2510c4af6f8bb5b67b87c65853e977a3d0baccc8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 1 Oct 2018 15:38:12 -0500 Subject: [PATCH 0290/1415] MC-4303: Functional tests failure with the installed Dotmailer module --- .../Test/Mftf/ActionGroup/CaptchaFormsDisplayingActionGroup.xml | 2 +- .../Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Captcha/Test/Mftf/ActionGroup/CaptchaFormsDisplayingActionGroup.xml b/app/code/Magento/Captcha/Test/Mftf/ActionGroup/CaptchaFormsDisplayingActionGroup.xml index 71a876bbbcdbf..beb2c2bffa135 100644 --- a/app/code/Magento/Captcha/Test/Mftf/ActionGroup/CaptchaFormsDisplayingActionGroup.xml +++ b/app/code/Magento/Captcha/Test/Mftf/ActionGroup/CaptchaFormsDisplayingActionGroup.xml @@ -13,7 +13,7 @@ <waitForPageLoad stepKey="waitForStoresLoaded"/> <click selector="{{CaptchaFormsDisplayingSection.config}}" stepKey="ClickToGoConfiguration"/> <waitForPageLoad stepKey="waitForConfigurationsLoaded"/> - <scrollTo selector="{{CaptchaFormsDisplayingSection.customer}}" stepKey="ScrollToCustomers"/> + <scrollTo selector="{{CaptchaFormsDisplayingSection.customer}}" x="0" y="-80" stepKey="ScrollToCustomers"/> <click selector="{{CaptchaFormsDisplayingSection.customer}}" stepKey="ClickToCustomers"/> <waitForPageLoad stepKey="waitForCustomerConfigurationsLoaded"/> <click selector="{{CaptchaFormsDisplayingSection.customerConfig}}" stepKey="ClickToGoCustomerConfiguration"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml index ed08c84cdb6f8..7a9de9670f216 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml @@ -15,7 +15,7 @@ <element name="apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> <element name="filter" type="button" selector="//div[@class='data-grid-filters-action-wrap']/button" timeout="30"/> <element name="typeDropDown" type="multiselect" selector="//select[@name='type_id']" timeout="30"/> - <element name="bundleOption" type="multiselect" selector="//select[@name='type_id']/option[4]" timeout="30"/> + <element name="bundleOption" type="multiselect" selector="//select[@name='type_id']/option[@value='bundle']" timeout="30"/> <element name="applyFilters" type="button" selector="//button[@class='action-secondary']" timeout="30"/> <element name="allCheckbox" type="checkbox" selector="//div[@data-role='grid-wrapper']//label[@data-bind='attr: {for: ko.uid}']" timeout="30"/> <element name="actions" type="button" selector="//div[@class='action-select-wrap']/button" timeout="30"/> From 0c42ce29764cd1198a2d84ac0509891b7801934e Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 1 Oct 2018 17:31:28 -0500 Subject: [PATCH 0291/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - updated test to comment out a step to fillField --- .../Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index 66316d0af8b60..e4fd894f608c5 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -120,10 +120,9 @@ <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreateCreditMemo" after="createCreditMemoComment"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewMemoInPageTitle"/> - <!--Update Qty of items to be refunded and submit refund--> + <!--Submit refund--> <scrollTo selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" stepKey="scrollToItemsToRefund"/> - <fillField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" stepKey="fillQtyOfItemsToRefund" after="scrollToItemsToRefund"/> - + <!--<fillField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" stepKey="fillQtyOfItemsToRefund" after="scrollToItemsToRefund"/>--> <!--<click selector="{{AdminCreditMemoItemsSection.updateQty}}" stepKey="updateRefundQty"/>--> <waitForLoadingMaskToDisappear stepKey="waitForRefundQtyToUpdate"/> <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="seeSubmitRefundBtn"/> From 440e9eb40884e12236f820f9ba1e52cb704e702f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 2 Oct 2018 09:47:30 +0300 Subject: [PATCH 0292/1415] MAGETWO-91711: Unable to delete downloadable product links if sample links are not deleted - Set empty arrays if info doesn't come from request. --- .../Product/Initialization/Helper/Plugin/Downloadable.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php index f56b219f72db2..a283891afc406 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php @@ -11,6 +11,9 @@ use Magento\Downloadable\Api\Data\SampleInterfaceFactory; use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +/** + * Class for initialization downloadable info from request. + */ class Downloadable { /** @@ -92,6 +95,8 @@ public function afterInitialize( } } $extension->setDownloadableProductLinks($links); + } else { + $extension->setDownloadableProductLinks([]); } if (isset($downloadable['sample']) && is_array($downloadable['sample'])) { $samples = []; @@ -107,6 +112,8 @@ public function afterInitialize( } } $extension->setDownloadableProductSamples($samples); + } else { + $extension->setDownloadableProductSamples([]); } $product->setExtensionAttributes($extension); if ($product->getLinksPurchasedSeparately()) { From 45eecf58054aa9c22cdae6fb7f397371d79ddf75 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Tue, 2 Oct 2018 11:46:32 +0300 Subject: [PATCH 0293/1415] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Section/AdminUrlRewriteIndexSection.xml | 4 +-- ...writesForProductInAnchorCategoriesTest.xml | 34 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml index 3c445b5cf3e6f..0880b50950e15 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUrlRewriteIndexSection"> - <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> - <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> + <element name="requestPathFilter" type="input" selector="#urlrewriteGrid_filter_request_path"/> + <element name="requestPathColumnValue" type="text" selector="//*[@id='urlrewriteGrid']//tbody//td[@data-column='request_path' and normalize-space(.)='{{columnValue}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 562d414a63ddb..0d9df9176d2b5 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -35,8 +35,6 @@ </before> <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <deleteData createDataKey="simpleSubCategory3" stepKey="deletesimpleSubCategory3"/> - <deleteData createDataKey="simpleSubCategory2" stepKey="deletesimpleSubCategory2"/> <deleteData createDataKey="simpleSubCategory1" stepKey="deletesimpleSubCategory1"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> @@ -46,36 +44,36 @@ <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> - <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue4"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue4"/> <!-- 3. Edit Category 1 for DEFAULT Store View: --> - <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView"> + <actionGroup ref="switchCategoryStoreView" stepKey="switchStoreView"> <argument name="Store" value="_defaultStore.name"/> - <argument name="CatName" value="SimpleSubCategory.name"/> + <argument name="CatName" value="$$simpleSubCategory1.name$$"/> </actionGroup> <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection2"/> <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckRedirect2"/> <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new" stepKey="changeURLKey"/> - + <checkOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="checkUrlKeyRedirect"/> <!-- 4. Save Category 1 --> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessageAfterSaved"/> <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> - <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue4"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue5"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue6"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue7"/> </test> </tests> From f751fc0bf88cae96bb9f3a6b9e60fea646778bf2 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 1 Oct 2018 17:50:05 +0300 Subject: [PATCH 0294/1415] MAGETWO-91495: 'Invalid data provided for linked products' error on 'Save & Duplicate' product action - Fix code style --- app/code/Magento/Catalog/Model/Product.php | 96 ++++++++++++++-------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 0b3d298061c79..ff361a87bc724 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -503,8 +503,9 @@ protected function _getResource() } /** - * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for - * product will return all product attribute codes + * Get a list of custom attribute codes that belongs to product attribute set. + * + * If attribute set not specified for product will return all product attribute codes. * * @return string[] */ @@ -589,9 +590,10 @@ public function getPrice() } /** - * @codeCoverageIgnoreStart - * Get visibility status + * Get visibility status. + * * @see \Magento\Catalog\Model\Product\Visibility + * @codeCoverageIgnoreStart * * @return int */ @@ -667,6 +669,7 @@ public function getStatus() /** * Retrieve type instance of the product. + * * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType @@ -826,11 +829,12 @@ public function getStoreIds() } /** - * Retrieve product attributes - * if $groupId is null - retrieve all product attributes + * Retrieve product attributes. + * + * If $groupId is null - retrieve all product attributes. * - * @param int $groupId Retrieve attributes of the specified group - * @param bool $skipSuper Not used + * @param int $groupId Retrieve attributes of the specified group. + * @param bool $skipSuper Not used. * @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -920,11 +924,12 @@ public function beforeSave() } /** - * Check/set if options can be affected when saving product + * Check/set if options can be affected when saving product. + * * If value specified, it will be set. * - * @param bool $value - * @return bool + * @param bool $value + * @return bool */ public function canAffectOptions($value = null) { @@ -1040,8 +1045,9 @@ public function reindex() } /** - * Clear cache related with product and protect delete from not admin - * Register indexing event before delete product + * Clear cache related with product and protect delete from not admin. + * + * Register indexing event before delete product. * * @return \Magento\Catalog\Model\Product */ @@ -1548,13 +1554,12 @@ public function hasGalleryAttribute() } /** - * Add image to media gallery + * Add image to media gallery. * - * @param string $file file path of image in file system - * @param string|array $mediaAttribute code of attribute with type 'media_image', - * leave blank if image should be only in gallery - * @param boolean $move if true, it will move source file - * @param boolean $exclude mark image as disabled in product page view + * @param string $file Path in file system. + * @param string|array $mediaAttribute Attribute code. Leave blank if image should be only in gallery. + * @param boolean $move If true, it will move source file. + * @param boolean $exclude Mark image as disabled in product page view. * @return \Magento\Catalog\Model\Product */ public function addImageToMediaGallery($file, $mediaAttribute = null, $move = false, $exclude = true) @@ -1715,8 +1720,9 @@ public function getIsSalable() } /** - * Check is a virtual product - * Data helper wrapper + * Check is a virtual product. + * + * Data helper wrapper. * * @return bool */ @@ -1806,11 +1812,11 @@ public function formatUrlKey($str) } /** - * Save current attribute with code $code and assign new value + * Save current attribute with code and assign new value. * - * @param string $code Attribute code - * @param mixed $value New attribute value - * @param int $store Store ID + * @param string $code + * @param mixed $value + * @param int $store Store ID. * @return void */ public function addAttributeUpdate($code, $value, $store) @@ -1879,7 +1885,8 @@ public function getRequestPath() } /** - * Custom function for other modules + * Custom function for other modules. + * * @return string */ public function getGiftMessageAvailable() @@ -1998,6 +2005,10 @@ public function getOptions() } /** + * @inheritdoc + * + * Set product custom options to data array. + * * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options * @return $this */ @@ -2021,10 +2032,10 @@ public function getIsVirtual() /** * Add custom option information to product * - * @param string $code Option code - * @param mixed $value Value of the option - * @param int|Product $product Product ID - * @return $this + * @param string $code + * @param mixed $value + * @param int|Product $product + * @return $this */ public function addCustomOption($code, $value, $product = null) { @@ -2218,7 +2229,8 @@ public function getPreconfiguredValues() /** * Prepare product custom options. - * To be sure that all product custom options does not has ID and has product instance + * + * To be sure that all product custom options does not has ID and has product instance. * * @return \Magento\Catalog\Model\Product */ @@ -2552,7 +2564,9 @@ public function setTypeId($typeId) } /** - * {@inheritdoc} + * @inheritdoc + * + * Returns extension attributes from data array. * * @return \Magento\Catalog\Api\Data\ProductExtensionInterface */ @@ -2562,7 +2576,9 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc + * + * Set extension attributes to data array. * * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes * @return $this @@ -2575,6 +2591,8 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensio //@codeCoverageIgnoreEnd /** + * Converts to media gallery entry. + * * @param array $mediaGallery * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] */ @@ -2592,6 +2610,10 @@ protected function convertToMediaGalleryInterface(array $mediaGallery) } /** + * @inheritdoc + * + * Returns media gallery images. + * * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null */ public function getMediaGalleryEntries() @@ -2606,6 +2628,10 @@ public function getMediaGalleryEntries() } /** + * @inheritdoc + * + * Set media gallery images. + * * @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries * @return $this */ @@ -2648,6 +2674,8 @@ public function setId($value) } /** + * Returns product link repository. + * * @return ProductLinkRepositoryInterface */ private function getLinkRepository() @@ -2660,6 +2688,8 @@ private function getLinkRepository() } /** + * Returns media gallery processor. + * * @return Product\Gallery\Processor */ private function getMediaGalleryProcessor() From 2c651382be48db9916469d286227a400c5af1ef5 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Mon, 1 Oct 2018 19:36:56 +0300 Subject: [PATCH 0295/1415] MAGETWO-95315: [2.3] Joins to grid collections causes MySQL exception due to ambiguous where clause --- .../ResourceModel/Order/Grid/Collection.php | 15 +++++++ .../Order/Grid/CollectionTest.php | 45 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php index f6dd8f8527a53..82c612c1a781d 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php @@ -35,4 +35,19 @@ public function __construct( ) { parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel); } + + /** + * @inheritdoc + */ + protected function _initSelect() + { + parent::_initSelect(); + + $tableDescription = $this->getConnection()->describeTable($this->getMainTable()); + foreach ($tableDescription as $columnInfo) { + $this->addFilterToMap($columnInfo['COLUMN_NAME'], 'main_table.' . $columnInfo['COLUMN_NAME']); + } + + return $this; + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php new file mode 100644 index 0000000000000..1649706a51f6b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Model\ResourceModel\Order\Grid; + +use Magento\TestFramework\Helper\Bootstrap; + +class CollectionTest extends \PHPUnit\Framework\TestCase +{ + /** + * Tests collection properties. + * + * @throws \ReflectionException + * @return void + */ + public function testCollectionCreate(): void + { + $objectManager = Bootstrap::getObjectManager(); + + /** @var Collection $gridCollection */ + $gridCollection = $objectManager->get(Collection::class); + $tableDescription = $gridCollection->getConnection() + ->describeTable($gridCollection->getMainTable()); + + $mapper = new \ReflectionMethod( + Collection::class, + '_getMapper' + ); + $mapper->setAccessible(true); + $map = $mapper->invoke($gridCollection); + + self::assertInternalType('array', $map); + self::assertArrayHasKey('fields', $map); + self::assertInternalType('array', $map['fields']); + self::assertCount(count($tableDescription), $map['fields']); + + foreach ($map['fields'] as $mappedName) { + self::assertContains('main_table.', $mappedName); + } + } +} From 4333c92bf37af3c9e50fd953a46e904f0a1c2b05 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Tue, 2 Oct 2018 14:24:20 +0300 Subject: [PATCH 0296/1415] MAGETWO-95311: [2.3] Removed products are still exist in wishlist_item_option table in database --- .../Patch/Schema/AddProductIdConstraint.php | 79 +++++++++++++++++++ .../Wishlist/etc/db_schema_whitelist.json | 6 +- 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php diff --git a/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php b/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php new file mode 100644 index 0000000000000..5c65fce10ccd2 --- /dev/null +++ b/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Setup\Patch\Schema; + +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Setup\Patch\SchemaPatchInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * Class AddProductIdConstraint + */ +class AddProductIdConstraint implements SchemaPatchInterface +{ + /** + * @var SchemaSetupInterface + */ + private $schemaSetup; + + /** + * @param SchemaSetupInterface $schemaSetup + */ + public function __construct( + SchemaSetupInterface $schemaSetup + ) { + $this->schemaSetup = $schemaSetup; + } + + /** + * Run code inside patch. + * + * @return void + */ + public function apply() + { + $this->schemaSetup->startSetup(); + + $this->schemaSetup->getConnection()->addForeignKey( + $this->schemaSetup->getConnection()->getForeignKeyName( + $this->schemaSetup->getTable('wishlist_item_option'), + 'product_id', + $this->schemaSetup->getTable('catalog_product_entity'), + 'entity_id' + ), + $this->schemaSetup->getTable('wishlist_item_option'), + 'product_id', + $this->schemaSetup->getTable('catalog_product_entity'), + 'entity_id', + AdapterInterface::FK_ACTION_CASCADE, + true + ); + + $this->schemaSetup->endSetup(); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Wishlist/etc/db_schema_whitelist.json b/app/code/Magento/Wishlist/etc/db_schema_whitelist.json index beaab64280a76..36a294f26e145 100644 --- a/app/code/Magento/Wishlist/etc/db_schema_whitelist.json +++ b/app/code/Magento/Wishlist/etc/db_schema_whitelist.json @@ -35,8 +35,7 @@ "PRIMARY": true, "WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID": true, "WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "WISHLIST_ITEM_STORE_ID_STORE_STORE_ID": true, - "WISHLIST_ITEM_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "WISHLIST_ITEM_STORE_ID_STORE_STORE_ID": true } }, "wishlist_item_option": { @@ -49,7 +48,8 @@ }, "constraint": { "PRIMARY": true, - "FK_A014B30B04B72DD0EAB3EECD779728D6": true + "FK_A014B30B04B72DD0EAB3EECD779728D6": true, + "WISHLIST_ITEM_OPTION_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true } } } \ No newline at end of file From f8d5834fad78ff001e107c79e2f26de9b6604ed9 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 2 Oct 2018 14:38:13 +0300 Subject: [PATCH 0297/1415] MAGETWO-91753: Results of filters with color and other filters are not showing product results - Code style fix --- .../Model/Search/FilterMapper/CustomAttributeFilter.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php index 8beffab8053b9..723910978dfae 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php @@ -16,8 +16,7 @@ use Magento\Catalog\Model\Product; /** - * Class CustomAttributeFilter - * Applies filters by custom attributes to base select + * Applies filters by custom attributes to base select. */ class CustomAttributeFilter { @@ -71,13 +70,13 @@ public function __construct( * Applies filters by custom attributes to base select * * @param Select $select - * @param FilterInterface[] ...$filters + * @param FilterInterface[] $filters * @return Select * @throws \Magento\Framework\Exception\LocalizedException * @throws \InvalidArgumentException * @throws \DomainException */ - public function apply(Select $select, FilterInterface ... $filters) + public function apply(Select $select, FilterInterface ...$filters) { $select = clone $select; $mainTableAlias = $this->extractTableAliasFromSelect($select); From 6db1a827593a6a2196f0c711256cd5bbfc507ae1 Mon Sep 17 00:00:00 2001 From: bshevchenko <1408sheva@gmail.com> Date: Tue, 2 Oct 2018 17:02:00 +0300 Subject: [PATCH 0298/1415] MAGETWO-95332: Update price in shopping cart after product save --- .../Mftf/Section/AdminMainActionsSection.xml | 4 +- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 9 ++- .../Mftf/Section/CheckoutPaymentSection.xml | 7 +- .../Section/StorefrontMiniCartSection.xml | 1 + ...riceInShoppingCartAfterProductSaveTest.xml | 66 +++++++++++++++++++ .../AdminConfigCustomerActionGroup.xml | 20 ++++++ .../Mftf/Page/AdminCustomerConfigPage.xml | 12 ++++ .../Section/AdminCustomerConfigSection.xml | 12 ++++ 8 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml index cb164d43a49ff..bc576559e7a13 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminMainActionsSection"> - <element name="save" type="button" selector="#save"/> - <element name="delete" type="button" selector="#delete"/> + <element name="save" type="button" selector="#save" timeout="30"/> + <element name="delete" type="button" selector="#delete" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 32d6ad8667029..2e800cdb3fb8c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -10,17 +10,16 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!-- Go to checkout from minicart --> <actionGroup name="GoToCheckoutFromMinicartActionGroup"> - <wait stepKey="wait" time="10" /> + <waitForElementNotVisible selector="{{StorefrontMinicartSection.emptyCart}}" stepKey="waitUpdateQuantity" /> <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> <!-- Guest checkout filling shipping section --> <actionGroup name="GuestCheckoutFillingShippingSectionActionGroup"> <arguments> - <argument name="customerVar"/> - <argument name="customerAddressVar"/> + <argument name="customerVar" defaultValue="CustomerEntityOne"/> + <argument name="customerAddressVar" defaultValue="CustomerAddressSimple"/> </arguments> <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> @@ -161,4 +160,4 @@ <see userInput="You are signed out" stepKey="signOut"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 7dda1110fd145..2a6a6bb6d2593 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -25,7 +25,7 @@ <element name="billingAddress" type="text" selector="div.billing-address-details"/> <element name="cartItems" type="text" selector="ol.minicart-items"/> <element name="cartItemsArea" type="button" selector="div.block.items-in-cart"/> - <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active"/> + <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active" timeout="30"/> <element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/> <element name="placeOrder" type="button" selector="button.action.primary.checkout" timeout="30"/> <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[text()='Payment Method']" /> @@ -40,8 +40,9 @@ <element name="shipToInformation" type="text" selector="//div[@class='ship-to']//div[@class='shipping-information-content']" /> <element name="shippingMethodInformation" type="text" selector="//div[@class='ship-via']//div[@class='shipping-information-content']" /> <element name="paymentMethodTitle" type="text" selector=".payment-method-title span" /> - <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> - <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> + <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> + <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> + <element name="productItemPriceByName" type="text" selector="//div[@class='product-item-details'][contains(., '{{ProductName}}')]//span[@class='price']" parameterized="true"/> <element name="tax" type="text" selector="[data-th='Tax'] span" timeout="30"/> <element name="taxPercentage" type="text" selector=".totals-tax-details .mark"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index c8ff851ae54ab..ccb626d4e1e41 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -27,5 +27,6 @@ <element name="itemQuantityUpdate" type="button" selector="//a[text()='{{productName}}']/../..//span[text()='Update']" parameterized="true"/> <element name="itemDiscount" type="text" selector="//tr[@class='totals']//td[@class='amount']/span"/> <element name="subtotal" type="text" selector="//tr[@class='totals sub']//td[@class='amount']/span"/> + <element name="emptyCart" type="text" selector=".counter.qty.empty"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml new file mode 100644 index 0000000000000..91f9cbf398d24 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontUpdatePriceInShoppingCartAfterProductSaveTest"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via the Storefront"/> + <title value="Update price in shopping cart after product save"/> + <description value="Price in shopping cart should be updated after product save with changed price"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-58179"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="SimpleProduct2" stepKey="createSimpleProduct"> + <field key="price">100</field> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setCustomerDataLifetime"> + <argument name="minutes" value="1"/> + </actionGroup> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setDefaultCustomerDataLifetime"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Go to product page--> + <amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.custom_attributes[url_key]$$)}}" stepKey="navigateToSimpleProductPage"/> + + <!--Add Product to Shopping Cart--> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$$createSimpleProduct.name$$"/> + </actionGroup> + + <!--Go to Checkout--> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutFillingShipping"/> + + <!--Check price--> + <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsAreaActive}}" visible="false" stepKey="openItemProductBlock"/> + <see userInput="$100.00" selector="{{CheckoutPaymentSection.orderSummarySubtotal}}" stepKey="checkSummarySubtotal"/> + <see userInput="$100.00" selector="{{CheckoutPaymentSection.productItemPriceByName($$createSimpleProduct.name$$)}}" stepKey="checkItemPrice"/> + + <!--Edit product price via admin panel--> + <openNewTab stepKey="openNewTab"/> + <amOnPage url="{{AdminProductEditPage.url($$createSimpleProduct.id$$)}}" stepKey="goToProductEditPage"/> + <fillField userInput="120" selector="{{AdminProductFormSection.productPrice}}" stepKey="setNewPrice"/> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <closeTab stepKey="closeTab"/> + + <!--Check price--> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForCheckoutPageReload"/> + <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsAreaActive}}" visible="false" stepKey="openItemProductBlock1"/> + <see userInput="$120.00" selector="{{CheckoutPaymentSection.orderSummarySubtotal}}" stepKey="checkSummarySubtotal1"/> + <see userInput="$120.00" selector="{{CheckoutPaymentSection.productItemPriceByName($$createSimpleProduct.name$$)}}" stepKey="checkItemPrice1"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml new file mode 100644 index 0000000000000..8a3ab7068696c --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="SetCustomerDataLifetimeActionGroup"> + <arguments> + <argument name="minutes" defaultValue="60" type="string"/> + </arguments> + <amOnPage url="{{AdminCustomerConfigPage.url('#customer_online_customers-link')}}" stepKey="openCustomerConfigPage"/> + <fillField userInput="{{minutes}}" selector="{{AdminCustomerConfigSection.customerDataLifetime}}" stepKey="fillCustomerDataLifetime"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSave"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml new file mode 100644 index 0000000000000..282f9bb6fdeb5 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminCustomerConfigPage" url="admin/system_config/edit/section/customer/{{tabLink}}" area="admin" parameterized="true" module="Magento_Customer"> + <section name="AdminCustomerConfigSection"/> + </page> +</pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml new file mode 100644 index 0000000000000..9e104eb52cf90 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCustomerConfigSection"> + <element name="customerDataLifetime" type="input" selector="#customer_online_customers_section_data_lifetime"/> + </section> +</sections> From ac753fd7ec9d115726270038094f4b42fedfbaf0 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Tue, 2 Oct 2018 17:04:12 +0300 Subject: [PATCH 0299/1415] MAGETWO-95312: [2.3] Cart is not empty after removing the product --- .../Magento/Checkout/Controller/Cart/Delete.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php index 7e88a484f9f6c..e9c15bd7f8cc1 100644 --- a/app/code/Magento/Checkout/Controller/Cart/Delete.php +++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,11 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +/** + * Action Delete. + * + * Deletes item from cart. + */ class Delete extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface { /** @@ -24,7 +28,12 @@ public function execute() $id = (int)$this->getRequest()->getParam('id'); if ($id) { try { - $this->cart->removeItem($id)->save(); + $this->cart->removeItem($id); + // We should set Totals to be recollected once more because of Cart model as usually is loading + // before action executing and in case when triggerRecollect setted as true recollecting will + // executed and the flag will be true already. + $this->cart->getQuote()->setTotalsCollectedFlag(false); + $this->cart->save(); } catch (\Exception $e) { $this->messageManager->addErrorMessage(__('We can\'t remove the item.')); $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); From 069aa1c014ef872ba5b353fa08a2359e66cbe630 Mon Sep 17 00:00:00 2001 From: "Vasiliev.A" <a.vasiliev@sam-solutions.biz> Date: Mon, 17 Sep 2018 14:30:40 +0300 Subject: [PATCH 0300/1415] add support HTTP DELETE method for async bulk request by adding merging url params with body params --- .../Controller/Rest/Asynchronous/InputParamsResolver.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php index e6df38c563ed1..4ebb23f33e97b 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php @@ -95,6 +95,13 @@ public function resolve() $this->requestValidator->validate(); $webapiResolvedParams = []; $inputData = $this->request->getRequestData(); + + $httpMethod = $this->request->getHttpMethod(); + if ($httpMethod == \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE) { + $requestBodyParams = $this->request->getBodyParams(); + $inputData = array_merge($requestBodyParams, $inputData); + } + foreach ($inputData as $key => $singleEntityParams) { $webapiResolvedParams[$key] = $this->resolveBulkItemParams($singleEntityParams); } From 9a757cbbf2013fa849d13fe3d4775ec8cd38b6dc Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Tue, 2 Oct 2018 17:28:09 +0300 Subject: [PATCH 0301/1415] MAGETWO-94762: Amqp Logic Exception - fix magento/bulk-api-ce#28 --- .../Model/Cron/ConsumersRunner.php | 59 ++++++++++++++++--- .../Unit/Model/Cron/ConsumersRunnerTest.php | 13 +++- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/MessageQueue/Model/Cron/ConsumersRunner.php b/app/code/Magento/MessageQueue/Model/Cron/ConsumersRunner.php index f301fb9289efb..f5011248d7772 100644 --- a/app/code/Magento/MessageQueue/Model/Cron/ConsumersRunner.php +++ b/app/code/Magento/MessageQueue/Model/Cron/ConsumersRunner.php @@ -5,9 +5,13 @@ */ namespace Magento\MessageQueue\Model\Cron; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\MessageQueue\ConnectionTypeResolver; +use Magento\Framework\MessageQueue\Consumer\Config\ConsumerConfigItemInterface; use Magento\Framework\ShellInterface; use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; use Magento\Framework\App\DeploymentConfig; +use Psr\Log\LoggerInterface; use Symfony\Component\Process\PhpExecutableFinder; use Magento\MessageQueue\Model\Cron\ConsumersRunner\PidConsumerManager; @@ -56,6 +60,16 @@ class ConsumersRunner */ private $pidConsumerManager; + /** + * @var ConnectionTypeResolver + */ + private $mqConnectionTypeResolver; + + /** + * @var LoggerInterface + */ + private $logger; + /** * @param PhpExecutableFinder $phpExecutableFinder The executable finder specifically designed * for the PHP executable @@ -63,19 +77,27 @@ class ConsumersRunner * @param DeploymentConfig $deploymentConfig The application deployment configuration * @param ShellInterface $shellBackground The shell command line wrapper for executing command in background * @param PidConsumerManager $pidConsumerManager The class for checking status of process by PID + * @param ConnectionTypeResolver $mqConnectionTypeResolver Consumer connection resolver + * @param LoggerInterface $logger Logger */ public function __construct( PhpExecutableFinder $phpExecutableFinder, ConsumerConfigInterface $consumerConfig, DeploymentConfig $deploymentConfig, ShellInterface $shellBackground, - PidConsumerManager $pidConsumerManager + PidConsumerManager $pidConsumerManager, + ConnectionTypeResolver $mqConnectionTypeResolver = null, + LoggerInterface $logger = null ) { $this->phpExecutableFinder = $phpExecutableFinder; $this->consumerConfig = $consumerConfig; $this->deploymentConfig = $deploymentConfig; $this->shellBackground = $shellBackground; $this->pidConsumerManager = $pidConsumerManager; + $this->mqConnectionTypeResolver = $mqConnectionTypeResolver + ?: ObjectManager::getInstance()->get(ConnectionTypeResolver::class); + $this->logger = $logger + ?: ObjectManager::getInstance()->get(LoggerInterface::class); } /** @@ -94,12 +116,12 @@ public function run() $php = $this->phpExecutableFinder->find() ?: 'php'; foreach ($this->consumerConfig->getConsumers() as $consumer) { - $consumerName = $consumer->getName(); - - if (!$this->canBeRun($consumerName, $allowedConsumers)) { + if (!$this->canBeRun($consumer, $allowedConsumers)) { continue; } + $consumerName = $consumer->getName(); + $arguments = [ $consumerName, '--pid-file-path=' . $this->getPidFilePath($consumerName), @@ -119,16 +141,37 @@ public function run() /** * Checks that the consumer can be run * - * @param string $consumerName The consumer name + * @param ConsumerConfigItemInterface $consumerConfig The consumer config * @param array $allowedConsumers The list of allowed consumers * If $allowedConsumers is empty it means that all consumers are allowed * @return bool Returns true if the consumer can be run + * @throws \Magento\Framework\Exception\FileSystemException */ - private function canBeRun($consumerName, array $allowedConsumers = []) + private function canBeRun(ConsumerConfigItemInterface $consumerConfig, array $allowedConsumers = []): bool { - $allowed = empty($allowedConsumers) ?: in_array($consumerName, $allowedConsumers); + $consumerName = $consumerConfig->getName(); + if (!empty($allowedConsumers) && !in_array($consumerName, $allowedConsumers)) { + return false; + } + + if ($this->pidConsumerManager->isRun($this->getPidFilePath($consumerName))) { + return false; + } + + $connectionName = $consumerConfig->getConnection(); + try { + $this->mqConnectionTypeResolver->getConnectionType($connectionName); + } catch (\LogicException $e) { + $this->logger->info(sprintf( + 'Consumer "%s" skipped as required connection "%s" is not configured. %s', + $consumerName, + $connectionName, + $e->getMessage() + )); + return false; + } - return $allowed && !$this->pidConsumerManager->isRun($this->getPidFilePath($consumerName)); + return true; } /** diff --git a/app/code/Magento/MessageQueue/Test/Unit/Model/Cron/ConsumersRunnerTest.php b/app/code/Magento/MessageQueue/Test/Unit/Model/Cron/ConsumersRunnerTest.php index bf8796a03f52a..006354b997d3a 100644 --- a/app/code/Magento/MessageQueue/Test/Unit/Model/Cron/ConsumersRunnerTest.php +++ b/app/code/Magento/MessageQueue/Test/Unit/Model/Cron/ConsumersRunnerTest.php @@ -5,6 +5,7 @@ */ namespace Magento\MessageQueue\Test\Unit\Model\Cron; +use Magento\Framework\MessageQueue\ConnectionTypeResolver; use \PHPUnit_Framework_MockObject_MockObject as MockObject; use Magento\Framework\ShellInterface; use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfigInterface; @@ -41,6 +42,11 @@ class ConsumersRunnerTest extends \PHPUnit\Framework\TestCase */ private $phpExecutableFinderMock; + /** + * @var ConnectionTypeResolver + */ + private $connectionTypeResover; + /** * @var ConsumersRunner */ @@ -66,13 +72,18 @@ protected function setUp() $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) ->disableOriginalConstructor() ->getMock(); + $this->connectionTypeResover = $this->getMockBuilder(ConnectionTypeResolver::class) + ->disableOriginalConstructor() + ->getMock(); + $this->connectionTypeResover->method('getConnectionType')->willReturn('something'); $this->consumersRunner = new ConsumersRunner( $this->phpExecutableFinderMock, $this->consumerConfigMock, $this->deploymentConfigMock, $this->shellBackgroundMock, - $this->pidConsumerManagerMock + $this->pidConsumerManagerMock, + $this->connectionTypeResover ); } From 0e7f7792950225d26bda094fa9e667e9a3833a83 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 2 Oct 2018 10:06:09 -0500 Subject: [PATCH 0302/1415] Fixed docblock --- app/code/Magento/Catalog/Model/Product.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index cd68ca9889991..e0b1903621dcb 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -498,7 +498,8 @@ protected function _getResource() } /** - * Get a list of custom attribute codes that belongs to product attribute set. + * Get a list of custom attribute codes that belongs to product attribute set + * * If attribute set not specified for product will return all product attribute codes. * * @return string[] @@ -662,7 +663,8 @@ public function getStatus() } /** - * Retrieve type instance of the product. + * Retrieve type instance of the product + * * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType @@ -2217,7 +2219,8 @@ public function getPreconfiguredValues() } /** - * Prepare product custom options. + * Prepare product custom options + * * To be sure that all product custom options does not has ID and has product instance. * * @return \Magento\Catalog\Model\Product From 5f9a9901530d8023b6756a0a73a2a9c7a4c1ee35 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Tue, 28 Aug 2018 13:38:50 +0300 Subject: [PATCH 0303/1415] MAGETWO-91569: Special characters in CSV return error: General system exception happened - Added message to "Select File to Import" field in import form --- .../ImportExport/Block/Adminhtml/Import/Edit/Form.php | 5 ++++- .../CatalogImportExport/_files/product_export_data.php | 2 +- .../_files/product_export_data_special_chars.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index 39d0d5c7feaee..8fd73e466083a 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -212,7 +212,10 @@ protected function _prepareForm() 'label' => __('Select File to Import'), 'title' => __('Select File to Import'), 'required' => true, - 'class' => 'input-file' + 'class' => 'input-file', + 'note' => __( + 'File must be saved in UTF-8 encoding for proper import' + ), ] ); $fieldsets['upload']->addField( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php index 89fb9952cc6f1..477494626b9fb 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php @@ -70,7 +70,7 @@ )->setPrice( 10 )->addData( - ['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/'] + ['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/›ƒª'] )->setTierPrice( [0 => ['website_id' => 0, 'cust_group' => 0, 'price_qty' => 3, 'price' => 8]] )->setVisibility( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php index a2c2c1815a8a9..591dccf229f89 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php @@ -25,7 +25,7 @@ ->setName('New Product') ->setSku('simple "1"') ->setPrice(10) - ->addData(['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/']) + ->addData(['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/›ƒª']) ->setTierPrice([0 => ['website_id' => 0, 'cust_group' => 0, 'price_qty' => 3, 'price' => 8]]) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) From e402fc8ef52b53933e51ede14dce304ab47d378c Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 2 Oct 2018 13:27:32 -0500 Subject: [PATCH 0304/1415] MC-4303: Functional tests failure with the installed Dotmailer module --- app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 82f5b515eb967..0032a6c987e82 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -68,6 +68,7 @@ <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <waitForPageLoad stepKey="waitForInvoicePageLoad"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoices"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask5" /> From 39fbd1dadc81f837aaf2d8ec8f5615a55a2abff7 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Tue, 2 Oct 2018 15:53:31 -0500 Subject: [PATCH 0305/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization --- .../Model/Resolver/LayerFilters.php | 49 +++++++++++++++++++ .../Model/Resolver/Products.php | 12 ++--- .../CatalogGraphQl/etc/schema.graphqls | 2 +- .../GraphQl/Query/ResolverInterface.php | 3 +- 4 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/LayerFilters.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/LayerFilters.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/LayerFilters.php new file mode 100644 index 0000000000000..0ec7e12e42d55 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/LayerFilters.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Layered navigation filters resolver, used for GraphQL request processing. + */ +class LayerFilters implements ResolverInterface +{ + /** + * @var Layer\DataProvider\Filters + */ + private $filtersDataProvider; + + /** + * @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider + */ + public function __construct( + \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider + ) { + $this->filtersDataProvider = $filtersDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['layer_type'])) { + return null; + } + + return $this->filtersDataProvider->getData($value['layer_type']); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 0f618058e06df..47da945c2cce2 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -42,28 +42,22 @@ class Products implements ResolverInterface */ private $searchFilter; - /** - * @var Layer\DataProvider\Filters - */ - private $filtersDataProvider; - /** * @param Builder $searchCriteriaBuilder * @param Search $searchQuery * @param Filter $filterQuery + * @param SearchFilter $searchFilter */ public function __construct( Builder $searchCriteriaBuilder, Search $searchQuery, Filter $filterQuery, - SearchFilter $searchFilter, - \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider + SearchFilter $searchFilter ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; $this->filterQuery = $filterQuery; $this->searchFilter = $searchFilter; - $this->filtersDataProvider = $filtersDataProvider; } /** @@ -115,7 +109,7 @@ public function resolve( 'page_size' => $searchCriteria->getPageSize(), 'current_page' => $currentPage ], - 'filters' => $this->filtersDataProvider->getData($layerType) + 'layer_type' => $layerType ]; return $data; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 9235ec271a3c2..e80e6846bf9d0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -415,7 +415,7 @@ type Products @doc(description: "The Products object is the top-level object ret items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") page_info: SearchResultPageInfo @doc(description: "An object that includes the page_info and currentPage values specified in the query") total_count: Int @doc(description: "The number of products returned") - filters: [LayerFilter] @doc(description: "Layered navigation filters array") + filters: [LayerFilter] @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\LayerFilters") @doc(description: "Layered navigation filters array") sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFields") } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/ResolverInterface.php b/lib/internal/Magento/Framework/GraphQl/Query/ResolverInterface.php index 295113a98e465..c7b4c7688b9ab 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/ResolverInterface.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/ResolverInterface.php @@ -10,6 +10,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; /** * Resolver fetches the data and formats it according to the GraphQL schema. @@ -20,7 +21,7 @@ interface ResolverInterface * Fetches the data from persistence models and format it according to the GraphQL schema. * * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param $context + * @param ContextInterface $context * @param ResolveInfo $info * @param array|null $value * @param array|null $args From 2398a9448ee9c24228aa1a59f065585dc83feb4f Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Wed, 3 Oct 2018 10:11:16 +0300 Subject: [PATCH 0306/1415] MAGETWO-95174: Sorting by price for Configurable with Catalog Rule applied --- ...tSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml index a87780365c913..c93b216fc89d5 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml @@ -95,6 +95,8 @@ <actionGroup ref="changeUseForPromoRuleConditionsProductAttribute" stepKey="changeUseForPromoRuleConditionsProductAttributeToYes"> <argument name="option" value="Yes"/> </actionGroup> + <magentoCLI command="indexer:reindex" stepKey="reindex1"/> + <magentoCLI command="cache:flush" stepKey="flushCache1"/> </before> <after> From efad97ee46ebd340c6095648b8ba55776b00f318 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Wed, 3 Oct 2018 10:23:49 +0300 Subject: [PATCH 0307/1415] Fix methods descriptions --- .../AdvancedSearch/Model/Recommendations/DataProvider.php | 6 +----- app/code/Magento/CatalogInventory/Model/Configuration.php | 4 +--- .../Elasticsearch/Model/DataProvider/Suggestions.php | 8 +------- .../GiftMessage/Model/GiftMessageConfigProvider.php | 5 +---- app/code/Magento/NewRelicReporting/Model/Config.php | 4 ++-- app/code/Magento/Store/Model/HeaderProvider/Hsts.php | 4 +--- .../Store/Model/HeaderProvider/UpgradeInsecure.php | 4 +--- app/code/Magento/Store/Model/StoreManager.php | 8 ++------ app/code/Magento/Wishlist/Model/Rss/Wishlist.php | 8 ++------ 9 files changed, 12 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php index f0d998e19d7f1..c0c224766eb3c 100644 --- a/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php +++ b/app/code/Magento/AdvancedSearch/Model/Recommendations/DataProvider.php @@ -87,11 +87,7 @@ public function isResultsCountEnabled() } /** - * Get Items - * - * @param QueryInterface $query - * - * @return array|\Magento\Search\Model\QueryResult[] + * @inheritdoc */ public function getItems(QueryInterface $query) { diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php index a18fe053d5cef..8b0849c8874bc 100644 --- a/app/code/Magento/CatalogInventory/Model/Configuration.php +++ b/app/code/Magento/CatalogInventory/Model/Configuration.php @@ -152,9 +152,7 @@ public function __construct( } /** - * Default Scope Id - * - * @return int + * @inheritdoc */ public function getDefaultScopeId() { diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index 6338851bd2ff4..da8a32687535f 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -95,13 +95,7 @@ public function __construct( } /** - * Get Items - * - * @param QueryInterface $query - * - * @return array|\Magento\Search\Model\QueryResult[] - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @inheritdoc */ public function getItems(QueryInterface $query) { diff --git a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php index 82c2b52c97040..b124897770b6f 100644 --- a/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php +++ b/app/code/Magento/GiftMessage/Model/GiftMessageConfigProvider.php @@ -95,10 +95,7 @@ public function __construct( } /** - * Get Config - * - * @return array - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @inheritdoc */ public function getConfig() { diff --git a/app/code/Magento/NewRelicReporting/Model/Config.php b/app/code/Magento/NewRelicReporting/Model/Config.php index e09bae08dde75..6f3ff1df57448 100644 --- a/app/code/Magento/NewRelicReporting/Model/Config.php +++ b/app/code/Magento/NewRelicReporting/Model/Config.php @@ -91,7 +91,7 @@ public function __construct( */ public function isNewRelicEnabled() { - return $this->scopeConfig->getValue('newrelicreporting/general/enable'); + return $this->scopeConfig->isSetFlag('newrelicreporting/general/enable'); } /** @@ -181,7 +181,7 @@ public function isSeparateApps() */ public function isCronEnabled() { - return $this->scopeConfig->getValue('newrelicreporting/cron/enable_cron'); + return $this->scopeConfig->isSetFlag('newrelicreporting/cron/enable_cron'); } /** diff --git a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php index 3f6cb41ce3939..b22775e0987cb 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/Hsts.php +++ b/app/code/Magento/Store/Model/HeaderProvider/Hsts.php @@ -43,9 +43,7 @@ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $ } /** - * Whether the header should be attached to the response - * - * @return bool + * @inheritdoc */ public function canApply() { diff --git a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php index 265e9dbeb33da..0ef8726e07f1b 100644 --- a/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php +++ b/app/code/Magento/Store/Model/HeaderProvider/UpgradeInsecure.php @@ -43,9 +43,7 @@ public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $ } /** - * Whether the header should be attached to the response - * - * @return bool + * @inheritdoc */ public function canApply() { diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index b86e386c847ab..79ea0d7408c59 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -117,9 +117,7 @@ public function __construct( } /** - * Set current default store - * - * @param string $store + * @inheritdoc */ public function setCurrentStore($store) { @@ -127,9 +125,7 @@ public function setCurrentStore($store) } /** - * Allow or disallow single store mode - * - * @param bool $value + * @inheritdoc */ public function setIsSingleStoreModeAllowed($value) { diff --git a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php index 2a8b3d4152703..9ccbf80f99a0c 100644 --- a/app/code/Magento/Wishlist/Model/Rss/Wishlist.php +++ b/app/code/Magento/Wishlist/Model/Rss/Wishlist.php @@ -273,9 +273,7 @@ public function getProductPriceHtml(\Magento\Catalog\Model\Product $product) } /** - * Get Feeds - * - * @return array + * @inheritdoc */ public function getFeeds() { @@ -283,9 +281,7 @@ public function getFeeds() } /** - * Is Auth Required - * - * @return bool + * @inheritdoc */ public function isAuthRequired() { From 01419cc4d85e2d3a96e6a51383488c9fbdc85987 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Wed, 3 Oct 2018 12:37:05 +0300 Subject: [PATCH 0308/1415] MAGETWO-64282: Out of stock associated products to configurable are not full page cache cleaned - Update automation test --- ...tedProductToConfigurableOutOfStockTest.xml | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index e66ad24fd54e2..534541c96ea8c 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -26,6 +26,7 @@ <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> <requiredEntity createDataKey="simplecategory"/> </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> <requiredEntity createDataKey="createConfigProductAttribute"/> @@ -33,9 +34,11 @@ <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> <requiredEntity createDataKey="createConfigProductAttribute"/> </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> <requiredEntity createDataKey="createConfigProductAttribute"/> </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> <requiredEntity createDataKey="createConfigProductAttribute"/> </getData> @@ -53,12 +56,14 @@ <requiredEntity createDataKey="createConfigProductAttribute"/> <requiredEntity createDataKey="getConfigAttributeOption2"/> </createData> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> <requiredEntity createDataKey="createConfigProduct"/> <requiredEntity createDataKey="createConfigProductAttribute"/> <requiredEntity createDataKey="getConfigAttributeOption1"/> <requiredEntity createDataKey="getConfigAttributeOption2"/> </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> <requiredEntity createDataKey="createConfigProduct"/> <requiredEntity createDataKey="createConfigChildProduct1"/> @@ -87,11 +92,8 @@ <actionGroup ref="LoginToStorefrontActionGroup" stepKey="signUpNewUser"> <argument name="Customer" value="$$createSimpleUsCustomer$$"/> </actionGroup> - + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage"/> <!-- Go to configurable product page --> - <click userInput="$$simplecategory.name$$" stepKey="clickOnCategoryName"/> - <waitForPageLoad stepKey="waitForCategoryPageLoad"/> - <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView" after="clickOnCategoryName"/> <waitForPageLoad stepKey="waitForProductPageLoad"/> <!-- Order product with single quantity --> @@ -103,19 +105,34 @@ <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> - + <waitForPageLoad stepKey="waitForOrderSuccessPage1"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> <actionGroup ref="StorefrontSignOutActionGroup" stepKey="StorefrontSignOutActionGroup"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> - <amOnPage url="{{StorefrontCategoryPage.url($$simplecategory.name$$)}}" stepKey="onCategoryPage"/> - <waitForPageLoad stepKey="waitForCategoryLoad"/> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask3"/> + <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="searchOrderNum"/> + <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> + <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip"/> + <waitForLoadingMaskToDisappear stepKey="waitForShipLoadingMask"/> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="submitShipment"/> + <waitForPageLoad stepKey="waitShipmentCreated"/> + <actionGroup ref="logout" stepKey="logout"/> <magentoCLI stepKey="runCron" command="cron:run --group='index'"/> <!-- Wait till cron job runs for schedule updates --> <wait time="60" stepKey="waitForUpdateStarts"/> <!-- Assert that product with single quantity is not available for order --> - <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView2" /> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage2"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> <dontSee userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="assertOptionNotAvailable" /> </test> </tests> From 057f1209bcd739e14837a9e7bec91d615505174a Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Wed, 3 Oct 2018 13:41:20 +0300 Subject: [PATCH 0309/1415] MAGETWO-94121: Independent blocks rule --- .../Rule/Design/RequestAwareBlockMethod.php | 53 +++++++++++++++++++ .../resources/rulesets/design.xml | 31 +++++++++++ .../Magento/Test/Php/_files/phpmd/ruleset.xml | 1 + 3 files changed, 85 insertions(+) create mode 100644 dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/RequestAwareBlockMethod.php diff --git a/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/RequestAwareBlockMethod.php b/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/RequestAwareBlockMethod.php new file mode 100644 index 0000000000000..9ce891da718b4 --- /dev/null +++ b/dev/tests/static/framework/Magento/CodeMessDetector/Rule/Design/RequestAwareBlockMethod.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CodeMessDetector\Rule\Design; + +use PHPMD\AbstractNode; +use PHPMD\AbstractRule; +use PHPMD\Node\ClassNode; +use PHPMD\Node\MethodNode; +use PDepend\Source\AST\ASTMethod; +use PHPMD\Rule\MethodAware; + +/** + * Detect direct request usages. + */ +class RequestAwareBlockMethod extends AbstractRule implements MethodAware +{ + /** + * @inheritDoc + * + * @param ASTMethod|MethodNode $method + */ + public function apply(AbstractNode $method) + { + $definedIn = $method->getParentType(); + try { + $isBlock = ($definedIn instanceof ClassNode) + && is_subclass_of( + $definedIn->getFullQualifiedName(), + \Magento\Framework\View\Element\AbstractBlock::class + ); + } catch (\Throwable $exception) { + //Failed to load classes. + return; + } + + if ($isBlock) { + $nodes = $method->findChildrenOfType('PropertyPostfix') + $method->findChildrenOfType('MethodPostfix'); + foreach ($nodes as $node) { + $name = mb_strtolower($node->getFirstChildOfType('Identifier')->getImage()); + if ($name === '_request' || $name === 'getrequest') { + $this->addViolation($method, [$method->getFullQualifiedName()]); + break; + } + } + } + } +} diff --git a/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml b/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml index c9bfe4fe6e308..100e08276e6cf 100644 --- a/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml +++ b/dev/tests/static/framework/Magento/CodeMessDetector/resources/rulesets/design.xml @@ -54,6 +54,37 @@ class PostOrder implements ActionInterface ... return $response; } +} + ]]> + </example> + </rule> + <rule name="RequestAwareBlockMethod" + class="Magento\CodeMessDetector\Rule\Design\RequestAwareBlockMethod" + message="{0} uses request object directly. Add user input validation and suppress this warning."> + <description> + <![CDATA[ +Blocks must not depend on being used with certain controllers. +If you use request object in a block directly you must validate all user input inside the block. + ]]> + </description> + <priority>2</priority> + <properties /> + <example> + <![CDATA[ +class MyOrder extends AbstractBlock +{ + + ....... + + public function getOrder() + { + $orderId = $this->getRequest()->getParam('order_id'); + //Validate customer having such order. + if (!$this->hasOrder($this->getCustomerId(), $orderId)) { + ...deny access... + } + ..... + } } ]]> </example> diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml index fddb1e6fdfc14..2d9eb7478ce91 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpmd/ruleset.xml @@ -48,5 +48,6 @@ <!-- Magento Specific Rules --> <rule ref="Magento/CodeMessDetector/resources/rulesets/design.xml/FinalImplementation" /> <rule ref="Magento/CodeMessDetector/resources/rulesets/design.xml/AllPurposeAction" /> + <rule ref="Magento/CodeMessDetector/resources/rulesets/design.xml/RequestAwareBlockMethod" /> </ruleset> From 7c5962a43c38024275530ba71215acdd9573bbb5 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 19 Sep 2018 02:57:08 +0300 Subject: [PATCH 0310/1415] MAGETWO-91684: Issue with Newsletter subscriptions - Changing subscription behavior to websites --- .../Model/ResourceModel/Subscriber.php | 43 ++++++++++--------- .../Magento/Newsletter/Model/Subscriber.php | 3 ++ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index b6e53b3695f78..100d179cbb60e 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -5,6 +5,9 @@ */ namespace Magento\Newsletter\Model\ResourceModel; +use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\StoreManagerInterface; + /** * Newsletter subscriber resource model * @@ -48,6 +51,11 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $mathRandom; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * Construct * @@ -55,15 +63,18 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * @param \Magento\Framework\Stdlib\DateTime\DateTime $date * @param \Magento\Framework\Math\Random $mathRandom * @param string $connectionName + * @param StoreManagerInterface $storeManager */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Stdlib\DateTime\DateTime $date, \Magento\Framework\Math\Random $mathRandom, - $connectionName = null + $connectionName = null, + StoreManagerInterface $storeManager = null ) { $this->_date = $date; $this->mathRandom = $mathRandom; + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); parent::__construct($context, $connectionName); } @@ -117,19 +128,15 @@ public function loadByEmail($subscriberEmail) */ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer) { + $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); + $select = $this->connection ->select() ->from($this->getMainTable()) - ->where('customer_id=:customer_id and store_id=:store_id'); - - $result = $this->connection - ->fetchRow( - $select, - [ - 'customer_id' => $customer->getId(), - 'store_id' => $customer->getStoreId() - ] - ); + ->where('customer_id = ?', $customer->getId()) + ->where('store_id IN (?)', $storeIds); + + $result = $this->connection->fetchRow($select); if ($result) { return $result; @@ -138,16 +145,10 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select = $this->connection ->select() ->from($this->getMainTable()) - ->where('subscriber_email=:subscriber_email and store_id=:store_id'); - - $result = $this->connection - ->fetchRow( - $select, - [ - 'subscriber_email' => $customer->getEmail(), - 'store_id' => $customer->getStoreId() - ] - ); + ->where('subscriber_email = ?', $customer->getEmail()) + ->where('store_id IN (?)', $storeIds); + + $result = $this->connection->fetchRow($select); if ($result) { return $result; diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..9611e4b67f1e2 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -392,6 +392,9 @@ public function loadByCustomerId($customerId) try { $customerData = $this->customerRepository->getById($customerId); $customerData->setStoreId($this->_storeManager->getStore()->getId()); + if ($customerData->getWebsiteId() === null) { + $customerData->setWebsiteId($this->_storeManager->getStore()->getWebsiteId()); + } $data = $this->getResource()->loadByCustomerData($customerData); $this->addData($data); if (!empty($data) && $customerData->getId() && !$this->getCustomerId()) { From 9ff3f48412067730c9926bf6354d896d4b21f4a8 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 3 Oct 2018 13:47:29 +0300 Subject: [PATCH 0311/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/Block/Media/Uploader.php | 26 +++++-- .../Backend/Model/Image/ImageUploadConfig.php | 72 +++++++++++++++++++ .../Image/ImageUploadConfigInterface.php | 37 ++++++++++ app/code/Magento/Backend/etc/adminhtml/di.xml | 1 + .../Magento/Backend/etc/adminhtml/system.xml | 15 +++- app/code/Magento/Backend/etc/config.xml | 1 + .../adminhtml/templates/media/uploader.phtml | 3 +- .../view/adminhtml/web/js/media-uploader.js | 16 +++-- .../Magento/Framework/File/Uploader.php | 4 +- .../Framework/Image/Adapter/Config.php | 12 ++++ .../Image/Adapter/UploadConfigInterface.php | 2 + 11 files changed, 173 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Backend/Model/Image/ImageUploadConfig.php create mode 100644 app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index eb98808dd644b..6962141c465b8 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -10,6 +10,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Image\Adapter\UploadConfigInterface; +use Magento\Backend\Model\Image\ImageUploadConfigInterface; /** * Adminhtml media library uploader @@ -39,9 +40,9 @@ class Uploader extends \Magento\Backend\Block\Widget private $jsonEncoder; /** - * @var UploadConfigInterface + * @var ImageUploadConfigInterface */ - private $imageConfig; + private $imageUploadConfig; /** * @param \Magento\Backend\Block\Template\Context $context @@ -49,18 +50,19 @@ class Uploader extends \Magento\Backend\Block\Widget * @param array $data * @param Json $jsonEncoder * @param UploadConfigInterface $imageConfig + * @param ImageUploadConfigInterface $imageUploadConfig */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\File\Size $fileSize, array $data = [], Json $jsonEncoder = null, - UploadConfigInterface $imageConfig = null + UploadConfigInterface $imageConfig = null, + ImageUploadConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); - $this->imageConfig = $imageConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); - + $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); parent::__construct($context, $data); } @@ -111,7 +113,7 @@ public function getFileSizeService() */ public function getImageUploadMaxWidth() { - return $this->imageConfig->getMaxWidth(); + return $this->imageUploadConfig->getMaxWidth(); } /** @@ -121,7 +123,17 @@ public function getImageUploadMaxWidth() */ public function getImageUploadMaxHeight() { - return $this->imageConfig->getMaxHeight(); + return $this->imageUploadConfig->getMaxHeight(); + } + + /** + * Get image resize configuration + * + * @return bool + */ + public function getIsResizeEnabled(): bool + { + return $this->imageUploadConfig->isResizeEnabled(); } /** diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php b/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php new file mode 100644 index 0000000000000..b7e13b1e8274c --- /dev/null +++ b/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Model\Image; + +/** + * Image uploader config provider. + */ +class ImageUploadConfig implements ImageUploadConfigInterface +{ + /** + * Config path for the maximal image width value + */ + const XML_PATH_MAX_WIDTH_IMAGE = 'system/upload_configuration/max_width'; + + /** + * Config path for the maximal image height value + */ + const XML_PATH_MAX_HEIGHT_IMAGE = 'system/upload_configuration/max_height'; + + /** + * Config path for the maximal image height value + */ + const XML_PATH_ENABLE_RESIZE = 'system/upload_configuration/enable_resize'; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + private $config; + + /** + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + */ + public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $config) + { + $this->config = $config; + } + + /** + * Get maximal width value for resized image + * + * @return int + */ + public function getMaxWidth(): int + { + return (int)$this->config->getValue(self::XML_PATH_MAX_WIDTH_IMAGE); + } + + /** + * Get maximal height value for resized image + * + * @return int + */ + public function getMaxHeight(): int + { + return (int)$this->config->getValue(self::XML_PATH_MAX_HEIGHT_IMAGE); + } + + /** + * Get config value for frontend resize + * + * @return bool + */ + public function isResizeEnabled(): bool + { + return (bool)$this->config->getValue(self::XML_PATH_ENABLE_RESIZE); + } +} diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php b/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php new file mode 100644 index 0000000000000..254a13407b2c1 --- /dev/null +++ b/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Model\Image; + +/** + * Interface ImageUploadConfigInterface + * + * Used to retrieve configuration for frontend image uploader + */ +interface ImageUploadConfigInterface +{ + /** + * Get maximal width value for resized image + * + * @return int + */ + public function getMaxWidth(): int; + + /** + * Get maximal height value for resized image + * + * @return int + */ + public function getMaxHeight(): int; + + /** + * Get config value for frontend resize + * + * @return bool + */ + public function isResizeEnabled(): bool; +} diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index 3384384343fe9..dcfc99cfed310 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -168,4 +168,5 @@ </arguments> </type> <preference for="CsrfRequestValidator" type="Magento\Backend\App\Request\BackendValidator" /> + <preference for="Magento\Backend\Model\Image\ImageUploadConfigInterface" type="Magento\Backend\Model\Image\ImageUploadConfig" /> </config> diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index e061455acbe6b..3a0d3e50acc5a 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -338,15 +338,26 @@ </group> <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Images Upload Configuration</label> - <field id="max_width" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="enable_resize" translate="label" type="select" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Enable Front-end Resize</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <comment>Resize performed by javascript during file upload.</comment> + </field> + <field id="max_width" translate="label comment" type="text" sortOrder="300" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Width</label> <validate>validate-greater-than-zero validate-number required-entry</validate> <comment>Maximum allowed width for uploaded image.</comment> + <depends> + <field id="enable_resize">1</field> + </depends> </field> - <field id="max_height" translate="label comment" type="text" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="max_height" translate="label comment" type="text" sortOrder="400" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Height</label> <validate>validate-greater-than-zero validate-number required-entry</validate> <comment>Maximum allowed height for uploaded image.</comment> + <depends> + <field id="enable_resize">1</field> + </depends> </field> </group> </section> diff --git a/app/code/Magento/Backend/etc/config.xml b/app/code/Magento/Backend/etc/config.xml index 45d283ad3ff22..8283fa18dd370 100644 --- a/app/code/Magento/Backend/etc/config.xml +++ b/app/code/Magento/Backend/etc/config.xml @@ -29,6 +29,7 @@ <enable_charts>1</enable_charts> </dashboard> <upload_configuration> + <enable_resize>1</enable_resize> <max_width>1920</max_width> <max_height>1200</max_height> </upload_configuration> diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index 966372773f295..edd54ae38b6a1 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -14,7 +14,8 @@ "Magento_Backend/js/media-uploader" : { "maxFileSize": <?= /* @escapeNotVerified */ $block->getFileSizeService()->getMaxFileSize() ?>, "maxWidth":<?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , - "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?> + "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?>, + "isResizeEnabled": <?= /* @noEscape */ $block->getIsResizeEnabled() ?> } }' > diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 7e0b6bdfb46dd..35e9ec244df24 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -35,7 +35,10 @@ define([ _create: function () { var self = this, - progressTmpl = mageTemplate('[data-template="uploader"]'); + progressTmpl = mageTemplate('[data-template="uploader"]'), + resizeConfig = { + action: 'resize' + }; this.element.find('input[type=file]').fileupload({ dataType: 'json', @@ -120,14 +123,19 @@ define([ stop: fileUploader.uploaderConfig.stop }); + if (typeof this.options.isResizeEnabled !== 'undefined' && this.options.isResizeEnabled === true) { + resizeConfig.maxWidth = this.options.maxWidth; + resizeConfig.maxHeight = this.options.maxHeight; + } + this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: this.options.maxFileSize - }, { - action: 'resize' - }, { + }, + resizeConfig, + { action: 'save' }] }); diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 9a6787ddbaffd..0785177042451 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -140,14 +140,14 @@ class Uploader * @deprecated * @see \Magento\Framework\Image\Adapter\UploadConfigInterface::getMaxWidth() */ - const MAX_IMAGE_WIDTH = 4096; + const MAX_IMAGE_WIDTH = 1920; /** * Maximum Image Height resolution in pixels. For image resizing on client side * @deprecated * @see \Magento\Framework\Image\Adapter\UploadConfigInterface::getMaxHeight() */ - const MAX_IMAGE_HEIGHT = 2160; + const MAX_IMAGE_HEIGHT = 1200; /** * Resulting of uploaded file diff --git a/lib/internal/Magento/Framework/Image/Adapter/Config.php b/lib/internal/Magento/Framework/Image/Adapter/Config.php index a159bc9ffd448..84b6b6dcfbdd1 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Config.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Config.php @@ -16,8 +16,16 @@ class Config implements ConfigInterface, UploadConfigInterface const XML_PATH_IMAGE_ADAPTERS = 'dev/image/adapters'; + /** + * Config path for the maximal image width value + * @deprecated + */ const XML_PATH_MAX_WIDTH_IMAGE = 'system/upload_configuration/max_width'; + /** + * Config path for the maximal image height value + * @deprecated + */ const XML_PATH_MAX_HEIGHT_IMAGE = 'system/upload_configuration/max_height'; /** @@ -57,6 +65,8 @@ public function getAdapters() * Get Maximum Image Width resolution in pixels. For image resizing on client side. * * @return int + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() */ public function getMaxWidth(): int { @@ -67,6 +77,8 @@ public function getMaxWidth(): int * Get Maximum Image Height resolution in pixels. For image resizing on client side. * * @return int + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() */ public function getMaxHeight(): int { diff --git a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php index c42879060b0b2..990062b83ef6f 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php @@ -9,6 +9,8 @@ /** * Interface UploadConfigInterface + * @deprecated because new interface was introduced + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface; */ interface UploadConfigInterface { From cad023ddcb808eee009a0e1addbe6ba2ce80cbdd Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Wed, 3 Oct 2018 13:53:13 +0300 Subject: [PATCH 0312/1415] MAGETWO-56094: Header issue when resizing in Internet Explorer - Fixed css styles for page-actions div elements --- .../Magento_Backend/web/css/source/module/main/_actions-bar.less | 1 - 1 file changed, 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less index 07050c1e5111d..08434727ccc9c 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_actions-bar.less @@ -44,7 +44,6 @@ .page-actions { @_page-action__indent: 1.3rem; - float: right; .page-main-actions & { &._fixed { From e5a30aab22728751c8a79a1d0062f4e2206766e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 3 Oct 2018 14:32:22 +0300 Subject: [PATCH 0313/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Backend/Block/Media/Uploader.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 6962141c465b8..1995d72661e2e 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -62,7 +62,8 @@ public function __construct( ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); - $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); + $this->imageUploadConfig = $imageUploadConfig + ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); parent::__construct($context, $data); } From 7547dd2e0a66d66fc0ed1b4dcb2ccd9de792a6b4 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Wed, 3 Oct 2018 15:38:50 +0300 Subject: [PATCH 0314/1415] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Added possibility to retrieve multiselect option values for catalog fulltext search reindexation --- .../Indexer/Fulltext/Action/DataProvider.php | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 83058b6f0ad55..3882921680a42 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -12,6 +12,8 @@ use Magento\Store\Model\Store; /** + * Data provider class + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @api @@ -570,8 +572,8 @@ public function prepareProductIndex($indexData, $productData, $storeId) } } foreach ($indexData as $entityId => $attributeData) { - foreach ($attributeData as $attributeId => $attributeValue) { - $value = $this->getAttributeValue($attributeId, $attributeValue, $storeId); + foreach ($attributeData as $attributeId => $attributeValues) { + $value = $this->getAttributeValue($attributeId, $attributeValues, $storeId); if (!empty($value)) { if (isset($index[$attributeId])) { $index[$attributeId][$entityId] = $value; @@ -602,16 +604,16 @@ public function prepareProductIndex($indexData, $productData, $storeId) * Retrieve attribute source value for search * * @param int $attributeId - * @param mixed $valueId + * @param mixed $valueIds * @param int $storeId * @return string */ - private function getAttributeValue($attributeId, $valueId, $storeId) + private function getAttributeValue($attributeId, $valueIds, $storeId) { $attribute = $this->getSearchableAttribute($attributeId); - $value = $this->engine->processAttributeValue($attribute, $valueId); + $value = $this->engine->processAttributeValue($attribute, $valueIds); if (false !== $value) { - $optionValue = $this->getAttributeOptionValue($attributeId, $valueId, $storeId); + $optionValue = $this->getAttributeOptionValue($attributeId, $valueIds, $storeId); if (null === $optionValue) { $value = $this->filterAttributeValue($value); } else { @@ -626,13 +628,15 @@ private function getAttributeValue($attributeId, $valueId, $storeId) * Get attribute option value * * @param int $attributeId - * @param int $valueId + * @param int|string $valueIds * @param int $storeId * @return null|string */ - private function getAttributeOptionValue($attributeId, $valueId, $storeId) + private function getAttributeOptionValue($attributeId, $valueIds, $storeId) { $optionKey = $attributeId . '-' . $storeId; + $attributeValueIds = explode(',', $valueIds); + $attributeOptionValue = ''; if (!array_key_exists($optionKey, $this->attributeOptions) ) { $attribute = $this->getSearchableAttribute($attributeId); @@ -650,8 +654,10 @@ private function getAttributeOptionValue($attributeId, $valueId, $storeId) $this->attributeOptions[$optionKey] = null; } } - - return $this->attributeOptions[$optionKey][$valueId] ?? null; + foreach ($attributeValueIds as $attrValueId) { + $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + } + return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } /** From 6c03f76e2ede0ec03723f87cf1d4246614bddd85 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Wed, 3 Oct 2018 16:03:50 +0300 Subject: [PATCH 0315/1415] MAGETWO-95491: Product Review "Save and Next" and "Save and Previous" not working --- .../Review/Model/ResourceModel/Review/Product/Collection.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 99c963501a9d4..68dc8d753b5bd 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -406,7 +406,6 @@ public function getResultingIds() $idsSelect->reset(Select::LIMIT_COUNT); $idsSelect->reset(Select::LIMIT_OFFSET); $idsSelect->reset(Select::COLUMNS); - $idsSelect->reset(Select::ORDER); $idsSelect->columns('rt.review_id'); return $this->getConnection()->fetchCol($idsSelect); } From 94ce40832e4c405f22a748ff8445c1b5777589a1 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 3 Oct 2018 17:44:23 +0300 Subject: [PATCH 0316/1415] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed codestyle issue in 'ChildrenUrlRewriteGenerator'; --- .../Model/Category/ChildrenUrlRewriteGenerator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php index f6049bbff02c4..d18034220cfa8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php @@ -71,7 +71,8 @@ public function __construct( public function generate($storeId, Category $category, $rootCategoryId = null) { $mergeDataProvider = clone $this->mergeDataProviderPrototype; - if ($childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true)) { + $childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); + if ($childrenIds) { foreach ($childrenIds as $childId) { /** @var Category $childCategory */ $childCategory = $this->categoryRepository->get($childId, $storeId); From b1b39283c17b718a356f8f16e39815885e096637 Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Wed, 3 Oct 2018 17:04:51 +0200 Subject: [PATCH 0317/1415] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 6add4e8cb3ad1..8756aab1acec3 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,6 @@ public function getHostUrl() $host = 'localhost'; } - // HTTP_X_FORWARDED_PROTO to check whether a webserver using HTTP is behind a load balancer serving HTTPS $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; $url = ($isSecure ? 'https://' : 'http://') . $host; From 53452fbe0dbe96e1ceb3f91973fc88e25c9108ee Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Wed, 3 Oct 2018 17:15:43 +0200 Subject: [PATCH 0318/1415] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 8756aab1acec3..3958c6d152c9d 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,8 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') + || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); $url = ($isSecure ? 'https://' : 'http://') . $host; if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443]) From 56c1e0ebe2eb07d131949a92c61294d42cea7da1 Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Wed, 3 Oct 2018 17:26:29 +0200 Subject: [PATCH 0319/1415] move hardcoded MIME types from class private to DI configuration. --- .../Magento/Catalog/Model/ImageUploader.php | 23 +++++++++++-------- app/code/Magento/Catalog/etc/di.xml | 6 +++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index ce92a2c1d958d..165821920580e 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -67,14 +67,9 @@ class ImageUploader /** * List of allowed image mime types * - * @var array + * @var string[] */ - private $allowedMimeTypes = [ - 'image/jpg', - 'image/jpeg', - 'image/gif', - 'image/png', - ]; + protected $allowedMimeTypes; /** * ImageUploader constructor @@ -96,7 +91,8 @@ public function __construct( \Psr\Log\LoggerInterface $logger, $baseTmpPath, $basePath, - $allowedExtensions + $allowedExtensions, + $allowedMimeTypes ) { $this->coreFileStorageDatabase = $coreFileStorageDatabase; $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); @@ -106,6 +102,7 @@ public function __construct( $this->baseTmpPath = $baseTmpPath; $this->basePath = $basePath; $this->allowedExtensions = $allowedExtensions; + $this->allowedMimeTypes = $allowedMimeTypes; } /** @@ -174,6 +171,14 @@ public function getAllowedExtensions() return $this->allowedExtensions; } + /** + * @return string[] + */ + public function getAllowedMimeTypes() + { + return $this->allowedMimeTypes; + } + /** * Retrieve path * @@ -239,7 +244,7 @@ public function saveFileToTmpDir($fileId) $uploader = $this->uploaderFactory->create(['fileId' => $fileId]); $uploader->setAllowedExtensions($this->getAllowedExtensions()); $uploader->setAllowRenameFiles(true); - if (!$uploader->checkMimeType($this->allowedMimeTypes)) { + if (!$uploader->checkMimeType($this->getAllowedMimeTypes())) { throw new \Magento\Framework\Exception\LocalizedException(__('File validation failed.')); } $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index d12ae8f821e6f..a802496d299b8 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -220,6 +220,12 @@ <item name="gif" xsi:type="string">gif</item> <item name="png" xsi:type="string">png</item> </argument> + <argument name="allowedMimeTypes" xsi:type="array"> + <item name="jpg" xsi:type="string">image/jpg</item> + <item name="jpeg" xsi:type="string">image/jpeg</item> + <item name="gif" xsi:type="string">image/gif</item> + <item name="png" xsi:type="string">image/png</item> + </argument> </arguments> </virtualType> <type name="Magento\Catalog\Controller\Adminhtml\Category\Image\Upload"> From 4be4d0faa5d5f02b4a1c1d5916391cd83d8dd5a5 Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Wed, 3 Oct 2018 17:35:56 +0200 Subject: [PATCH 0320/1415] add missing phpdoc comment --- app/code/Magento/Catalog/Model/ImageUploader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index 165821920580e..6b2604723ccbf 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -82,6 +82,7 @@ class ImageUploader * @param string $baseTmpPath * @param string $basePath * @param string[] $allowedExtensions + * @param string[] $allowedMimeTypes */ public function __construct( \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase, From 24672336afc2a748ab6f221a534f93ff1e894fdd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 3 Oct 2018 18:00:18 +0200 Subject: [PATCH 0321/1415] Concept for setting shipping method only for single address checkout --- .../SetShippingMethodsOnCart.php | 111 +++++++++++------- .../Magento/QuoteGraphQl/etc/schema.graphqls | 5 +- 2 files changed, 71 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 448bdcbb37a6d..f2e1be3bb0508 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -7,44 +7,63 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Exception\StateException; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\ShippingMethodManagementInterface; +use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; +/** + * Class SetShippingMethodsOnCart + * + * Mutation resolver for setting shipping methods for shopping cart + */ class SetShippingMethodsOnCart implements ResolverInterface { - /** - * @var CartRepositoryInterface - */ - private $cartRepository; - /** * @var MaskedQuoteIdToQuoteIdInterface */ private $maskedQuoteIdToQuoteId; - /** * @var ArrayManager */ private $arrayManager; + /** + * @var ShippingMethodManagementInterface + */ + private $shippingMethodManagement; + + /** + * @var IsCartMutationAllowedForCurrentUser + */ + private $isCartMutationAllowedForCurrentUser; + /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param ShippingMethodManagementInterface $shippingMethodManagement */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - CartRepositoryInterface $cartRepository + ShippingMethodManagementInterface $shippingMethodManagement, + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser ) { $this->arrayManager = $arrayManager; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->cartRepository = $cartRepository; + $this->shippingMethodManagement = $shippingMethodManagement; + $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -56,50 +75,56 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $this->arrayManager->get('input/cart_id', $args); if (!$maskedCartId) { - // TODO: throw an exception + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } if (!$shippingMethods) { - // TODO: throw an exception? + throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } - foreach ($shippingMethods as $shippingMethod) { - if (empty($shippingMethod['cart_address_id'])) { - // TODO: throw input exception - } - - if (empty($shippingMethod['shipping_method_code'])) { - // TODO: throw input exception - } + $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping - // TODO: move to a separate class - // TODO: check current customer can apply operations on specified cart + if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here + throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $quote = $this->cartRepository->get($quoteId); // TODO: catch no such entity exception - $this->setShippingMethods($shippingMethods, $quote); + if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here + throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); + } - $quote->collectTotals(); - $quote->save(); - //$this->cartRepository->save($quote); + try { + $cartId = $this->maskedQuoteIdToQuoteId->execute((string) $maskedCartId); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) + ); + } - return 'Success!'; - } + if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { + throw new GraphQlAuthorizationException( + __( + 'The current user cannot perform operations on cart "%masked_cart_id"', + ['masked_cart_id' => $maskedCartId] + ) + ); + } - private function setShippingMethods($shippingMethods, CartInterface $quote) - { - $addresses = $quote->getAllShippingAddresses(); - /** @var \Magento\Quote\Model\Quote\Address $address */ - foreach ($addresses as $address) { - $addressId = $address->getId(); - $shippingMethodForAddress = array_search($addressId, array_column($shippingMethods, 'cart_address_id')); - if ($shippingMethodForAddress !== false) { - $address->setShippingMethod($shippingMethods[$shippingMethodForAddress]['shipping_method_code']); -// $address->setCollectShippingRates(1); - $address->save(); - } + try { + $this->shippingMethodManagement->set( + $cartId, + $shippingMethods['shipping_carrier_code'], + $shippingMethods['shipping_method_code'] + ); + } catch (InputException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (CouldNotSaveException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (StateException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException(__($exception->getMessage())); } - // TODO: make sure that shipping method is assigned for all addresses + + return 'Success!'; // TODO we should return cart here } } \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 8ecb340db691b..45f98daeaed06 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -53,7 +53,8 @@ input SetShippingMethodsOnCartInput { } input ShippingMethodForAddressInput { - cart_address_id: String! # todo: int? + cart_address_id: int + shipping_carrier_code: String! shipping_method_code: String! } @@ -66,7 +67,7 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: String + cart: String #TODO: temp placeholder, should be Cart! } # If no address is provided, the system get address assigned to a quote From c2db6bfeb327802acf8879a64cbe30f7b547f4c2 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Wed, 3 Oct 2018 19:28:28 +0300 Subject: [PATCH 0322/1415] Fixed --- .../Ui/Component/DataProvider/Document.php | 7 +--- .../Model/DataProvider/Suggestions.php | 4 +- app/code/Magento/Store/Model/StoreManager.php | 39 ++++--------------- .../Magento/Framework/Session/SidResolver.php | 2 +- 4 files changed, 10 insertions(+), 42 deletions(-) diff --git a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php index 9180268ac5cc6..468a9e7946f2d 100644 --- a/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php +++ b/app/code/Magento/Customer/Ui/Component/DataProvider/Document.php @@ -94,12 +94,7 @@ public function __construct( } /** - * Get Custom Attribute - * - * @param string $attributeCode - * - * @return \Magento\Framework\Api\AttributeInterface|null - * @throws \Magento\Framework\Exception\LocalizedException + * @inheritdoc */ public function getCustomAttribute($attributeCode) { diff --git a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php index da8a32687535f..c4fab39dfde61 100644 --- a/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php +++ b/app/code/Magento/Elasticsearch/Model/DataProvider/Suggestions.php @@ -121,9 +121,7 @@ public function getItems(QueryInterface $query) } /** - * Is Results Count Enabled - * - * @return bool + * @inheritdoc */ public function isResultsCountEnabled() { diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 79ea0d7408c59..11f9787bf1471 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -205,11 +205,7 @@ public function getStores($withDefault = false, $codeKey = false) } /** - * Retrieve application website object - * - * @param null|bool|int|string|\Magento\Store\Api\Data\WebsiteInterface $websiteId - * @return \Magento\Store\Api\Data\WebsiteInterface - * @throws \Magento\Framework\Exception\LocalizedException + * @inheritdoc */ public function getWebsite($websiteId = null) { @@ -229,11 +225,7 @@ public function getWebsite($websiteId = null) } /** - * Get loaded websites - * - * @param bool $withDefault - * @param bool $codeKey - * @return \Magento\Store\Api\Data\WebsiteInterface[] + * @inheritdoc */ public function getWebsites($withDefault = false, $codeKey = false) { @@ -252,9 +244,7 @@ public function getWebsites($withDefault = false, $codeKey = false) } /** - * Reinitialize store list - * - * @return void + * @inheritdoc */ public function reinitStores() { @@ -267,10 +257,7 @@ public function reinitStores() } /** - * Retrieve default store for default group and website - * - * @return \Magento\Store\Api\Data\StoreInterface|null - * @throws NoSuchEntityException + * @inheritdoc */ public function getDefaultStoreView() { @@ -280,12 +267,7 @@ public function getDefaultStoreView() } /** - * Retrieve application store group object - * - * @param null|\Magento\Store\Api\Data\GroupInterface|string $groupId - * - * @return \Magento\Store\Api\Data\GroupInterface - * @throws NoSuchEntityException + * @inheritdoc */ public function getGroup($groupId = null) { @@ -300,10 +282,7 @@ public function getGroup($groupId = null) } /** - * Prepare array of store groups - * - * @param bool $withDefault - * @return \Magento\Store\Api\Data\GroupInterface[] + * @inheritdoc */ public function getGroups($withDefault = false) { @@ -345,11 +324,7 @@ private function getStoreWebsiteRelation() } /** - * Get assigned to website store - * - * @param int $websiteId - * - * @return array + * @inheritdoc */ public function getStoreByWebsiteId($websiteId) { diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 30d1a96ea4236..1208aeb31eaee 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -176,7 +176,7 @@ public function getUseSessionInUrl() if ($this->_useSessionInUrl === null) { //Using config value by default, can be overridden by using the //setter. - $this->_useSessionInUrl = $this->scopeConfig->getValue( + $this->_useSessionInUrl = $this->scopeConfig->isSetFlag( self::XML_PATH_USE_FRONTEND_SID, $this->_scopeType ); From 75eb9b128cb68707d0e7a45d7b05d79432253f31 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Wed, 3 Oct 2018 19:31:16 +0300 Subject: [PATCH 0323/1415] Fixed --- app/code/Magento/Store/Model/StoreManager.php | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 11f9787bf1471..0fce3a5217058 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -133,9 +133,7 @@ public function setIsSingleStoreModeAllowed($value) } /** - * Check if store has only one store view - * - * @return bool + * @inheritdoc */ public function hasSingleStore() { @@ -144,9 +142,7 @@ public function hasSingleStore() } /** - * Check if system is run in the single store mode - * - * @return bool + * @inheritdoc */ public function isSingleStoreMode() { @@ -154,11 +150,7 @@ public function isSingleStoreMode() } /** - * Retrieve application store object - * - * @param null|string|bool|int|\Magento\Store\Api\Data\StoreInterface $storeId - * @return \Magento\Store\Api\Data\StoreInterface - * @throws NoSuchEntityException If given store doesn't exist. + * @inheritdoc */ public function getStore($storeId = null) { @@ -182,11 +174,7 @@ public function getStore($storeId = null) } /** - * Retrieve stores array - * - * @param bool $withDefault - * @param bool $codeKey - * @return \Magento\Store\Api\Data\StoreInterface[] + * @inheritdoc */ public function getStores($withDefault = false, $codeKey = false) { From b8b6adea3d2f593d9f0c9c2ff926d217dbc7814d Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 3 Oct 2018 09:51:12 -0500 Subject: [PATCH 0324/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel --- .../Adminhtml/Edit/ResetPasswordButton.php | 9 ++++++++- .../view/adminhtml/web/edit/post-wrapper.js | 8 ++++++++ .../Adminhtml/Index/ResetPasswordTest.php | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php index f2d1dd9f0a853..c38f182f275f2 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php @@ -13,6 +13,8 @@ class ResetPasswordButton extends GenericButton implements ButtonProviderInterface { /** + * Retrieve button-specified settings + * * @return array */ public function getButtonData() @@ -23,7 +25,10 @@ public function getButtonData() $data = [ 'label' => __('Reset Password'), 'class' => 'reset reset-password', - 'on_click' => sprintf("location.href = '%s';", $this->getResetPasswordUrl()), + 'data_attribute' => [ + 'url' => $this->getResetPasswordUrl() + ], + 'on_click' => '', 'sort_order' => 60, ]; } @@ -31,6 +36,8 @@ public function getButtonData() } /** + * Get reset password url + * * @return string */ public function getResetPasswordUrl() diff --git a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js index 76b060015c5ff..27fa5eb783bba 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js +++ b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js @@ -44,4 +44,12 @@ define([ return false; }); + + $('#resetPassword').click(function () { + var url = $('#resetPassword').data('url'); + + getForm(url).appendTo('body').submit(); + + return false; + }); }); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php index eaaba639d49a8..8fa77a7388be2 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -43,6 +43,23 @@ public function testResetPasswordSuccess() $this->assertRedirect($this->stringStartsWith($this->baseControllerUrl . 'edit')); } + /** + * Checks reset password functionality cannot be performed with GET request + * + * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0 + * @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0 + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testResetPasswordWithGet() + { + $this->passwordResetRequestEventCreate( + \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST + ); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); + $this->dispatch('backend/customer/index/resetPassword'); + $this->assertEquals('noroute', $this->getRequest()->getControllerName()); + } + /** * Checks reset password functionality with default restrictive min time between * password reset requests and customer reset request event. From c3093ad20aef629a38424da83281840f231d1c9c Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Wed, 3 Oct 2018 21:20:07 +0200 Subject: [PATCH 0325/1415] fix related test --- .../Catalog/Test/Unit/Model/ImageUploaderTest.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php index c989f2dd47462..35a17824b1ddb 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php @@ -69,10 +69,17 @@ class ImageUploaderTest extends \PHPUnit\Framework\TestCase /** * Allowed extensions * - * @var string + * @var array */ private $allowedExtensions; + /** + * Allowed mime types + * + * @var array + */ + private $allowedMimeTypes; + protected function setUp() { $this->coreFileStorageDatabaseMock = $this->createMock( @@ -97,6 +104,7 @@ protected function setUp() $this->baseTmpPath = 'base/tmp/'; $this->basePath = 'base/real/'; $this->allowedExtensions = ['.jpg']; + $this->allowedMimeTypes = ['image/jpg']; $this->imageUploader = new \Magento\Catalog\Model\ImageUploader( @@ -107,7 +115,8 @@ protected function setUp() $this->loggerMock, $this->baseTmpPath, $this->basePath, - $this->allowedExtensions + $this->allowedExtensions, + $this->allowedMimeTypes ); } From 83e0f7fdf69c6c32c8061824ac2e4e85c512adb2 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 27 Sep 2018 14:15:04 -0500 Subject: [PATCH 0326/1415] MC-4063: Flaky MFTF Test: AdminRemoveDefaultImageDownloadableProductTest - Unskipped AdminRemoveDefaultImageDownloadableProductTest --- .../Test/AdminRemoveDefaultImageDownloadableProductTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml index 6e3e7f7d17146..3ee6cef47738b 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml @@ -17,9 +17,6 @@ <severity value="MAJOR"/> <testCaseId value="MC-201"/> <group value="Downloadable"/> - <skip> - <issueId value="MC-4063"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 85cd771b9bffe661e76f5587b2ed935d3097a772 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 3 Oct 2018 14:45:17 -0500 Subject: [PATCH 0327/1415] MAGETWO-95130: CMS block cannot be deleted - Reapplied the changes from the original fix --- .../Cms/Block/Adminhtml/Block/Edit/DeleteButton.php | 6 ++++-- .../Cms/Block/Adminhtml/Page/Edit/DeleteButton.php | 6 ++++-- .../Ui/Component/Listing/Column/BlockActionsTest.php | 1 + .../Unit/Ui/Component/Listing/Column/PageActionsTest.php | 1 + .../Cms/Ui/Component/Listing/Column/BlockActions.php | 9 ++++----- .../Cms/Ui/Component/Listing/Column/PageActions.php | 9 ++++----- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/DeleteButton.php b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/DeleteButton.php index a7410cac64d76..51a9313fdefd2 100644 --- a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/DeleteButton.php +++ b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit/DeleteButton.php @@ -13,7 +13,7 @@ class DeleteButton extends GenericButton implements ButtonProviderInterface { /** - * @return array + * @inheritDoc */ public function getButtonData() { @@ -24,7 +24,7 @@ public function getButtonData() 'class' => 'delete', 'on_click' => 'deleteConfirm(\'' . __( 'Are you sure you want to do this?' - ) . '\', \'' . $this->getDeleteUrl() . '\')', + ) . '\', \'' . $this->getDeleteUrl() . '\', {"data": {}})', 'sort_order' => 20, ]; } @@ -32,6 +32,8 @@ public function getButtonData() } /** + * URL to send delete requests to. + * * @return string */ public function getDeleteUrl() diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/DeleteButton.php b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/DeleteButton.php index 1fc599e4c856a..b434fd3f5d348 100644 --- a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/DeleteButton.php +++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit/DeleteButton.php @@ -13,7 +13,7 @@ class DeleteButton extends GenericButton implements ButtonProviderInterface { /** - * @return array + * @inheritDoc */ public function getButtonData() { @@ -24,7 +24,7 @@ public function getButtonData() 'class' => 'delete', 'on_click' => 'deleteConfirm(\'' . __( 'Are you sure you want to do this?' - ) . '\', \'' . $this->getDeleteUrl() . '\')', + ) . '\', \'' . $this->getDeleteUrl() . '\', {"data": {}})', 'sort_order' => 20, ]; } @@ -32,6 +32,8 @@ public function getButtonData() } /** + * Url to send delete requests to. + * * @return string */ public function getDeleteUrl() diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php index 3dcf6c4a3fce0..3095abef7bbe3 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php @@ -95,6 +95,7 @@ public function testPrepareDataSource() 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title) ], + 'post' => true ] ], ] diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php index b0cc1bf061a48..9b3165a2c5517 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php @@ -70,6 +70,7 @@ public function testPrepareItemsByPageId() 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title) ], + 'post' => true ] ], ] diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php index 60b9f34d29ae6..f68ef35e534f3 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -55,10 +55,7 @@ public function __construct( } /** - * Prepare Data Source - * - * @param array $dataSource - * @return array + * @inheritDoc */ public function prepareDataSource(array $dataSource) { @@ -87,7 +84,8 @@ public function prepareDataSource(array $dataSource) 'confirm' => [ 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title) - ] + ], + 'post' => true ] ]; } @@ -99,6 +97,7 @@ public function prepareDataSource(array $dataSource) /** * Get instance of escaper + * * @return Escaper * @deprecated 101.0.7 */ diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index ea6882e21c85f..26d31456bf61d 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -67,10 +67,7 @@ public function __construct( } /** - * Prepare Data Source - * - * @param array $dataSource - * @return array + * @inheritDoc */ public function prepareDataSource(array $dataSource) { @@ -89,7 +86,8 @@ public function prepareDataSource(array $dataSource) 'confirm' => [ 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title) - ] + ], + 'post' => true ]; } if (isset($item['identifier'])) { @@ -110,6 +108,7 @@ public function prepareDataSource(array $dataSource) /** * Get instance of escaper + * * @return Escaper * @deprecated 101.0.7 */ From ade72ffadf747b9e19edae9473e982d43100e082 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 19 Sep 2018 10:16:13 -0500 Subject: [PATCH 0328/1415] MC-3857: Products Content Type is broken on Dynamic Block page - Added block creation on failed blocked retrieval in product list --- .../Magento/CatalogWidget/Block/Product/ProductsList.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 9a55f981b7607..14bcc3956334d 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -198,6 +198,13 @@ public function getProductPriceHtml( /** @var \Magento\Framework\Pricing\Render $priceRender */ $priceRender = $this->getLayout()->getBlock('product.price.render.default'); + if (!$priceRender) { + $priceRender = $this->getLayout()->createBlock( + \Magento\Framework\Pricing\Render::class, + 'product.price.render.default', + ['data' => ['price_render_handle' => 'catalog_product_prices']] + ); + } $price = ''; if ($priceRender) { From 681654ccc7ccaa8b003a0dc8336da3e087b0b443 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 20 Sep 2018 10:14:01 -0500 Subject: [PATCH 0329/1415] MC-3857: Products Content Type is broken on Dynamic Block page - Removed uneeded conditional from producslist.php --- .../CatalogWidget/Block/Product/ProductsList.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 14bcc3956334d..31edeaae9daba 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -206,14 +206,12 @@ public function getProductPriceHtml( ); } - $price = ''; - if ($priceRender) { - $price = $priceRender->render( - \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE, - $product, - $arguments - ); - } + $price = $priceRender->render( + \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE, + $product, + $arguments + ); + return $price; } From f02eb037a9fe250e3545469a9d412a1f37fa1c21 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 17 Sep 2018 15:20:05 -0500 Subject: [PATCH 0330/1415] MC-4114: There is a modal overlay display on Schedule Update page when trying to add a block using Block Content Type - Removed conditional from _unsetActive to allow overlay z-index to decrease on multiple layers of modal --- app/code/Magento/Ui/view/base/web/js/modal/modal.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js index f016b0dbefd87..c81274337f418 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js @@ -363,14 +363,7 @@ define([ this.modal.data('active', false); if (this.overlay) { - // In cases when one modal is closed but there is another modal open (e.g. admin notifications) - // to avoid collisions between overlay and modal zIndexes - // overlay zIndex is set to be less than modal one - if (this._getVisibleCount() === 1) { - this.overlay.zIndex(this.prevOverlayIndex - 1); - } else { - this.overlay.zIndex(this.prevOverlayIndex); - } + this.overlay.zIndex(this.prevOverlayIndex - 1); } }, From bcd54542e7812deae7b7ada493d8c96c8853d7fb Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 3 Oct 2018 15:54:16 -0500 Subject: [PATCH 0331/1415] MC-4303: Functional tests failure with the installed Dotmailer module --- .../Mftf/Section/BraintreeConfigurationPaymentSection.xml | 1 + .../Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml index d8e1b837a1d1b..d9f2b14a40e2f 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="BraintreeConfigurationPaymentSection"> <element name="creditCart" type="radio" selector="#braintree"/> + <element name="paymentMethodContainer" type="block" selector=".payment-method-braintree"/> <element name="paymentMethod" type="radio" selector="//div[@class='payment-group']//input[contains(@id, 'braintree_cc_vault_')]"/> <element name="cartFrame" type="iframe" selector="braintree-hosted-field-number"/> <element name="monthFrame" type="iframe" selector="braintree-hosted-field-expirationMonth"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml index 7f6d862ada085..114c79189101a 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -61,10 +61,12 @@ <!--Fill cart data--> <click selector="{{BraintreeConfigurationPaymentSection.creditCart}}" stepKey="SelectBraintreePaymentMethod"/> <waitForPageLoad stepKey="waitForPageLoad3"/> + <scrollTo selector="{{BraintreeConfigurationPaymentSection.creditCart}}" stepKey="ScrollToCreditCardSection"/> <actionGroup ref="StorefrontFillCartDataActionGroup" stepKey="StorefrontFillCartDataActionGroup"/> <waitForPageLoad stepKey="waitForPageLoad4"/> <!--Place order--> - <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="PlaceOrder"/> + <click selector="{{BraintreeConfigurationPaymentSection.paymentMethodContainer}} {{CheckoutPaymentSection.placeOrder}}" + stepKey="PlaceOrder"/> <waitForPageLoad stepKey="waitForPageLoad5"/> <!--Add product to cart again--> From 4bcb4b1436eecd8652714dcab7eb5e84c78f5aee Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Thu, 4 Oct 2018 00:17:35 +0200 Subject: [PATCH 0332/1415] fix integration test --- .../testsuite/Magento/Catalog/Model/ImageUploaderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index 50b40cf4f2efb..04baef55863f2 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -50,6 +50,7 @@ protected function setUp() 'baseTmpPath' => $this->mediaDirectory->getRelativePath('tmp'), 'basePath' => __DIR__, 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] ] ); } From d18a0bffd2a2b81bfb65705e1909f0a9bced5a7e Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Wed, 3 Oct 2018 20:28:18 -0500 Subject: [PATCH 0333/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Optimized media gallery and product options loading --- .../Magento/Catalog/Model/Product/Media/Config.php | 10 +++++++++- .../Model/Resolver/Products/DataProvider/Product.php | 8 ++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Media/Config.php b/app/code/Magento/Catalog/Model/Product/Media/Config.php index 72936d317399c..b01f254b8377b 100644 --- a/app/code/Magento/Catalog/Model/Product/Media/Config.php +++ b/app/code/Magento/Catalog/Model/Product/Media/Config.php @@ -31,6 +31,11 @@ class Config implements ConfigInterface */ private $attributeHelper; + /** + * @var string[] + */ + private $mediaAttributeCodes; + /** * @param StoreManagerInterface $storeManager */ @@ -173,7 +178,10 @@ protected function _prepareFile($file) */ public function getMediaAttributeCodes() { - return $this->getAttributeHelper()->getAttributeCodesByFrontendType('media_image'); + if (!isset($this->mediaAttributeCodes)) { + $this->mediaAttributeCodes = $this->getAttributeHelper()->getAttributeCodesByFrontendType('media_image'); + } + return $this->mediaAttributeCodes; } /** diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index 2c73d7a079170..7f1fd71942253 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -86,8 +86,12 @@ public function getList( $collection->load(); // Methods that perform extra fetches post-load - $collection->addMediaGalleryData(); - $collection->addOptionsToResult(); + if (in_array('media_gallery_entries', $attributes)) { + $collection->addMediaGalleryData(); + } + if (in_array('options', $attributes)) { + $collection->addOptionsToResult(); + } $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); From e0e6de1e8c3f9cdfeec397a7f0c8e4c0f7eaec5b Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Wed, 3 Oct 2018 21:34:05 -0500 Subject: [PATCH 0334/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Optimized category data loading for products query --- .../CatalogGraphQl/Model/AttributesJoiner.php | 37 +++++++++++++++---- .../Model/Resolver/Categories.php | 12 ++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php index ebd8671de02fb..d57154c429920 100644 --- a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php +++ b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php @@ -15,6 +15,11 @@ */ class AttributesJoiner { + /** + * @var array + */ + private $queryFields = []; + /** * Join fields attached to field node to collection's select. * @@ -24,17 +29,33 @@ class AttributesJoiner */ public function join(FieldNode $fieldNode, AbstractCollection $collection) : void { - $query = $fieldNode->selectionSet->selections; - - /** @var FieldNode $field */ - foreach ($query as $field) { - if ($field->kind === 'InlineFragment') { - continue; + foreach ($this->getQueryFields($fieldNode) as $field) { + if (!$collection->isAttributeAdded($field)) { + $collection->addAttributeToSelect($field); } + } + } - if (!$collection->isAttributeAdded($field->name->value)) { - $collection->addAttributeToSelect($field->name->value); + /** + * Get an array of queried fields. + * + * @param FieldNode $fieldNode + * @return string[] + */ + public function getQueryFields(FieldNode $fieldNode) + { + if (!isset($this->queryFields[$fieldNode->name->value])) { + $this->queryFields[$fieldNode->name->value] = []; + $query = $fieldNode->selectionSet->selections; + /** @var FieldNode $field */ + foreach ($query as $field) { + if ($field->kind === 'InlineFragment') { + continue; + } + $this->queryFields[$fieldNode->name->value][] = $field->name->value; } } + + return $this->queryFields[$fieldNode->name->value]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index 4326a51f309b1..11614e79bba22 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -107,6 +107,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ foreach ($this->collection as $item) { if (in_array($item->getId(), $categoryIds)) { + + // Try to extract all requested fields from the loaded collection data + $categories[$item->getId()] = $item->getData(); + $categories[$item->getId()]['id'] = $item->getId(); + $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); + $extractedFields = array_keys($categories[$item->getId()]); + $foundFields = array_intersect($requestedFields, $extractedFields); + if (count($requestedFields) === count($foundFields)) { + continue; + } + + // If not all requested fields were extracted from the collection, start more complex extraction $categories[$item->getId()] = $this->dataObjectProcessor->buildOutputDataArray( $item, CategoryInterface::class From 56092f48f02eed6b0da7220601f62722c2402489 Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Mon, 20 Aug 2018 11:45:03 +0300 Subject: [PATCH 0335/1415] ConfigurableProduct module fixes - Add feature to show price of customized product in select on product page --- .../view/frontend/web/js/configurable.js | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 8cabe71c17504..6f83072f0afc4 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -360,7 +360,12 @@ define([ index = 1, allowedProducts, i, - j; + j, + basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount), + optionPriceLabel, + optionFinalPrice, + optionPriceDiff, + optionPrices = this.options.spConfig.optionPrices; this._clearSelect(element); element.options[0] = new Option('', ''); @@ -374,6 +379,8 @@ define([ if (options) { for (i = 0; i < options.length; i++) { allowedProducts = []; + optionPriceLabel = ''; + optionPriceDiff = 0; /* eslint-disable max-depth */ if (prevConfig) { @@ -387,6 +394,19 @@ define([ } } else { allowedProducts = options[i].products.slice(0); + if (typeof allowedProducts[0] !== "undefined" + && typeof optionPrices[allowedProducts[0]] !== "undefined") { + + optionFinalPrice = parseFloat(optionPrices[allowedProducts[0]].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + + if (optionPriceDiff !== 0) { + options[i].label = options[i].label + ' ' + priceUtils.formatPrice( + optionPriceDiff, + this.options.priceFormat, + 1); + } + } } if (allowedProducts.length > 0) { @@ -394,7 +414,7 @@ define([ element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id); if (typeof options[i].price !== 'undefined') { - element.options[index].setAttribute('price', options[i].prices); + element.options[index].setAttribute('price', options[i].price); } element.options[index].config = options[i]; From fccb34131da0f03ea1fd355aa183b9e27c22b6ff Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Mon, 20 Aug 2018 12:33:10 +0300 Subject: [PATCH 0336/1415] ConfigurableProduct module fixes - Fix isShowSign parameter passing that adds "+" or "-" to the option. Previously there was a bug because this parameter should be boolean. --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 6f83072f0afc4..37f938338c9ed 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -404,7 +404,7 @@ define([ options[i].label = options[i].label + ' ' + priceUtils.formatPrice( optionPriceDiff, this.options.priceFormat, - 1); + true); } } } From 9b34db4ecc7cd42f480648d9fb1b4c5b8e5f75b6 Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Mon, 20 Aug 2018 13:31:25 +0300 Subject: [PATCH 0337/1415] ConfigurableProduct module fixes - Remove unused variable --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 37f938338c9ed..7fc26b8efdcee 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -362,7 +362,6 @@ define([ i, j, basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount), - optionPriceLabel, optionFinalPrice, optionPriceDiff, optionPrices = this.options.spConfig.optionPrices; @@ -379,7 +378,6 @@ define([ if (options) { for (i = 0; i < options.length; i++) { allowedProducts = []; - optionPriceLabel = ''; optionPriceDiff = 0; /* eslint-disable max-depth */ From 149f54549466a0e58cb11c35ea7daf21bc22133c Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Mon, 20 Aug 2018 13:44:30 +0300 Subject: [PATCH 0338/1415] ConfigurableProduct module fixes - Fix code style errors --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 7fc26b8efdcee..8a8514f3c9cf4 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -392,8 +392,9 @@ define([ } } else { allowedProducts = options[i].products.slice(0); - if (typeof allowedProducts[0] !== "undefined" - && typeof optionPrices[allowedProducts[0]] !== "undefined") { + + if (typeof allowedProducts[0] !== 'undefined' + && typeof optionPrices[allowedProducts[0]] !== 'undefined') { optionFinalPrice = parseFloat(optionPrices[allowedProducts[0]].finalPrice.amount); optionPriceDiff = optionFinalPrice - basePrice; From 0fd2fe91da18898c3a5276a5be59042f27869fb4 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 21 Aug 2018 11:38:29 +0300 Subject: [PATCH 0339/1415] magento/magento2#17695 ConfigurableProduct show prices in select options Fix js static test failure --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 8a8514f3c9cf4..6b6c1762fadd9 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -393,8 +393,8 @@ define([ } else { allowedProducts = options[i].products.slice(0); - if (typeof allowedProducts[0] !== 'undefined' - && typeof optionPrices[allowedProducts[0]] !== 'undefined') { + if (typeof allowedProducts[0] !== 'undefined' && + typeof optionPrices[allowedProducts[0]] !== 'undefined') { optionFinalPrice = parseFloat(optionPrices[allowedProducts[0]].finalPrice.amount); optionPriceDiff = optionFinalPrice - basePrice; From 1e3728050a4236827bf65a52fd1dfc8e759d1c59 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 4 Oct 2018 10:24:24 +0300 Subject: [PATCH 0340/1415] MAGETWO-88654: Sales Rule Widget Label --- .../SalesRule/Block/Adminhtml/Promo/Widget/Chooser.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Widget/Chooser.php b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Widget/Chooser.php index b4be904223aac..901866d52f73f 100644 --- a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Widget/Chooser.php +++ b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Widget/Chooser.php @@ -3,8 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\SalesRule\Block\Adminhtml\Promo\Widget; +/** + * Widget that allows to select a sales rule. + */ class Chooser extends \Magento\Backend\Block\Widget\Grid\Extended { /** @@ -87,7 +91,7 @@ public function prepareElementHtml(\Magento\Framework\Data\Form\Element\Abstract if ($element->getValue()) { $rule = $this->ruleFactory->create()->load((int)$element->getValue()); if ($rule->getId()) { - $chooser->setLabel($rule->getName()); + $chooser->setLabel($this->escapeHtml($rule->getName())); } } From ac06b7ef3252c37b001f2a3f5d15f01a908a5e0f Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Thu, 4 Oct 2018 09:45:15 +0200 Subject: [PATCH 0341/1415] fix phpcbf errors --- app/code/Magento/Catalog/Model/ImageUploader.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index 6b2604723ccbf..13cfa4a98ca53 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -163,7 +163,7 @@ public function getBasePath() } /** - * Retrieve base path + * Retrieve allowed extensions * * @return string[] */ @@ -173,6 +173,8 @@ public function getAllowedExtensions() } /** + * Retrieve allowed mime types + * * @return string[] */ public function getAllowedMimeTypes() From 69f948a64c8b54db43a0a04b9fcfd5af1557bab5 Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Thu, 4 Oct 2018 09:59:28 +0200 Subject: [PATCH 0342/1415] solve @orlangur requests. --- app/code/Magento/Catalog/Model/ImageUploader.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index 13cfa4a98ca53..b2f968553887c 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -69,7 +69,7 @@ class ImageUploader * * @var string[] */ - protected $allowedMimeTypes; + private $allowedMimeTypes; /** * ImageUploader constructor @@ -172,16 +172,6 @@ public function getAllowedExtensions() return $this->allowedExtensions; } - /** - * Retrieve allowed mime types - * - * @return string[] - */ - public function getAllowedMimeTypes() - { - return $this->allowedMimeTypes; - } - /** * Retrieve path * @@ -247,7 +237,7 @@ public function saveFileToTmpDir($fileId) $uploader = $this->uploaderFactory->create(['fileId' => $fileId]); $uploader->setAllowedExtensions($this->getAllowedExtensions()); $uploader->setAllowRenameFiles(true); - if (!$uploader->checkMimeType($this->getAllowedMimeTypes())) { + if (!$uploader->checkMimeType($this->allowedMimeTypes)) { throw new \Magento\Framework\Exception\LocalizedException(__('File validation failed.')); } $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath)); From 24e17f6e37f02278b58104a3996ef07f17b52cc3 Mon Sep 17 00:00:00 2001 From: Milan Osztromok <tufa@polisys.hu> Date: Thu, 4 Oct 2018 10:17:00 +0200 Subject: [PATCH 0343/1415] fix failed unit test --- app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php index 35a17824b1ddb..6552e85440008 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ImageUploaderTest.php @@ -104,7 +104,7 @@ protected function setUp() $this->baseTmpPath = 'base/tmp/'; $this->basePath = 'base/real/'; $this->allowedExtensions = ['.jpg']; - $this->allowedMimeTypes = ['image/jpg']; + $this->allowedMimeTypes = ['image/jpg', 'image/jpeg', 'image/gif', 'image/png']; $this->imageUploader = new \Magento\Catalog\Model\ImageUploader( From b6dcb9f71084aca48488ff070fd03ec30157ac70 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Thu, 4 Oct 2018 12:01:16 +0200 Subject: [PATCH 0344/1415] MC-4014: PageBuilder Performance Is Bad With Minimal Content - Update dom-observer to allow for certain nodes to be ignored --- .../web/js/lib/view/utils/dom-observer.js | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js index 4590af4f2d635..03012918f4a0d 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js @@ -12,7 +12,8 @@ define([ var counter = 1, watchers, - globalObserver; + globalObserver, + disabledNodes = []; watchers = { selectors: {}, @@ -238,11 +239,58 @@ define([ }; } + /** + * Verify if the DOM node is a child of a defined disabled node, if so we shouldn't observe provided mutation. + * + * @param {Object} mutation - a single mutation + * @returns {Boolean} + */ + function shouldObserveMutation(mutation) { + var isDisabled; + + if (disabledNodes.length > 0) { + // Iterate through the disabled nodes and determine if this mutation is occurring inside one of them + isDisabled = _.find(disabledNodes, function (node) { + return node === mutation.target || $.contains(node, mutation.target); + }); + + // If we find a matching node we should not observe the mutation + return !isDisabled; + } + + return true; + } + + /** + * Should we observe these mutations? Check the first and last mutation to determine if this is a disabled mutation, + * we check both the first and last in case one has been removed from the DOM during the process of the mutation. + * + * @param {Array} mutations - An array of mutation records. + * @returns {Boolean} + */ + function shouldObserveMutations(mutations) { + var firstMutation, + lastMutation; + + if (mutations.length > 0) { + firstMutation = mutations[0]; + lastMutation = mutations[mutations.length - 1]; + + return shouldObserveMutation(firstMutation) && shouldObserveMutation(lastMutation); + } + + return true; + } + globalObserver = new MutationObserver(function (mutations) { - var changes = formChangesLists(mutations); + var changes; + + if (shouldObserveMutations(mutations)) { + changes = formChangesLists(mutations); - changes.removed.forEach(processRemoved); - changes.added.forEach(processAdded); + changes.removed.forEach(processRemoved); + changes.added.forEach(processAdded); + } }); globalObserver.observe(document.body, { @@ -251,6 +299,16 @@ define([ }); return { + /** + * Disable a node from being observed by the mutations, you may want to disable specific aspects of the + * application which are heavy on DOM changes. The observer running on some actions could cause significant + * delays and degrade the performance of that specific part of the application exponentially. + * + * @param {HTMLElement} node - a HTML node within the document + */ + disableNode: function (node) { + disabledNodes.push(node); + }, /** * Adds listener for the appearance of nodes that matches provided From ce0cb8c76c31545d3527243cbef1bd77947caf49 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Thu, 4 Oct 2018 13:39:59 +0300 Subject: [PATCH 0345/1415] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Fix statics. --- app/code/Magento/GiftMessage/Block/Message/Inline.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index f44f967cefdc6..4a9311c1b4ba2 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -139,7 +139,7 @@ public function getType() /** * Define checkout type * - * @param $type string + * @param string $type * @return $this * @codeCoverageIgnore */ @@ -278,6 +278,8 @@ public function countItems() } /** + * Call method getItemsHasMessages + * * @deprecated Misspelled method * @see getItemsHasMessages */ From 420ab7ef10211a2e1664d55b8445f3c39659643c Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Thu, 4 Oct 2018 14:00:02 +0300 Subject: [PATCH 0346/1415] MAGETWO-91699: Displaying of error messages in a customer account is broken --- .../Customer/Controller/Account/EditPost.php | 17 +++++++++++++---- .../Magento/Customer/Controller/AccountTest.php | 6 +++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php index e3b3d8345224e..38bc52eac4266 100644 --- a/app/code/Magento/Customer/Controller/Account/EditPost.php +++ b/app/code/Magento/Customer/Controller/Account/EditPost.php @@ -22,6 +22,7 @@ use Magento\Customer\Model\CustomerExtractor; use Magento\Customer\Model\Session; use Magento\Framework\App\Action\Context; +use Magento\Framework\Escaper; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\InvalidEmailOrPasswordException; use Magento\Framework\Exception\State\UserLockedException; @@ -79,6 +80,11 @@ class EditPost extends AbstractAccount implements CsrfAwareActionInterface, Http */ private $customerMapper; + /** + * @var Escaper + */ + private $escaper; + /** * @param Context $context * @param Session $customerSession @@ -86,6 +92,7 @@ class EditPost extends AbstractAccount implements CsrfAwareActionInterface, Http * @param CustomerRepositoryInterface $customerRepository * @param Validator $formKeyValidator * @param CustomerExtractor $customerExtractor + * @param Escaper|null $escaper */ public function __construct( Context $context, @@ -93,7 +100,8 @@ public function __construct( AccountManagementInterface $customerAccountManagement, CustomerRepositoryInterface $customerRepository, Validator $formKeyValidator, - CustomerExtractor $customerExtractor + CustomerExtractor $customerExtractor, + ?Escaper $escaper = null ) { parent::__construct($context); $this->session = $customerSession; @@ -101,6 +109,7 @@ public function __construct( $this->customerRepository = $customerRepository; $this->formKeyValidator = $formKeyValidator; $this->customerExtractor = $customerExtractor; + $this->escaper = $escaper ?: ObjectManager::getInstance()->get(Escaper::class); } /** @@ -196,7 +205,7 @@ public function execute() $this->messageManager->addSuccess(__('You saved the account information.')); return $resultRedirect->setPath('customer/account'); } catch (InvalidEmailOrPasswordException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); } catch (UserLockedException $e) { $message = __( 'The account sign-in was incorrect or your account is disabled temporarily. ' @@ -207,9 +216,9 @@ public function execute() $this->messageManager->addError($message); return $resultRedirect->setPath('customer/account/login'); } catch (InputException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); foreach ($e->getErrors() as $error) { - $this->messageManager->addError($error->getMessage()); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); } } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 921fa81fa6f23..eb06d8d5d66bf 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -606,7 +606,7 @@ public function testMissingDataEditPostAction() $this->assertRedirect($this->stringContains('customer/account/edit/')); $this->assertSessionMessages( - $this->equalTo(['"Email" is not a valid email address.']), + $this->equalTo(['"Email" is not a valid email address.']), MessageInterface::TYPE_ERROR ); } @@ -637,7 +637,7 @@ public function testWrongPasswordEditPostAction() $this->assertRedirect($this->stringContains('customer/account/edit/')); // Not sure if its the most secure message. Not changing the behavior for now in the new AccountManagement APIs. $this->assertSessionMessages( - $this->equalTo(["The password doesn't match this account. Verify the password and try again."]), + $this->equalTo(["The password doesn't match this account. Verify the password and try again."]), MessageInterface::TYPE_ERROR ); } @@ -665,7 +665,7 @@ public function testWrongConfirmationEditPostAction() $this->assertRedirect($this->stringContains('customer/account/edit/')); $this->assertSessionMessages( - $this->equalTo(['Password confirmation doesn\'t match entered password.']), + $this->equalTo(['Password confirmation doesn't match entered password.']), MessageInterface::TYPE_ERROR ); } From ef8f126056b004cea86c5ce726794844e969f848 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 4 Oct 2018 15:15:11 +0300 Subject: [PATCH 0347/1415] graph-ql: concept of shipping address coverage, added separate flows for multi shipping and single shipping --- .../MultiShipping.php | 23 ++++ .../SingleShipping.php | 63 ++++++++++ .../SetShippingAddressesOnCart.php | 109 ++++++++++++------ 3 files changed, 162 insertions(+), 33 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php new file mode 100644 index 0000000000000..71560a26c03ee --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php @@ -0,0 +1,23 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; + +class MultiShipping +{ + /** + * @param int $cartId + * @param array $cartItems + * @param int|null $customerAddressId + * @param array|null $address + * @return void + */ + public function setAddress(int $cartId, array $cartItems, ?int $customerAddressId, ?array $address): void + { + //TODO: implement multi shipping + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php new file mode 100644 index 0000000000000..536a907541b1a --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php @@ -0,0 +1,63 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; + +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\Customer\Api\AddressRepositoryInterface; + +class SingleShipping +{ + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + + /** + * @var Address + */ + private $addressModel; + + /** + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param AddressRepositoryInterface $addressRepository + * @param Address $addressModel + */ + public function __construct( + ShippingAddressManagementInterface $shippingAddressManagement, + AddressRepositoryInterface $addressRepository, + Address $addressModel + ) { + $this->shippingAddressManagement = $shippingAddressManagement; + $this->addressRepository = $addressRepository; + $this->addressModel = $addressModel; + } + + /** + * @param int $cartId + * @param int|null $customerAddressId + * @param array|null $address + * @return void + */ + public function setAddress(int $cartId, ?int $customerAddressId, ?array $address): void + { + if($customerAddressId) { + $customerAddress = $this->addressRepository->getById($customerAddressId); + $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); + } else { + $shippingAddress = $this->addressModel->addData($address); + } + + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php index 9d54792136367..f3960f66d2792 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -7,15 +7,15 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; -use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\SingleShipping; /** * @inheritdoc @@ -23,48 +23,49 @@ class SetShippingAddressesOnCart implements ResolverInterface { /** - * @var ShippingAddressManagementInterface + * @var DataObjectHelper */ - private $shippingAddressManagement; + private $dataObjectHelper; /** - * @var AddressRepositoryInterface + * @var MaskedQuoteIdToQuoteIdInterface */ - private $addressRepository; + private $maskedQuoteIdToQuoteId; /** - * @var Address + * @var MultiShipping */ - private $addressModel; + private $multiShipping; + /** - * @var DataObjectHelper + * @var SingleShipping */ - private $dataObjectHelper; + private $singleShipping; /** - * @var MaskedQuoteIdToQuoteIdInterface + * @var ShippingAddressManagementInterface */ - private $maskedQuoteIdToQuoteId; + private $shippingAddressManagement; /** - * @param ShippingAddressManagementInterface $shippingAddressManagement - * @param AddressRepositoryInterface $addressRepository - * @param Address $addressModel * @param DataObjectHelper $dataObjectHelper * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param MultiShipping $multiShipping + * @param SingleShipping $singleShipping + * @param ShippingAddressManagementInterface $shippingAddressManagement */ public function __construct( - ShippingAddressManagementInterface $shippingAddressManagement, - AddressRepositoryInterface $addressRepository, - Address $addressModel, DataObjectHelper $dataObjectHelper, - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + MultiShipping $multiShipping, + SingleShipping $singleShipping, + ShippingAddressManagementInterface $shippingAddressManagement ) { - $this->shippingAddressManagement = $shippingAddressManagement; - $this->addressRepository = $addressRepository; - $this->addressModel = $addressModel; $this->dataObjectHelper = $dataObjectHelper; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->multiShipping = $multiShipping; + $this->singleShipping = $singleShipping; + $this->shippingAddressManagement = $shippingAddressManagement; } /** @@ -78,7 +79,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $args['input']['cart_id']; $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $customerAddressId = $args['input']['customer_address_id'] ?? 0; + $customerAddressId = $args['input']['customer_address_id'] ?? null; $address = $args['input']['address'] ?? null; $cartItems = $args['input']['cart_items'] ?? []; @@ -86,19 +87,61 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__('Query should contain either address id or address input.')); } + //TODO: how to determine whether is multi shipping or not if (!$cartItems) { - if($customerAddressId) { - $customerAddress = $this->addressRepository->getById($customerAddressId); - $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); - $this->shippingAddressManagement->assign($cartId, $shippingAddress); - } else { - $shippingAddress = $this->addressModel->addData($address); - $this->shippingAddressManagement->assign($cartId, $shippingAddress); - } + //TODO: assign cart items + $this->singleShipping->setAddress($cartId, $customerAddressId, $address); } else { - //TODO: implement multi shipping address assign flow + $this->multiShipping->setAddress($cartId, $cartItems, $customerAddressId, $address); } - return []; + //TODO: implement Cart object in the separate resolver + $shippingAddress = $this->shippingAddressManagement->get($cartId); + return [ + 'cart' => [ + 'applied_coupon' => [ + 'code' => '' + ], + 'addresses' => [[ + 'firstname' => $shippingAddress->getFirstname(), + 'lastname' => $shippingAddress->getLastname(), + 'company' => $shippingAddress->getCompany(), + 'street' => $shippingAddress->getStreet(), + 'city' => $shippingAddress->getCity(), + 'region' => [ + 'code' => $shippingAddress->getRegionCode(), + 'label' => $shippingAddress->getRegion() + ], + 'country' => [ + 'code' => $shippingAddress->getCountryId(), + 'label' => '' + ], + 'postcode' => $shippingAddress->getPostcode(), + 'telephone' => $shippingAddress->getTelephone(), + 'address_type' => 'SHIPPING', + 'selected_shipping_method' => [ + 'code' => 'test', + 'label' => 'test', + 'free_shipping' => 'test', + 'error_message' => 'test' + ], + 'available_shipping_methods' => [[ + 'code' => 'test', + 'label' => 'test', + 'free_shipping' => 'test', + 'error_message' => 'test' + ]], + 'items_weight' => [0], + 'customer_notes' => $shippingAddress->getLastname(), + 'cart_items' => [[ + 'cart_item_id' => '', + 'quantity' => 0 + ]], + 'applied_coupon' => [ + 'code' => '' + ] + ]] + ] + ]; } } From e7c2ddcfbfa9668c0a7d8c8706892740add84c5d Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Thu, 4 Oct 2018 16:12:11 +0300 Subject: [PATCH 0348/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix elements arrangement issue --- .../adminhtml/web/css/grouped-product.css | 13 +++++-- .../adminhtml/web/js/grouped-product-grid.js | 34 +++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index cd0aa25ae1f88..9142eaf90899e 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -67,9 +67,8 @@ text-overflow: ellipsis; } - .position { - width:90px; + width: 100px; } .icon-rearrange-position > span { @@ -91,6 +90,11 @@ speak: none; } +.position > * { + float: left; + margin: 3px; +} + .position-widget-input { text-align: center; width: 40px; @@ -103,3 +107,8 @@ .icon-backward:before { content: '\e619'; } + +.icon-rearrange-position, .icon-rearrange-position:hover { + color: #d9d9d9; + text-decoration: none; +} diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 7c9563bb1a0ce..c1a35cb0afede 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -36,7 +36,17 @@ define([ * @param position */ shiftNextPagesPositions: function (position) { - console.log("todo: shifting positions to right on next pages related data"); + var recordData = this.recordData(); + if (~~this.currentPage() === this.pages()) { + return false; + } else { + var startIndex = ~~this.currentPage() * this.pageSize, + offset = position - startIndex + 1; + for (var index = startIndex; index < recordData.length; index++) { + recordData[index].position = index + offset; + } + this.recordData(recordData); + } }, @@ -47,30 +57,36 @@ define([ * @param event */ updateGridPosition: function (data, event) { - var inputValue = ~~event.target.value, + var inputValue = parseInt(event.target.value), recordData = this.recordData(), record, + previousValue, updatedRecord; record = this.elems().find(function (obj) { return obj.dataScope === data.parentScope - }).data(); + }); - if (inputValue === ~~record.positionCalculated) { + previousValue = this.getCalculatedPosition(record); + + if (isNaN(inputValue) || inputValue < 0 || inputValue === previousValue) { return false; } this.elems([]); - updatedRecord = this.getUpdatedRecordIndex(recordData, record.id); + updatedRecord = this.getUpdatedRecordIndex(recordData, record.data().id); if (inputValue >= this.recordData().size() - 1) { recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; } else { - recordData[updatedRecord].position = inputValue; recordData.forEach(function (value, index) { - if (~~value.id !== ~~record.id) { - recordData[index].position = (index !== inputValue) ? index : index + 1; + if (~~value.id === ~~record.data().id) { + recordData[index].position = inputValue; + } else if (inputValue > previousValue && index <= inputValue) { + recordData[index].position = index - 1; + } else if (inputValue < previousValue && index >= inputValue) { + recordData[index].position = index + 1; } }); } @@ -203,7 +219,5 @@ define([ return ~~r.position })); } - - }); }); From 694d2191c74b3ecba27748c11380ee6a70cd3117 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Wed, 3 Oct 2018 12:47:18 +0300 Subject: [PATCH 0349/1415] Fix doc block style --- .../Controller/Rest/Asynchronous/InputParamsResolver.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php index 4ebb23f33e97b..cb72189f6d5c2 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php @@ -80,12 +80,14 @@ public function __construct( /** * Process and resolve input parameters + * * Return array with validated input params * or throw \Exception if at least one request entity params is not valid * * @return array * @throws \Magento\Framework\Exception\InputException if no value is provided for required parameters * @throws \Magento\Framework\Webapi\Exception + * @throws \Magento\Framework\Exception\AuthorizationException */ public function resolve() { @@ -110,6 +112,8 @@ public function resolve() } /** + * Detect route by input parameters + * * @return \Magento\Webapi\Controller\Rest\Router\Route */ public function getRoute() @@ -118,9 +122,10 @@ public function getRoute() } /** + * Resolve parameters for service + * * Convert the input array from key-value format to a list of parameters * suitable for the specified class / method. - * * Instead of \Magento\Webapi\Controller\Rest\InputParamsResolver * we don't need to merge body params with url params and use only body params * From ae03f80da3b6500cf245f06133f528257490852d Mon Sep 17 00:00:00 2001 From: bshevchenko <1408sheva@gmail.com> Date: Thu, 4 Oct 2018 16:50:28 +0300 Subject: [PATCH 0350/1415] MAGETWO-95332: Update price in shopping cart after product save --- .../StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml index 91f9cbf398d24..b4747a6bf7273 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml @@ -30,6 +30,7 @@ <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setDefaultCustomerDataLifetime"/> + <magentoCLI command="indexer:reindex customer_grid" stepKey="reindexCustomerGrid"/> <actionGroup ref="logout" stepKey="logout"/> </after> <!--Go to product page--> From bbbfa0793daab18e1547eeeb986380cbd63f22cb Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Thu, 4 Oct 2018 17:02:41 +0300 Subject: [PATCH 0351/1415] MAGETWO-95171: Filtering Category Products using scope selector --- ...minFilteringCategoryProductsUsingScopeSelectorTest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index 38da50e730d9a..a4bd507d98f55 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -129,7 +129,11 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('Default Store View')}}" stepKey="clickStoreView"/> + <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForModalAccept"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept"/> + <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForNotVisibleModalAccept"/> <waitForPageLoad stepKey="waitForCategoryPageLoad2"/> <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection1"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct1.name$$)}}" @@ -148,8 +152,12 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad3"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('secondStoreView')}}" stepKey="clickStoreView1"/> + <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForModalAccept1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept1"/> + <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForNotVisibleModalAccept1"/> <waitForPageLoad stepKey="waitForCategoryPageLoad4"/> <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection2"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" From 12f668cb28dfc9f657563bb21016bd3ea0c0cee1 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 10:02:42 -0500 Subject: [PATCH 0352/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - Changed implementation of sniff to look for selectors and ignore all else --- .../Magento/Sniffs/Less/AvoidIdSniff.php | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php index f9cec6404dc69..e6e747aed3262 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php +++ b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php @@ -14,7 +14,6 @@ * Ensure that id selector is not used * * @link http://devdocs.magento.com/guides/v2.0/coding-standards/code-standard-less.html#types - * */ class AvoidIdSniff implements Sniff { @@ -26,15 +25,7 @@ class AvoidIdSniff implements Sniff public $supportedTokenizers = [TokenizerSymbolsInterface::TOKENIZER_CSS]; /** - * @var array - */ - private $symbolsBeforeId = [ - TokenizerSymbolsInterface::INDENT_SPACES, - TokenizerSymbolsInterface::NEW_LINE, - ]; - - /** - * {@inheritdoc} + * @inheritdoc */ public function register() { @@ -42,15 +33,56 @@ public function register() } /** - * {@inheritdoc} + * Will flag any selector that looks like the following: + * #foo[bar], + * #foo[bar=bash], + * #foo[bar~=bash], + * #foo[bar$=bash], + * #foo[bar*=bash], + * #foo[bar='bash'], + * #foo:hover, + * #foo:nth-last-of-type(n), + * #foo::before, + * #foo + div, + * #foo > div, + * #foo ~ div, + * #foo\3Abar ~ div, + * #foo\:bar ~ div, + * div#foo { + * blah: 'abc'; + * } + * + * @inheritdoc */ public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - if (T_WHITESPACE === $tokens[$stackPtr - 1]['code'] - && in_array($tokens[$stackPtr - 1]['content'], $this->symbolsBeforeId) - ) { + $nextToken = $phpcsFile->findNext([ + T_HASH, + T_WHITESPACE, + T_STRING_CONCAT, + T_OPEN_PARENTHESIS, + T_CLOSE_PARENTHESIS, + T_OPEN_SQUARE_BRACKET, + T_CLOSE_SQUARE_BRACKET, + T_DOUBLE_QUOTED_STRING, + T_CONSTANT_ENCAPSED_STRING, + T_DOUBLE_COLON, + T_COLON, + T_EQUAL, + T_MUL_EQUAL, + T_STRING, + T_NONE, + T_DOLLAR, + T_GREATER_THAN, + T_PLUS, + T_NS_SEPARATOR, + T_LNUMBER, + ], $stackPtr + 1, null, true); + + // Anything except a { or a , means this is not a selector + if (in_array($tokens[$nextToken]['code'], [T_OPEN_CURLY_BRACKET, T_COMMA])) { $phpcsFile->addError('Id selector is used', $stackPtr, 'IdSelectorUsage'); } } From 929ed778dd4f6157d2ddfbc49289661559d384eb Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 4 Oct 2018 18:07:35 +0300 Subject: [PATCH 0353/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/Block/Media/Uploader.php | 6 +++--- .../adminhtml/templates/media/uploader.phtml | 2 +- .../view/adminhtml/web/js/media-uploader.js | 18 ++++++++++-------- .../templates/browser/content/uploader.phtml | 15 ++++++++++----- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 1995d72661e2e..22e9197418e4c 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -130,11 +130,11 @@ public function getImageUploadMaxHeight() /** * Get image resize configuration * - * @return bool + * @return int */ - public function getIsResizeEnabled(): bool + public function getIsResizeEnabled(): int { - return $this->imageUploadConfig->isResizeEnabled(); + return (int)$this->imageUploadConfig->isResizeEnabled(); } /** diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index edd54ae38b6a1..d6e97cf4d58e3 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -13,7 +13,7 @@ data-mage-init='{ "Magento_Backend/js/media-uploader" : { "maxFileSize": <?= /* @escapeNotVerified */ $block->getFileSizeService()->getMaxFileSize() ?>, - "maxWidth":<?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , + "maxWidth": <?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?>, "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?>, "isResizeEnabled": <?= /* @noEscape */ $block->getIsResizeEnabled() ?> } diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 35e9ec244df24..2a15f5262bda1 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -36,10 +36,17 @@ define([ var self = this, progressTmpl = mageTemplate('[data-template="uploader"]'), - resizeConfig = { - action: 'resize' + isResizeEnabled = this.options.isResizeEnabled, + resizeConfiguration = { + action: 'resize', + maxWidth: this.options.maxWidth, + maxHeight: this.options.maxHeight }; + if (isResizeEnabled === 0) { + resizeConfiguration = {action: 'resize'}; + } + this.element.find('input[type=file]').fileupload({ dataType: 'json', formData: { @@ -123,18 +130,13 @@ define([ stop: fileUploader.uploaderConfig.stop }); - if (typeof this.options.isResizeEnabled !== 'undefined' && this.options.isResizeEnabled === true) { - resizeConfig.maxWidth = this.options.maxWidth; - resizeConfig.maxHeight = this.options.maxHeight; - } - this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: this.options.maxFileSize }, - resizeConfig, + resizeConfiguration, { action: 'save' }] diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 5f4e40667eda5..b1824f639c940 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,6 +17,13 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } +$resizeConfig = ($block->getIsResizeEnabled()) + ? "{action: 'resize', maxWidth: " + . $block->getImageUploadMaxWidth() + . ", maxHeight: " + . $block->getImageUploadMaxHeight() + . "}" + : "{action: 'resize'}"; ?> <div id="<?= $block->getHtmlId() ?>" class="uploader"> @@ -145,11 +152,9 @@ require([ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 - }, { - action: 'resize', - maxWidth: <?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , - maxHeight: <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?> - }, { + }, + <?= /* @noEscape*/ $resizeConfig ?>, + { action: 'save' }] }); From ae9f00c4ace79710fe87da37874102a73e1f5d6e Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 10:10:55 -0500 Subject: [PATCH 0354/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - Added additional selector support and more doc --- .../static/framework/Magento/Sniffs/Less/AvoidIdSniff.php | 3 +++ dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php index e6e747aed3262..f12e2dba6e447 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php +++ b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php @@ -39,6 +39,7 @@ public function register() * #foo[bar~=bash], * #foo[bar$=bash], * #foo[bar*=bash], + * #foo[bar|=bash], * #foo[bar='bash'], * #foo:hover, * #foo:nth-last-of-type(n), @@ -48,6 +49,7 @@ public function register() * #foo ~ div, * #foo\3Abar ~ div, * #foo\:bar ~ div, + * #foo.bar .baz, * div#foo { * blah: 'abc'; * } @@ -72,6 +74,7 @@ public function process(File $phpcsFile, $stackPtr) T_COLON, T_EQUAL, T_MUL_EQUAL, + T_OR_EQUAL, T_STRING, T_NONE, T_DOLLAR, diff --git a/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php index 47d5df331e5cd..82bb2526a9e4a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php @@ -52,7 +52,7 @@ public function testCodeStyle() $codeSniffer->setExtensions([LessWrapper::LESS_FILE_EXTENSION]); - $fileList = PHPCodeTest::getWhitelist([LessWrapper::LESS_FILE_EXTENSION], __DIR__, __DIR__); + $fileList = ['/Users/nathsmit/Sites/pagebuilder/app/myfile.less'];//PHPCodeTest::getWhitelist([LessWrapper::LESS_FILE_EXTENSION], __DIR__, __DIR__); $result = $codeSniffer->run($this->filterFiles($fileList)); From a2d2eb3cd14739ac1c9959be237eaaf3a357853d Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 10:11:59 -0500 Subject: [PATCH 0355/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - Removed test data --- dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php index 82bb2526a9e4a..47d5df331e5cd 100644 --- a/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Less/LiveCodeTest.php @@ -52,7 +52,7 @@ public function testCodeStyle() $codeSniffer->setExtensions([LessWrapper::LESS_FILE_EXTENSION]); - $fileList = ['/Users/nathsmit/Sites/pagebuilder/app/myfile.less'];//PHPCodeTest::getWhitelist([LessWrapper::LESS_FILE_EXTENSION], __DIR__, __DIR__); + $fileList = PHPCodeTest::getWhitelist([LessWrapper::LESS_FILE_EXTENSION], __DIR__, __DIR__); $result = $codeSniffer->run($this->filterFiles($fileList)); From 42c46c1730a1ada0a19bcf31a4a0271d47c096d8 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 11:11:48 -0500 Subject: [PATCH 0356/1415] MAGETWO-87353: \Magento\Cms\Model\BlockTest::testUpdateTime randomly fails on CI - Changed test to only use timestamps from the database for comparison --- .../testsuite/Magento/Cms/Model/BlockTest.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/BlockTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/BlockTest.php index 16331ccde245c..3925975a0f70e 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Model/BlockTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Model/BlockTest.php @@ -7,6 +7,7 @@ use Magento\Cms\Model\ResourceModel\Block; use Magento\Cms\Model\BlockFactory; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Stdlib\DateTime\DateTime; use Magento\Framework\Stdlib\DateTime\Timezone; @@ -82,23 +83,26 @@ public function testGetByIdentifier(array $blockData) */ public function testUpdateTime(array $blockData) { + /** + * @var $db \Magento\Framework\DB\Adapter\AdapterInterface + */ + $db = $this->objectManager->get(\Magento\Framework\App\ResourceConnection::class) + ->getConnection(ResourceConnection::DEFAULT_CONNECTION); # Prepare and save the temporary block - $beforeTimestamp = $this->objectManager->get(DateTime::class)->timestamp(); $tempBlock = $this->blockFactory->create(); $tempBlock->setData($blockData); + $beforeTimestamp = $db->fetchCol('SELECT UNIX_TIMESTAMP()')[0]; $this->blockResource->save($tempBlock); + $afterTimestamp = $db->fetchCol('SELECT UNIX_TIMESTAMP()')[0]; # Load previously created block and compare identifiers $storeId = reset($blockData['stores']); $block = $this->blockIdentifier->execute($blockData['identifier'], $storeId); - $afterTimestamp = $this->objectManager->get(DateTime::class)->timestamp(); $blockTimestamp = strtotime($block->getUpdateTime()); /* - * This test used to fail due to a race condition @see MAGETWO-87353 - * The DB time would be one second older than the check time. The new check allows the DB time - * to be between the test start time and right before the assertion. + * These checks prevent a race condition MAGETWO-87353 */ $this->assertGreaterThanOrEqual($beforeTimestamp, $blockTimestamp); $this->assertLessThanOrEqual($afterTimestamp, $blockTimestamp); From 3bd78c6897fdccf6deb351b4b3510e979bb673a6 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 4 Oct 2018 20:42:45 +0300 Subject: [PATCH 0357/1415] MAGETWO-91650: Translation not working for product alerts - Add foreign key for store table --- app/code/Magento/ProductAlert/etc/db_schema.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index 1d145482ea38f..2b3d9c0db3bc5 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -41,7 +41,7 @@ table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID" - table="product_alert_stock" column="website_id" referenceTable="store" + table="product_alert_stock" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> @@ -82,7 +82,7 @@ table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID" - table="product_alert_stock" column="website_id" referenceTable="store" + table="product_alert_stock" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" From 459834557562947a9959d0486ad6f695b8d79433 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 12:49:49 -0500 Subject: [PATCH 0358/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - CR Feedback --- .../Magento/Sniffs/Less/AvoidIdSniff.php | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php index f12e2dba6e447..49339054f8766 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php +++ b/dev/tests/static/framework/Magento/Sniffs/Less/AvoidIdSniff.php @@ -24,6 +24,35 @@ class AvoidIdSniff implements Sniff */ public $supportedTokenizers = [TokenizerSymbolsInterface::TOKENIZER_CSS]; + /** + * Tokens that can appear in a selector + * + * @var array + */ + private $selectorTokens = [ + T_HASH, + T_WHITESPACE, + T_STRING_CONCAT, + T_OPEN_PARENTHESIS, + T_CLOSE_PARENTHESIS, + T_OPEN_SQUARE_BRACKET, + T_CLOSE_SQUARE_BRACKET, + T_DOUBLE_QUOTED_STRING, + T_CONSTANT_ENCAPSED_STRING, + T_DOUBLE_COLON, + T_COLON, + T_EQUAL, + T_MUL_EQUAL, + T_OR_EQUAL, + T_STRING, + T_NONE, + T_DOLLAR, + T_GREATER_THAN, + T_PLUS, + T_NS_SEPARATOR, + T_LNUMBER, + ]; + /** * @inheritdoc */ @@ -33,6 +62,8 @@ public function register() } /** + * @inheritdoc + * * Will flag any selector that looks like the following: * #foo[bar], * #foo[bar=bash], @@ -53,39 +84,16 @@ public function register() * div#foo { * blah: 'abc'; * } - * - * @inheritdoc */ public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - $nextToken = $phpcsFile->findNext([ - T_HASH, - T_WHITESPACE, - T_STRING_CONCAT, - T_OPEN_PARENTHESIS, - T_CLOSE_PARENTHESIS, - T_OPEN_SQUARE_BRACKET, - T_CLOSE_SQUARE_BRACKET, - T_DOUBLE_QUOTED_STRING, - T_CONSTANT_ENCAPSED_STRING, - T_DOUBLE_COLON, - T_COLON, - T_EQUAL, - T_MUL_EQUAL, - T_OR_EQUAL, - T_STRING, - T_NONE, - T_DOLLAR, - T_GREATER_THAN, - T_PLUS, - T_NS_SEPARATOR, - T_LNUMBER, - ], $stackPtr + 1, null, true); + // Find the next non-selector token + $nextToken = $phpcsFile->findNext($this->selectorTokens, $stackPtr + 1, null, true); // Anything except a { or a , means this is not a selector - if (in_array($tokens[$nextToken]['code'], [T_OPEN_CURLY_BRACKET, T_COMMA])) { + if ($nextToken !== false && in_array($tokens[$nextToken]['code'], [T_OPEN_CURLY_BRACKET, T_COMMA])) { $phpcsFile->addError('Id selector is used', $stackPtr, 'IdSelectorUsage'); } } From d1dfb8dfbfdf590b0786d040a4a05a1ee261a298 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 13 Sep 2018 15:58:54 -0500 Subject: [PATCH 0359/1415] MAGETWO-89738: Sanity job failing on Bamboo PAT build --- .../Indexer/Price/CompositeProductRowSizeEstimatorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php index 1c47644338143..728044b89cafe 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php @@ -49,7 +49,6 @@ protected function setUp() public function testEstimateRowSize() { - $this->markTestSkipped('Unskip after MAGETWO-89738'); $expectedResult = 40000000; $maxRelatedProductCount = 10; From c2fd8e9d47db8080f15f5d3634159c7d0d25d57e Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Thu, 4 Oct 2018 21:36:51 +0300 Subject: [PATCH 0360/1415] Fix test --- .../testsuite/Magento/Framework/Session/SidResolverTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php index e928422528409..e67d9f8ad1846 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php @@ -195,7 +195,7 @@ public function testSetGetUseSessionInUrl($configValue) $this->scopeConfig->expects( $this->any() )->method( - 'getValue' + 'isSetFlag' )->with( \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, \Magento\Store\Model\ScopeInterface::SCOPE_STORE From 6facb56624b2d97bf4c5f793ed49a4d4e32eba7f Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 4 Oct 2018 14:51:05 -0500 Subject: [PATCH 0361/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - Added unit test for sniff --- .../Magento/Sniffs/Less/AvoidIdSniffTest.php | 55 +++++++++++++++++++ .../Sniffs/Less/_files/avoid-ids-errors.txt | 26 +++++++++ .../Magento/Sniffs/Less/_files/avoid-ids.less | 34 ++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/AvoidIdSniffTest.php create mode 100644 dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt create mode 100644 dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/AvoidIdSniffTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/AvoidIdSniffTest.php new file mode 100644 index 0000000000000..ad9e8edd4d1b3 --- /dev/null +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/AvoidIdSniffTest.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Sniffs\Less; + +use Magento\TestFramework\CodingStandard\Tool\CodeSniffer\LessWrapper; + +class AvoidIdSniffTest extends \PHPUnit\Framework\TestCase +{ + /** + * @return array + */ + public function processDataProvider() + { + return [ + [ + 'avoid-ids.less', + 'avoid-ids-errors.txt' + ] + ]; + } + + /** + * @param string $fileUnderTest + * @param string $expectedReportFile + * @dataProvider processDataProvider + */ + public function testProcess($fileUnderTest, $expectedReportFile) + { + $reportFile = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'phpcs_report.txt'; + $wrapper = new LessWrapper(); + $codeSniffer = new \Magento\TestFramework\CodingStandard\Tool\CodeSniffer( + 'Magento', + $reportFile, + $wrapper + ); + $codeSniffer->setExtensions([LessWrapper::LESS_FILE_EXTENSION]); + $result = $codeSniffer->run( + [__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . $fileUnderTest] + ); + // Remove the absolute path to the file from the output + $actual = preg_replace('/^.+\n/', '', ltrim(file_get_contents($reportFile))); + $expected = file_get_contents( + __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . $expectedReportFile + ); + unlink($reportFile); + $this->assertEquals(1, $result); + $this->assertEquals($expected, $actual); + } +} diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt new file mode 100644 index 0000000000000..7ce7bc6de4ad0 --- /dev/null +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt @@ -0,0 +1,26 @@ +--------------------------------------------------------------------------------------------------------------------------------- +FOUND 20 ERRORS AFFECTING 20 LINES +--------------------------------------------------------------------------------------------------------------------------------- + 1 | ERROR | Id selector is used + 2 | ERROR | Id selector is used + 3 | ERROR | Id selector is used + 4 | ERROR | Id selector is used + 5 | ERROR | Id selector is used + 6 | ERROR | Id selector is used + 7 | ERROR | Id selector is used + 8 | ERROR | Id selector is used + 9 | ERROR | Id selector is used + 10 | ERROR | Id selector is used + 11 | ERROR | Id selector is used + 12 | ERROR | Id selector is used + 13 | ERROR | Id selector is used + 14 | ERROR | Id selector is used + 15 | ERROR | Id selector is used + 16 | ERROR | Id selector is used + 17 | ERROR | Id selector is used + 21 | ERROR | Id selector is used + 22 | ERROR | Id selector is used + 23 | ERROR | Id selector is used +--------------------------------------------------------------------------------------------------------------------------------- + + diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less new file mode 100644 index 0000000000000..45eb999c803c7 --- /dev/null +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less @@ -0,0 +1,34 @@ +#foo[bar], +#foo[bar=bash], +#foo[bar~=bash], +#foo[bar$=bash], +#foo[bar*=bash], +#foo[bar|=bash], +#foo[bar='bash'], +#foo:hover, +#foo:nth-last-of-type(n), +#foo::before, +#foo + div, +#foo > div, +#foo ~ div, +#foo\3Abar ~ div, +#foo\:bar ~ div, +#foo.bar .baz, +div#foo { + blah: 'abc'; +} + +.my #foo, +#foo .blah, +.my #foo .blah { + some: 'stuff'; +} +.blah { + #bar .baz(); + .foo #bar .baz(); + #bar .baz(); + + #bar .baz; + .foo #bar .baz; + #bar .baz; +} From e140d29a3e6ec297be4e8fffdfea07bbc521b971 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 14:57:27 -0500 Subject: [PATCH 0362/1415] MAGETWO-89232: Validation error appears if duplicate product twice --- .../Model/Exception/UrlAlreadyExistsException.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php index c7e83819f2569..fdfadc5737af2 100644 --- a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php +++ b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php @@ -8,10 +8,12 @@ use Magento\Framework\Phrase; /** + * Exception for already created url. + * * @api * @since 100.2.0 */ -class UrlAlreadyExistsException extends \Magento\Framework\Exception\LocalizedException +class UrlAlreadyExistsException extends \Magento\Framework\Exception\AlreadyExistsException { /** * @var array @@ -34,6 +36,8 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** + * Returns urls. + * * @return array * @since 100.2.0 */ From ee21cf41a961dc35545518e8b0912feab03b600f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 17:04:13 -0500 Subject: [PATCH 0363/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Magento/Checkout/Model/ShippingInformationManagement.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 381ee2b9015c9..77833711e7f2a 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -151,6 +151,10 @@ public function saveAddressInformation( $address->setCustomerAddressId(null); } + if (!$billingAddress->getCustomerAddressId()) { + $billingAddress->setCustomerAddressId(null); + } + if (!$address->getCountryId()) { throw new StateException(__('The shipping address is missing. Set the address and try again.')); } From 422d24444321f7c5d5f6ae7fe7ec9872e233ba7a Mon Sep 17 00:00:00 2001 From: Logan Stellway <loganstellway@users.noreply.github.com> Date: Thu, 4 Oct 2018 15:36:06 -0700 Subject: [PATCH 0364/1415] Fix for #12969 - server port detection for errors Updates `getHostUrl()` method to reference `HTTP_HOST` rather than `SERVER_PORT`. --- pub/errors/processor.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 7240707f642c2..615a0c0f96ec3 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -268,10 +268,11 @@ public function getHostUrl() $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'); $url = ($isSecure ? 'https://' : 'http://') . $host; - if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443]) + $port = explode(':', $host); + if (isset($port[1]) && !in_array($port[1], [80, 443]) && !preg_match('/.*?\:[0-9]+$/', $url) ) { - $url .= ':' . $_SERVER['SERVER_PORT']; + $url .= ':' . $port[1]; } return $url; } From 84c7cd8478a6d5fa28d59d4c16e0240af309ee05 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 19:51:03 -0500 Subject: [PATCH 0365/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country - fix static tests --- .../Model/ShippingInformationManagement.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 77833711e7f2a..6bd78cecd3a6b 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -19,6 +19,9 @@ use Magento\Framework\App\ObjectManager; /** + * Class ShippingInformationManagement + * + * @package Magento\Checkout\Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInformationManagementInterface @@ -99,8 +102,8 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector - * @param CartExtensionFactory|null $cartExtensionFactory, - * @param ShippingAssignmentFactory|null $shippingAssignmentFactory, + * @param CartExtensionFactory|null $cartExtensionFactory + * @param ShippingAssignmentFactory|null $shippingAssignmentFactory * @param ShippingFactory|null $shippingFactory * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -136,7 +139,14 @@ public function __construct( } /** - * {@inheritDoc} + * Save address information. + * + * @param int $cartId + * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation + * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException */ public function saveAddressInformation( $cartId, @@ -212,6 +222,8 @@ protected function validateQuote(\Magento\Quote\Model\Quote $quote) } /** + * Prepare shipping assignment. + * * @param CartInterface $quote * @param AddressInterface $address * @param string $method From 78e8059da0e05ccdacc0c5b8777dbfa10794e3ed Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 5 Oct 2018 11:47:10 +0300 Subject: [PATCH 0366/1415] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Fixed PhpDoc; --- .../Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 1f0da62f61056..a529580e29239 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -54,7 +54,7 @@ public function modifyData(array $data) } /** - * Add tier price info to meta array. {@inheritdoc} + * Add tier price info to meta array. * * @since 101.1.0 * @param array $meta From 3a65d73ff8b2cc5d801de99f182389a52edec318 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 5 Oct 2018 11:52:38 +0300 Subject: [PATCH 0367/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Catalog/etc/adminhtml/system.xml | 17 +++++++++++++++++ app/code/Magento/Catalog/etc/config.xml | 3 +++ 2 files changed, 20 insertions(+) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 71a799fd22427..26da542cde65b 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -10,6 +10,9 @@ <tab id="catalog" translate="label" sortOrder="200"> <label>Catalog</label> </tab> + <tab id="advanced" translate="label" sortOrder="999999"> + <label>Advanced</label> + </tab> <section id="catalog" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> <class>separator-top</class> <label>Catalog</label> @@ -193,5 +196,19 @@ </field> </group> </section> + <section id="system" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1"> + <class>separator-top</class> + <label>System</label> + <tab>advanced</tab> + <resource>Magento_Config::config_system</resource> + <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Images Upload Configuration</label> + <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Quality</label> + <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> + <comment>Jpeg quality for images 1-100%.</comment> + </field> + </group> + </section> </system> </config> diff --git a/app/code/Magento/Catalog/etc/config.xml b/app/code/Magento/Catalog/etc/config.xml index f52760aa50743..9c9054dd0ce22 100644 --- a/app/code/Magento/Catalog/etc/config.xml +++ b/app/code/Magento/Catalog/etc/config.xml @@ -66,6 +66,9 @@ <product_custom_options_fodler>custom_options</product_custom_options_fodler> </allowed_resources> </media_storage_configuration> + <upload_configuration> + <jpeg_quality>80</jpeg_quality> + </upload_configuration> </system> <design> <watermark> From f67fe209496c7a674444816ca42157cce94ca3f3 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 12:14:10 +0300 Subject: [PATCH 0368/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...eckoutFillNewBillingAddressActionGroup.xml | 6 +- .../Mftf/Section/CheckoutShippingSection.xml | 3 + ...OrderWithNewAddressesThatWasEditedTest.xml | 93 +++++++++++++++++++ ...omerDashboardAccountInformationSection.xml | 3 + .../StorefrontCustomerOrderViewSection.xml | 2 + 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 5a71b82c15cdb..27e5ed7b6e9ab 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -44,5 +44,9 @@ <selectOption stepKey="selectCounty" selector="{{classPrefix}} {{CheckoutShippingSection.country}}" userInput="{{Address.country_id}}"/> <waitForPageLoad stepKey="waitForFormUpdate2"/> </actionGroup> - + <!--Filling address without second address field and without state field--> + <actionGroup name="LoggedInCheckoutWithOneAddressFieldWithoutStateField" extends="LoggedInCheckoutFillNewBillingAddressActionGroup"> + <remove keyForRemoval="fillStreetAddress2"/> + <remove keyForRemoval="selectState"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 494a365ffd507..069e2c74430d3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,5 +32,8 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> + <element name="editNewAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> + <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml new file mode 100644 index 0000000000000..c834f8dd9ece9 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via the Storefront"/> + <title value="Customer Checkout"/> + <description value="Customer can place order with new addresses."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-67837"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + </before> + <after> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + <!--Go to Storefront as Customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin"> + <argument name="Customer" value="$$createCustomer$$" /> + </actionGroup> + + <!-- Add simple product to cart and go to checkout--> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> + + <!-- Click "+ New Address" and Fill new address--> + <click selector="{{CheckoutShippingSection.newAddressButton}}" stepKey="addAddress"/> + <actionGroup ref="LoggedInCheckoutWithOneAddressFieldWithoutStateField" stepKey="changeAddress"> + <argument name="Address" value="UK_Not_Default_Address"/> + <argument name="classPrefix" value="._show"/> + </actionGroup> + + <!--Click "Save Addresses" --> + <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> + <waitForPageLoad stepKey="waitForAddressSaved"/> + <dontSeeElement selector="{{CheckoutShippingSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + + <!--Select Shipping Rate "Flat Rate"--> + <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> + + <!--Click "Edit" for the new address and clear required fields--> + <click selector="{{CheckoutShippingSection.editNewAddress}}" stepKey="editNewAddress"/> + <clearField selector="._show {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> + <clearField selector="._show {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> + <clearField selector="._show {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> + <clearField selector="._show {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> + <clearField selector="._show {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> + <selectOption selector="._show {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> + <clearField selector="._show {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + + <!--Close Popup and click next--> + <click selector="{{CheckoutShippingSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> + + <!--Refresh Page and Place Order--> + <reloadPage stepKey="reloadPage"/> + <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="waitForPlaceOrderButton"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <seeElement selector="{{CheckoutSuccessMainSection.success}}" stepKey="orderIsSuccessfullyPlaced"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="grabOrderNumber"/> + + <!--Verify New addresses in Customer's Address Book--> + <amOnPage url="customer/address/" stepKey="goToCustomerAddressBook"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerAddressBookSection.addressesList}}" stepKey="checkNewAddresses"/> + <!--Order review page has address that was created during checkout--> + <amOnPage url="sales/order/view/order_id/$grabOrderNumber" stepKey="goToOrderReviewPage"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml index 70d1bb6675db5..a20193f85ed57 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml @@ -24,4 +24,7 @@ <element name="country" type="select" selector="#country"/> <element name="saveAddress" type="button" selector="[data-action='save-address']" timeout="30"/> </section> + <section name="StorefrontCustomerAddressBookSection"> + <element name="addressesList" type="text" selector="//ol[@class='items addresses']//li[@class='item']" /> + </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml index 81612d1c64334..f831aabddd4ee 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml @@ -14,5 +14,7 @@ <element name="subtotal" type="text" selector=".subtotal .amount"/> <element name="paymentMethod" type="text" selector=".payment-method dt"/> <element name="printOrderLink" type="text" selector="a.action.print" timeout="30"/> + <element name="shippingAddress" type="text" selector=".box.box-order-shipping-address"/> + <element name="billingAddress" type="text" selector=".box.box-order-billing-address"/> </section> </sections> From 6209f4107673c89b134e2aacd3a23ae708f383ef Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Thu, 4 Oct 2018 13:50:15 +0300 Subject: [PATCH 0369/1415] MAGETWO-91784: On Payment screen up and down arrow key allow to add -ve numbers - Trim the first dash in "Credit Card Number" field --- .../credit-card-validation/credit-card-number-validator.js | 2 +- .../base/web/js/model/credit-card-validation/validator.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js index 8fb12093e36e4..785b636d5832f 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js @@ -36,7 +36,7 @@ define([ return resultWrapper(null, false, false); } - value = value.replace(/\-|\s/g, ''); + value = value.replace(/|\s/g, ''); if (!/^\d*$/.test(value)) { return resultWrapper(null, false, false); diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js index c6f1bad31fc07..f9af514a6d4da 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js @@ -23,6 +23,12 @@ }(function ($, cvvValidator, creditCardNumberValidator, yearValidator, monthValidator, creditCardData) { 'use strict'; + $('.payment-method-content input[type="number"]').on('keyup', function() { + if ($(this).val() < 0) { + $(this).val($(this).val().replace(/^-/, '')); + } + }); + $.each({ 'validate-card-type': [ function (number, item, allowedTypes) { From a71bea80510b8db011812f7052d5f227ebbf2901 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Mon, 17 Sep 2018 11:47:18 +0300 Subject: [PATCH 0370/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Adding min/max qty checks - Adding js validation --- .../Customer/Wishlist/Item/Column/Cart.php | 26 +++++++++ .../frontend/templates/item/column/cart.phtml | 3 +- .../view/frontend/web/js/add-to-wishlist.js | 56 ++++++++++--------- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index b043a8d4b684c..fe0683a52fe97 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -6,6 +6,8 @@ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; +use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter; + /** * Wishlist block customer item cart column * @@ -35,4 +37,28 @@ public function getProductItem() { return $this->getItem()->getProduct(); } + + /** + * Get min and max qty for wishlist form. + * + * @return array + */ + public function getMinMaxQty() + { + $stockItem = $this->stockRegistry->getStockItem( + $this->getItem()->getProduct()->getId(), + $this->getItem()->getProduct()->getStore()->getWebsiteId() + ); + + $params = []; + + $params['minAllowed'] = (float)$stockItem->getMinSaleQty(); + if ($stockItem->getMaxSaleQty()) { + $params['maxAllowed'] = (float)$stockItem->getMaxSaleQty(); + } else { + $params['maxAllowed'] = (float)StockDataFilter::MAX_QTY_VALUE; + } + + return $params; + } } diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index e124edc6a43e1..c1cccae85971c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -11,6 +11,7 @@ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); +$allowedQty = $block->getMinMaxQty(); ?> <?php foreach ($block->getChildNames() as $childName): ?> <?= /* @noEscape */ $block->getLayout()->renderElement($childName, false) ?> @@ -21,7 +22,7 @@ $product = $item->getProduct(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true,'maxlength':8}" + <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index 7ce934317263b..db5f77348b2c0 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -63,12 +63,6 @@ define([ isFileUploaded = false, self = this; - if (event.handleObj.selector == this.options.qtyInfo) { //eslint-disable-line eqeqeq - this._updateAddToWishlistButton({}); - event.stopPropagation(); - - return; - } $(event.handleObj.selector).each(function (index, element) { if ($(element).is('input[type=text]') || $(element).is('input[type=email]') || @@ -89,9 +83,7 @@ define([ } }); - if (isFileUploaded) { - this.bindFormSubmit(); - } + this.bindFormSubmit(isFileUploaded); this._updateAddToWishlistButton(dataToAdd); event.stopPropagation(); }, @@ -195,34 +187,44 @@ define([ /** * Bind form submit. + * + @param {boolean} isFileUploaded */ - bindFormSubmit: function () { + bindFormSubmit: function (isFileUploaded) { var self = this; $('[data-action="add-to-wishlist"]').on('click', function (event) { var element, params, form, action; - event.stopPropagation(); - event.preventDefault(); + if (!$($(self.options.qtyInfo).closest('form')).valid()) { + event.stopPropagation(); + event.preventDefault(); + return; + } - element = $('input[type=file]' + self.options.customOptionsInfo); - params = $(event.currentTarget).data('post'); - form = $(element).closest('form'); - action = params.action; + if (isFileUploaded) { - if (params.data.id) { - $('<input>', { - type: 'hidden', - name: 'id', - value: params.data.id - }).appendTo(form); - } + element = $('input[type=file]' + self.options.customOptionsInfo); + params = $(event.currentTarget).data('post'); + form = $(element).closest('form'); + action = params.action; - if (params.data.uenc) { - action += 'uenc/' + params.data.uenc; - } + if (params.data.id) { + $('<input>', { + type: 'hidden', + name: 'id', + value: params.data.id + }).appendTo(form); + } - $(form).attr('action', action).submit(); + if (params.data.uenc) { + action += 'uenc/' + params.data.uenc; + } + + $(form).attr('action', action).submit(); + event.stopPropagation(); + event.preventDefault(); + } }); } }); From 03e8408b6184d3478251f30cc69956a06752503f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 5 Oct 2018 13:51:24 +0300 Subject: [PATCH 0371/1415] MAGETWO-91636: Tooltip Position on Mobile out of view range - Fix css styles for 768px --- .../web/css/source/module/checkout/_tooltip.less | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less index 273f626ec03d6..bf264a98f33b8 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less @@ -137,9 +137,12 @@ } } -.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { +.media-width(@extremum, @break) when (@extremum = 'max') and (@break >= @screen__m) { .field-tooltip { .field-tooltip-content { + .lib-css(right, @checkout-tooltip-content-mobile__right); + .lib-css(top, @checkout-tooltip-content-mobile__top); + left: auto; &:extend(.abs-checkout-tooltip-content-position-top-mobile all); } } From e194b139c8889587a90aca5cee470e0a40f26422 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 5 Oct 2018 14:04:50 +0300 Subject: [PATCH 0372/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Helper/Image.php | 1 + .../Magento/Catalog/Model/Product/Image.php | 17 +++++++++++++---- .../Model/Product/Image/ParamsBuilder.php | 9 +++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 758e59790d241..74153267f41d6 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -298,6 +298,7 @@ public function resize($width, $height = null) * * @param int $quality * @return $this + * @deprecated */ public function setQuality($quality) { diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index f1ae9ac62dc9b..564b817fc167e 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -24,6 +24,11 @@ */ class Image extends \Magento\Framework\Model\AbstractModel { + /** + * Config path for the jpeg image quality value + */ + const XML_PATH_JPEG_QUALITY = 'system/upload_configuration/jpeg_quality'; + /** * @var int */ @@ -38,8 +43,9 @@ class Image extends \Magento\Framework\Model\AbstractModel * Default quality value (for JPEG images only). * * @var int + * @deprecated */ - protected $_quality = 80; + protected $_quality = null; /** * @var bool @@ -289,6 +295,7 @@ public function getHeight() * * @param int $quality * @return $this + * @deprecated */ public function setQuality($quality) { @@ -303,7 +310,9 @@ public function setQuality($quality) */ public function getQuality() { - return $this->_quality; + return $this->_quality === null + ? $this->_scopeConfig->getValue(self::XML_PATH_JPEG_QUALITY) + : $this->_quality; } /** @@ -461,7 +470,7 @@ public function getImageProcessor() $this->_processor->keepTransparency($this->_keepTransparency); $this->_processor->constrainOnly($this->_constrainOnly); $this->_processor->backgroundColor($this->_backgroundColor); - $this->_processor->quality($this->_quality); + $this->_processor->quality($this->getQuality()); return $this->_processor; } @@ -843,7 +852,7 @@ private function getMiscParams() 'transparency' => $this->_keepTransparency, 'background' => $this->_backgroundColor, 'angle' => $this->_angle, - 'quality' => $this->_quality + 'quality' => $this->getQuality() ] ); } diff --git a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php index dd8d352fecebc..21fde84931fa6 100644 --- a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php +++ b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php @@ -10,17 +10,13 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\View\ConfigInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Catalog\Model\Product\Image; /** * Builds parameters array used to build Image Asset */ class ParamsBuilder { - /** - * @var int - */ - private $defaultQuality = 80; - /** * @var array */ @@ -100,11 +96,12 @@ private function overwriteDefaultValues(array $imageArguments): array $transparency = $imageArguments['transparency'] ?? $this->defaultKeepTransparency; $background = $imageArguments['background'] ?? $this->defaultBackground; $angle = $imageArguments['angle'] ?? $this->defaultAngle; + $quality = (int) $this->scopeConfig->getValue(Image::XML_PATH_JPEG_QUALITY); return [ 'background' => (array) $background, 'angle' => $angle, - 'quality' => $this->defaultQuality, + 'quality' => $quality, 'keep_aspect_ratio' => (bool) $aspectRatio, 'keep_frame' => (bool) $frame, 'keep_transparency' => (bool) $transparency, From 8cf76a56cb7d4eb43489e223240f17868a2b8ca4 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 5 Oct 2018 16:30:57 +0300 Subject: [PATCH 0373/1415] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../frontend/web/js/model/checkout-data-resolver.js | 13 ++++++++----- .../view/frontend/web/js/view/form/element/email.js | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 25abe3c4ed3a0..4abb4c4d61700 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -66,14 +66,15 @@ define([ * Resolve shipping address. Used local storage */ resolveShippingAddress: function () { + var newCustomerShippingAddress; + if (!checkoutData.getShippingAddressFromData() && window.checkoutConfig.shippingAddressFromData ) { checkoutData.setShippingAddressFromData(window.checkoutConfig.shippingAddressFromData); } - var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); - + newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); if (newCustomerShippingAddress) { createShippingAddress(newCustomerShippingAddress); } @@ -201,15 +202,17 @@ define([ * Resolve billing address. Used local storage */ resolveBillingAddress: function () { + var selectedBillingAddress, + newCustomerBillingAddressData; + if (!checkoutData.getBillingAddressFromData() && window.checkoutConfig.billingAddressFromData ) { checkoutData.setBillingAddressFromData(window.checkoutConfig.billingAddressFromData); } - var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), - newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); - + selectedBillingAddress = checkoutData.getSelectedBillingAddress(); + newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); if (selectedBillingAddress) { if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { //eslint-disable-line selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 6c0075fca6d51..37a785e292365 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -17,6 +17,8 @@ define([ ], function ($, Component, ko, customer, checkEmailAvailability, loginAction, quote, checkoutData, fullScreenLoader) { 'use strict'; + var validatedEmail; + if (!checkoutData.getValidatedEmailValue() && window.checkoutConfig.validatedEmailValue ) { @@ -24,8 +26,7 @@ define([ checkoutData.setValidatedEmailValue(window.checkoutConfig.validatedEmailValue); } - var validatedEmail = checkoutData.getValidatedEmailValue(); - + validatedEmail = checkoutData.getValidatedEmailValue(); if (validatedEmail && !customer.isLoggedIn()) { quote.guestEmail = validatedEmail; } From c8a059dc87f1ce4c478d052ba1795e6d92f2cceb Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 5 Oct 2018 16:23:53 +0300 Subject: [PATCH 0374/1415] MAGETWO-91496: Instantiating WYSIWYG in DynamicRows - Add wysiwyg suffix to html and js --- .../view/base/web/js/form/element/wysiwyg.js | 20 +++++++++++++++---- .../Framework/Data/Form/Element/Editor.php | 8 ++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 6507da5e1a933..0c11ceeb03dae 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -20,6 +20,7 @@ define([ return Abstract.extend({ defaults: { elementSelector: 'textarea', + suffixRegExpPattern: '\\${ \\$.wysiwygUniqueSuffix }', value: '', $wysiwygEditorButton: '', links: { @@ -61,12 +62,23 @@ define([ return this; }, + /** @inheritdoc */ + initConfig: function (config) { + var pattern = config.suffixRegExpPattern || this.constructor.defaults.suffixRegExpPattern; + + config.content = config.content.replace(new RegExp(pattern, 'g'), this.getUniqueSuffix(config)); + this._super(); + + return this; + }, + /** - * @inheritdoc + * Build unique id based on name, underscore separated. + * + * @param {Object} config */ - destroy: function () { - this._super(); - wysiwyg.removeEvents(this.wysiwygId); + getUniqueSuffix: function (config) { + return config.name.replace(/(\.|-)/g, '_'); }, /** diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php index c438edf3aa9ac..dee0b6c842f5f 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php @@ -542,4 +542,12 @@ protected function getInlineJs($jsSetupObject, $forceLoad) </script>'; return $jsString; } + + /** + * @inheritdoc + */ + public function getHtmlId() + { + return parent::getHtmlId() . '${ $.wysiwygUniqueSuffix }'; + } } From fa250373443e0a10e9f9472cff69d33754740382 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 17:11:59 +0300 Subject: [PATCH 0375/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...eckoutFillNewBillingAddressActionGroup.xml | 16 +++++++++++ .../Test/Mftf/Page/CheckoutShippingPage.xml | 1 + .../CheckoutNewAddressModalPopupSection.xml | 15 ++++++++++ .../Mftf/Section/CheckoutShippingSection.xml | 4 +-- ...OrderWithNewAddressesThatWasEditedTest.xml | 28 +++++++++---------- .../Page/StorefrontCustomerAddressesPage.xml | 14 ++++++++++ .../StorefrontCustomerAddressesSection.xml | 14 ++++++++++ ...omerDashboardAccountInformationSection.xml | 3 -- 8 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 27e5ed7b6e9ab..62dd6b67b78a6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -49,4 +49,20 @@ <remove keyForRemoval="fillStreetAddress2"/> <remove keyForRemoval="selectState"/> </actionGroup> + + <actionGroup name="clearCheckoutAddressPopupFieldsActionGroup"> + <arguments> + <argument name="classPrefix" type="string" defaultValue=""/> + </arguments> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.company}}" stepKey="clearFieldCompany"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.street2}}" stepKey="clearFieldStreetAddress2"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> + <selectOption selector="{{classPrefix}} {{CheckoutShippingSection.region}}" userInput="" stepKey="clearFieldRegion"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> + <selectOption selector="{{classPrefix}} {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index 07f9e9e6481f7..d13c2d265462b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -11,5 +11,6 @@ <page name="CheckoutShippingPage" url="/checkout/#shipping" module="Checkout" area="storefront"> <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> + <section name="CheckoutNewAddressModalPopupSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml new file mode 100644 index 0000000000000..1c523670f7dbb --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CheckoutNewAddressModalPopupSection"> + <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> + <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 069e2c74430d3..cff960946565d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,8 +32,6 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> - <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> - <element name="editNewAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> - <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> + <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index c834f8dd9ece9..0283f6bd108ec 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -12,7 +12,7 @@ <annotations> <features value="Checkout"/> <stories value="Checkout via the Storefront"/> - <title value="Customer Checkout"/> + <title value="Customer can place order with new addresses that was edited during checkout with several conditions"/> <description value="Customer can place order with new addresses."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-67837"/> @@ -51,24 +51,19 @@ <!--Click "Save Addresses" --> <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> <waitForPageLoad stepKey="waitForAddressSaved"/> - <dontSeeElement selector="{{CheckoutShippingSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + <dontSeeElement selector="{{CheckoutNewAddressModalPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> <!--Select Shipping Rate "Flat Rate"--> <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> - <!--Click "Edit" for the new address and clear required fields--> - <click selector="{{CheckoutShippingSection.editNewAddress}}" stepKey="editNewAddress"/> - <clearField selector="._show {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> - <clearField selector="._show {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> - <clearField selector="._show {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> - <clearField selector="._show {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> - <clearField selector="._show {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> - <selectOption selector="._show {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> - <clearField selector="._show {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + <click selector="{{CheckoutShippingSection.editActiveAddress}}" stepKey="editNewAddress"/> + <actionGroup ref="clearCheckoutAddressPopupFieldsActionGroup" stepKey="clearRequiredFields"> + <argument name="classPrefix" value="._show"/> + </actionGroup> <!--Close Popup and click next--> - <click selector="{{CheckoutShippingSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <click selector="{{CheckoutNewAddressModalPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> @@ -80,14 +75,17 @@ <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="grabOrderNumber"/> <!--Verify New addresses in Customer's Address Book--> - <amOnPage url="customer/address/" stepKey="goToCustomerAddressBook"/> + <amOnPage url="{{StorefrontCustomerAddressesPage.url}}" stepKey="goToCustomerAddressBook"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" - selector="{{StorefrontCustomerAddressBookSection.addressesList}}" stepKey="checkNewAddresses"/> + selector="{{StorefrontCustomerAddressesSection.addressesList}}" stepKey="checkNewAddresses"/> <!--Order review page has address that was created during checkout--> - <amOnPage url="sales/order/view/order_id/$grabOrderNumber" stepKey="goToOrderReviewPage"/> + <amOnPage url="{{StorefrontCustomerOrderViewPage.url({$grabOrderNumber})}}" stepKey="goToOrderReviewPage"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> + + <!--Logout from customer account--> + <amOnPage url="customer/account/logout/" stepKey="logoutCustomer"/> </test> </tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml new file mode 100644 index 0000000000000..b9bede5133060 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="StorefrontCustomerAddressesPage" url="/customer/address/" area="storefront" module="Magento_Customer"> + <section name="StorefrontCustomerAddressesSection"/> + </page> +</pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml new file mode 100644 index 0000000000000..8a6a98ff45a6a --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCustomerAddressesSection"> + <element name="addressesList" type="text" selector=".block-addresses-list" /> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml index a20193f85ed57..70d1bb6675db5 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml @@ -24,7 +24,4 @@ <element name="country" type="select" selector="#country"/> <element name="saveAddress" type="button" selector="[data-action='save-address']" timeout="30"/> </section> - <section name="StorefrontCustomerAddressBookSection"> - <element name="addressesList" type="text" selector="//ol[@class='items addresses']//li[@class='item']" /> - </section> </sections> From 77af6f7d21949eaac1866dfbbbfb4ec1b424a407 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 17:14:37 +0300 Subject: [PATCH 0376/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- .../Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml | 2 +- ...pupSection.xml => StorefrontCheckoutAddressPopupSection.xml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/code/Magento/Checkout/Test/Mftf/Section/{CheckoutNewAddressModalPopupSection.xml => StorefrontCheckoutAddressPopupSection.xml} (90%) diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index d13c2d265462b..c8641f7d8fbf3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -11,6 +11,6 @@ <page name="CheckoutShippingPage" url="/checkout/#shipping" module="Checkout" area="storefront"> <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> - <section name="CheckoutNewAddressModalPopupSection"/> + <section name="StorefrontCheckoutAddressPopupSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml similarity index 90% rename from app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml rename to app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml index 1c523670f7dbb..6a27915768dd7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="CheckoutNewAddressModalPopupSection"> + <section name="StorefrontCheckoutAddressPopupSection"> <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> </section> From 63887c28e24a36d9b5004d6258a42e8c79bb3fb0 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 5 Oct 2018 09:37:14 -0500 Subject: [PATCH 0377/1415] MC-3857: Products Content Type is broken on Dynamic Block page - fix static test failures --- .../Block/Product/ProductsList.php | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 31edeaae9daba..8bec76428316b 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -14,7 +14,7 @@ /** * Catalog Products List widget block - * Class ProductsList + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implements BlockInterface, IdentityInterface @@ -130,7 +130,9 @@ public function __construct( } /** - * {@inheritdoc} + * Internal constructor, that is called from real constructor + * + * @return void */ protected function _construct() { @@ -174,7 +176,14 @@ public function getCacheKeyInfo() } /** - * {@inheritdoc} + * Return HTML block with tier price + * + * @param \Magento\Catalog\Model\Product $product + * @param string $priceType + * @param string $renderZone + * @param array $arguments + * @return string + * * @SuppressWarnings(PHPMD.NPathComplexity) */ public function getProductPriceHtml( @@ -216,6 +225,8 @@ public function getProductPriceHtml( } /** + * Before rendering html, but after trying to load cache + * * {@inheritdoc} */ protected function _beforeToHtml() @@ -254,6 +265,8 @@ public function createCollection() } /** + * Get conditions + * * @return \Magento\Rule\Model\Condition\Combine */ protected function getConditions() @@ -391,8 +404,9 @@ public function getTitle() } /** - * @return PriceCurrencyInterface + * Get currency of product * + * @return PriceCurrencyInterface * @deprecated 100.2.0 */ private function getPriceCurrency() From 8a3fd0440b7b54e8b51e171e81b26a812e14eed3 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 5 Oct 2018 10:09:16 -0500 Subject: [PATCH 0378/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Optimized config elements initialization --- .../Products/Attributes/Collection.php | 3 + .../Magento/GraphQl/Controller/GraphQl.php | 10 +- .../Magento/Framework/GraphQl/Config.php | 11 +++ .../GraphQl/Config/Element/FieldFactory.php | 5 +- .../GraphQl/Query/FieldExtractor.php | 95 +++++++++++++++++++ 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php index ab0531ad09513..5218b055deec6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php @@ -64,6 +64,9 @@ public function getAttributes() : AttributeCollection ['eq' => '1'] ] ); + $arrayOfAttributesRequested = \Magento\Framework\GraphQl\Query\FieldExtractor::$fieldsUsedInQuery; + //$this->collection->addFieldToFilter('attribute_code', ['eq' => 'cost1']); + //do a filter only by fields requested } return $this->collection->load(); diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index 493cabfaee922..f1c22465032fa 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -100,10 +100,18 @@ public function dispatch(RequestInterface $request) : ResponseInterface /** @var Http $request */ $this->requestProcessor->processHeaders($request); $data = $this->jsonSerializer->unserialize($request->getContent()); + + $source = isset($data['query']) ? $data['query'] : ''; + + $documentNode = \GraphQL\Language\Parser::parse(new \GraphQL\Language\Source($source ?: '', 'GraphQL')); + // We have to extract queried field names to avoid instantiation of non necessary fields in webonyx schema + // FieldExtractor class needs to be rewritten it was copied from \GraphQL\Language\Printer + \Magento\Framework\GraphQl\Query\FieldExtractor::doExtract($documentNode); + $schema = $this->schemaGenerator->generate(); $result = $this->queryProcessor->process( $schema, - isset($data['query']) ? $data['query'] : '', + $source, $this->resolverContext, isset($data['variables']) ? $data['variables'] : [] ); diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 8d40d7fa6bb49..312da5cf0b8d5 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -53,6 +53,17 @@ public function getConfigElement(string $configElementName) : ConfigElementInter sprintf('Config element "%s" is not declared in GraphQL schema', $configElementName) ); } + + //limiting the data from config array that is cached + if (isset($data['fields'])) { + foreach ($data['fields'] as $fieldName => $fieldConfig) { + $arrayOfAttributesRequested = \Magento\Framework\GraphQl\Query\FieldExtractor::$fieldsUsedInQuery; + if (!isset($arrayOfAttributesRequested[$fieldName])) { + unset($data['fields'][$fieldName]); + } + } + } + return $this->configElementFactory->createFromConfigData($data); } diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php index 1a022e92c829b..b9ec1dd87d122 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php +++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldFactory.php @@ -42,10 +42,11 @@ public function createFromConfigData( array $fieldData, array $arguments = [] ) : Field { - $arraySign = '/^.*(\[\])$/'; + $fieldType = $fieldData['type']; $isList = false; - if (preg_match($arraySign, $fieldData['type'])) { + //check if type ends with [] + if ($fieldType{strlen($fieldType) - 2} == '[' && $fieldType{strlen($fieldType) - 1} == ']') { $isList = true; $fieldData['type'] = str_replace('[]', '', $fieldData['type']); $fieldData['itemType'] = str_replace('[]', '', $fieldData['type']); diff --git a/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php b/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php new file mode 100644 index 0000000000000..429d03e93d1bb --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\GraphQl\Query; + +use GraphQL\Language\AST\ArgumentNode; +use GraphQL\Language\AST\DirectiveDefinitionNode; +use GraphQL\Language\AST\EnumTypeDefinitionNode; +use GraphQL\Language\AST\EnumTypeExtensionNode; +use GraphQL\Language\AST\EnumValueDefinitionNode; +use GraphQL\Language\AST\FieldDefinitionNode; +use GraphQL\Language\AST\InputObjectTypeDefinitionNode; +use GraphQL\Language\AST\InputObjectTypeExtensionNode; +use GraphQL\Language\AST\InputValueDefinitionNode; +use GraphQL\Language\AST\InterfaceTypeDefinitionNode; +use GraphQL\Language\AST\InterfaceTypeExtensionNode; +use GraphQL\Language\AST\ListValueNode; +use GraphQL\Language\AST\BooleanValueNode; +use GraphQL\Language\AST\DirectiveNode; +use GraphQL\Language\AST\DocumentNode; +use GraphQL\Language\AST\EnumValueNode; +use GraphQL\Language\AST\FieldNode; +use GraphQL\Language\AST\FloatValueNode; +use GraphQL\Language\AST\FragmentDefinitionNode; +use GraphQL\Language\AST\FragmentSpreadNode; +use GraphQL\Language\AST\InlineFragmentNode; +use GraphQL\Language\AST\IntValueNode; +use GraphQL\Language\AST\ListTypeNode; +use GraphQL\Language\AST\NamedTypeNode; +use GraphQL\Language\AST\Node; +use GraphQL\Language\AST\NodeKind; +use GraphQL\Language\AST\NonNullTypeNode; +use GraphQL\Language\AST\NullValueNode; +use GraphQL\Language\AST\ObjectFieldNode; +use GraphQL\Language\AST\ObjectTypeDefinitionNode; +use GraphQL\Language\AST\ObjectValueNode; +use GraphQL\Language\AST\OperationDefinitionNode; +use GraphQL\Language\AST\OperationTypeDefinitionNode; +use GraphQL\Language\AST\ScalarTypeDefinitionNode; +use GraphQL\Language\AST\ScalarTypeExtensionNode; +use GraphQL\Language\AST\SchemaDefinitionNode; +use GraphQL\Language\AST\SelectionSetNode; +use GraphQL\Language\AST\StringValueNode; +use GraphQL\Language\AST\ObjectTypeExtensionNode; +use GraphQL\Language\AST\UnionTypeDefinitionNode; +use GraphQL\Language\AST\UnionTypeExtensionNode; +use GraphQL\Language\AST\VariableDefinitionNode; +use GraphQL\Utils\Utils; + +/** + * Prints AST to string. Capable of printing GraphQL queries and Type definition language. + * Useful for pretty-printing queries or printing back AST for logging, documentation, etc. + * + * Usage example: + * + * ```php + * $query = 'query myQuery {someField}'; + * $ast = GraphQL\Language\Parser::parse($query); + * $printed = GraphQL\Language\Printer::doPrint($ast); + * ``` + * This class was copied from \GraphQL\Language\Printer + */ +class FieldExtractor +{ + + public static $fieldsUsedInQuery = []; + /** + * Prints AST to string. Capable of printing GraphQL queries and Type definition language. + * + * @api + * @param Node $ast + * @return string + */ + public static function doExtract($ast) + { + static $instance; + $instance = $instance ?: new static(); + return $instance->extract($ast); + } + + public function extract($ast) + { + return \GraphQL\Language\Visitor::visit($ast, [ + 'leave' => [ + NodeKind::NAME => function(Node $node) { + self::$fieldsUsedInQuery[$node->value] = $node->value; + } + ] + ]); + } +} From 57ff992b89e2347282af46ee1e77f122abba86a4 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 5 Oct 2018 11:35:28 -0500 Subject: [PATCH 0379/1415] MAGETWO-95346: Configurable and Bundled Product InvoiceOrder Api Service - Fixed bug and added tests --- .../Sales/Model/Service/InvoiceService.php | 6 +- .../Service/V1/OrderInvoiceCreateTest.php | 88 +++++++++++++++++++ .../Sales/_files/order_with_bundle.php | 84 ++++++++++++++++++ .../_files/order_with_bundle_rollback.php | 8 ++ 4 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle_rollback.php diff --git a/app/code/Magento/Sales/Model/Service/InvoiceService.php b/app/code/Magento/Sales/Model/Service/InvoiceService.php index 718f55c3e551c..fa2dcff191775 100644 --- a/app/code/Magento/Sales/Model/Service/InvoiceService.php +++ b/app/code/Magento/Sales/Model/Service/InvoiceService.php @@ -136,7 +136,7 @@ public function prepareInvoice(Order $order, array $qtys = []) $totalQty = 0; $qtys = $this->prepareItemsQty($order, $qtys); foreach ($order->getAllItems() as $orderItem) { - if (!$this->_canInvoiceItem($orderItem)) { + if (!$this->_canInvoiceItem($orderItem, $qtys)) { continue; } $item = $this->orderConverter->itemToInvoiceItem($orderItem); @@ -196,12 +196,12 @@ private function prepareItemsQty(Order $order, array $qtys = []) * with parent item which is included to invoice * * @param \Magento\Sales\Api\Data\OrderItemInterface $item + * @param array $qtys * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function _canInvoiceItem(\Magento\Sales\Api\Data\OrderItemInterface $item) + protected function _canInvoiceItem(\Magento\Sales\Api\Data\OrderItemInterface $item, array $qtys = []) { - $qtys = []; if ($item->getLockedDoInvoice()) { return false; } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php index 49e05832f2ef3..941421d456ca9 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php @@ -90,4 +90,92 @@ public function testInvoiceCreate() 'Failed asserting that Order status was changed' ); } + + /** + * Tests that MAGETWO-95346 was fixed for bundled products + * + * @expectedException \Exception + * @codingStandardsIgnoreStart + * @expectedExceptionMessage {"message":"Invoice Document Validation Error(s):\nThe invoice can't be created without products. Add products and try again."} + * @codingStandardsIgnoreEnd + * @magentoApiDataFixture Magento/Sales/_files/order_with_bundle.php + */ + public function testOrderWithBundleInvoicedWithInvalidQuantitiesReturnsError() + { + /** @var \Magento\Sales\Model\Order $existingOrder */ + $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) + ->loadByIncrementId('100000001'); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/order/' . $existingOrder->getId() . '/invoice', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'execute', + ], + ]; + + $requestData = [ + 'notify' => true, + 'appendComment' => true, + 'items' => [ + [ + 'order_item_id' => -1, + 'qty' => 1 + ] + ], + 'comment' => [ + 'comment' => 'Test offline', + ], + ]; + + $this->_webApiCall($serviceInfo, $requestData); + } + + /** + * Tests that MAGETWO-95346 was fixed for configurable products + * + * @expectedException \Exception + * @codingStandardsIgnoreStart + * @expectedExceptionMessage {"message":"Invoice Document Validation Error(s):\nThe invoice can't be created without products. Add products and try again."} + * @codingStandardsIgnoreEnd + * @magentoApiDataFixture Magento/Sales/_files/order_configurable_product.php + */ + public function testOrderWithConfigurableProductInvoicedWithInvalidQuantitiesReturnsError() + { + /** @var \Magento\Sales\Model\Order $existingOrder */ + $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) + ->loadByIncrementId('100000001'); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/order/' . $existingOrder->getId() . '/invoice', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'execute', + ], + ]; + + $requestData = [ + 'notify' => true, + 'appendComment' => true, + 'items' => [ + [ + 'order_item_id' => -1, + 'qty' => 1 + ] + ], + 'comment' => [ + 'comment' => 'Test offline', + ], + ]; + + $this->_webApiCall($serviceInfo, $requestData); + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php new file mode 100644 index 0000000000000..6b6d6d6e6ec04 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Api\Data\OrderItemInterface; +use Magento\Sales\Api\OrderItemRepositoryInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Item; +use Magento\TestFramework\ObjectManager; + +$objectManager = ObjectManager::getInstance(); + +require 'order.php'; +/** @var Order $order */ + +$orderItems = [ + [ + OrderItemInterface::PRODUCT_ID => 2, + OrderItemInterface::BASE_PRICE => 100, + OrderItemInterface::ORDER_ID => $order->getId(), + OrderItemInterface::QTY_ORDERED => 2, + OrderItemInterface::QTY_INVOICED => 2, + OrderItemInterface::PRICE => 100, + OrderItemInterface::ROW_TOTAL => 102, + OrderItemInterface::PRODUCT_TYPE => 'bundle', + 'product_options' => [ + 'product_calculations' => 0, + ], + 'children' => [ + [ + OrderItemInterface::PRODUCT_ID => 13, + OrderItemInterface::ORDER_ID => $order->getId(), + OrderItemInterface::QTY_ORDERED => 10, + OrderItemInterface::QTY_INVOICED => 10, + OrderItemInterface::BASE_PRICE => 90, + OrderItemInterface::PRICE => 90, + OrderItemInterface::ROW_TOTAL => 92, + OrderItemInterface::PRODUCT_TYPE => 'simple', + 'product_options' => [ + 'bundle_selection_attributes' => [ + 'qty' => 2, + ], + ], + ], + ], + ], +]; + +if (!function_exists('saveOrderItems')) { + /** + * Save Order Items. + * + * @param array $orderItems + * @param Item|null $parentOrderItem [optional] + * @return void + */ + function saveOrderItems(array $orderItems, Order $order, $parentOrderItem = null) + { + $objectManager = ObjectManager::getInstance(); + + foreach ($orderItems as $orderItemData) { + /** @var Item $orderItem */ + $orderItem = $objectManager->create(Item::class); + if (null !== $parentOrderItem) { + $orderItemData['parent_item'] = $parentOrderItem; + } + $orderItem->setData($orderItemData); + $order->addItem($orderItem); + + if (isset($orderItemData['children'])) { + saveOrderItems($orderItemData['children'], $order, $orderItem); + } + } + } +} + +saveOrderItems($orderItems, $order); +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->get(OrderRepositoryInterface::class); +$order = $orderRepository->save($order); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle_rollback.php new file mode 100644 index 0000000000000..dd52deab825cb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require 'order_rollback.php'; From b6ff09014c1fead6f6e8c0a3020e2a4ab94a3812 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 5 Oct 2018 11:50:43 -0500 Subject: [PATCH 0380/1415] MAGETWO-93001: AvoidIdSniff Static test rule gives a false positive result - Fixed copyright header static failure --- .../Magento/Sniffs/Less/_files/avoid-ids-errors.txt | 12 ++++++------ .../Magento/Sniffs/Less/_files/avoid-ids.less | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt index 7ce7bc6de4ad0..ebc01c4e0852e 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids-errors.txt @@ -1,11 +1,6 @@ --------------------------------------------------------------------------------------------------------------------------------- FOUND 20 ERRORS AFFECTING 20 LINES --------------------------------------------------------------------------------------------------------------------------------- - 1 | ERROR | Id selector is used - 2 | ERROR | Id selector is used - 3 | ERROR | Id selector is used - 4 | ERROR | Id selector is used - 5 | ERROR | Id selector is used 6 | ERROR | Id selector is used 7 | ERROR | Id selector is used 8 | ERROR | Id selector is used @@ -18,9 +13,14 @@ FOUND 20 ERRORS AFFECTING 20 LINES 15 | ERROR | Id selector is used 16 | ERROR | Id selector is used 17 | ERROR | Id selector is used + 18 | ERROR | Id selector is used + 19 | ERROR | Id selector is used + 20 | ERROR | Id selector is used 21 | ERROR | Id selector is used 22 | ERROR | Id selector is used - 23 | ERROR | Id selector is used + 26 | ERROR | Id selector is used + 27 | ERROR | Id selector is used + 28 | ERROR | Id selector is used --------------------------------------------------------------------------------------------------------------------------------- diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less index 45eb999c803c7..dd37677b5b53b 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Less/_files/avoid-ids.less @@ -1,3 +1,8 @@ +// /** +// * Copyright © Magento, Inc. All rights reserved. +// * See COPYING.txt for license details. +// */ + #foo[bar], #foo[bar=bash], #foo[bar~=bash], From 89b54dd642f3e32fa1ef537aba54a536857b9cd6 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Fri, 5 Oct 2018 13:24:02 -0500 Subject: [PATCH 0381/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Refactored performance optimization for config elements initialization --- .../Products/Attributes/Collection.php | 3 - .../Magento/GraphQl/Controller/GraphQl.php | 22 +++-- .../Magento/Framework/GraphQl/Config.php | 18 +++- .../GraphQl/Query/FieldExtractor.php | 95 ------------------- .../Framework/GraphQl/Query/Fields.php | 64 +++++++++++++ 5 files changed, 92 insertions(+), 110 deletions(-) delete mode 100644 lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php create mode 100644 lib/internal/Magento/Framework/GraphQl/Query/Fields.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php index 5218b055deec6..ab0531ad09513 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Attributes/Collection.php @@ -64,9 +64,6 @@ public function getAttributes() : AttributeCollection ['eq' => '1'] ] ); - $arrayOfAttributesRequested = \Magento\Framework\GraphQl\Query\FieldExtractor::$fieldsUsedInQuery; - //$this->collection->addFieldToFilter('attribute_code', ['eq' => 'cost1']); - //do a filter only by fields requested } return $this->collection->load(); diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index f1c22465032fa..c4a0b55de9bfc 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -17,6 +17,7 @@ use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface; use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Webapi\Response; +use Magento\Framework\GraphQl\Query\Fields as QueryFields; /** * Front controller for web API GraphQL area. @@ -60,6 +61,11 @@ class GraphQl implements FrontControllerInterface */ private $requestProcessor; + /** + * @var QueryFields + */ + private $queryFields; + /** * @param Response $response * @param SchemaGeneratorInterface $schemaGenerator @@ -68,6 +74,7 @@ class GraphQl implements FrontControllerInterface * @param \Magento\Framework\GraphQl\Exception\ExceptionFormatter $graphQlError * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $resolverContext * @param HttpRequestProcessor $requestProcessor + * @param QueryFields $queryFields */ public function __construct( Response $response, @@ -76,7 +83,8 @@ public function __construct( QueryProcessor $queryProcessor, ExceptionFormatter $graphQlError, ContextInterface $resolverContext, - HttpRequestProcessor $requestProcessor + HttpRequestProcessor $requestProcessor, + QueryFields $queryFields ) { $this->response = $response; $this->schemaGenerator = $schemaGenerator; @@ -85,6 +93,7 @@ public function __construct( $this->graphQlError = $graphQlError; $this->resolverContext = $resolverContext; $this->requestProcessor = $requestProcessor; + $this->queryFields = $queryFields; } /** @@ -101,17 +110,16 @@ public function dispatch(RequestInterface $request) : ResponseInterface $this->requestProcessor->processHeaders($request); $data = $this->jsonSerializer->unserialize($request->getContent()); - $source = isset($data['query']) ? $data['query'] : ''; + $query = isset($data['query']) ? $data['query'] : ''; - $documentNode = \GraphQL\Language\Parser::parse(new \GraphQL\Language\Source($source ?: '', 'GraphQL')); // We have to extract queried field names to avoid instantiation of non necessary fields in webonyx schema - // FieldExtractor class needs to be rewritten it was copied from \GraphQL\Language\Printer - \Magento\Framework\GraphQl\Query\FieldExtractor::doExtract($documentNode); - + // Temporal coupling is required for performance optimization + $this->queryFields->setQuery($query); $schema = $this->schemaGenerator->generate(); + $result = $this->queryProcessor->process( $schema, - $source, + $query, $this->resolverContext, isset($data['variables']) ? $data['variables'] : [] ); diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 312da5cf0b8d5..52735acc6d70f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -10,6 +10,7 @@ use Magento\Framework\Config\DataInterface; use Magento\Framework\GraphQl\Config\ConfigElementFactoryInterface; use Magento\Framework\GraphQl\Config\ConfigElementInterface; +use Magento\Framework\GraphQl\Query\Fields as QueryFields; /** * Provides access to typing information for a configured GraphQL schema. @@ -26,16 +27,24 @@ class Config implements ConfigInterface */ private $configElementFactory; + /** + * @var QueryFields + */ + private $queryFields; + /** * @param DataInterface $data * @param ConfigElementFactoryInterface $configElementFactory + * @param QueryFields $queryFields */ public function __construct( DataInterface $data, - ConfigElementFactoryInterface $configElementFactory + ConfigElementFactoryInterface $configElementFactory, + QueryFields $queryFields ) { $this->configData = $data; $this->configElementFactory = $configElementFactory; + $this->queryFields = $queryFields; } /** @@ -54,11 +63,10 @@ public function getConfigElement(string $configElementName) : ConfigElementInter ); } - //limiting the data from config array that is cached - if (isset($data['fields'])) { + $fieldsInQuery = $this->queryFields->getFieldsUsedInQuery(); + if (isset($data['fields']) && !empty($fieldsInQuery)) { foreach ($data['fields'] as $fieldName => $fieldConfig) { - $arrayOfAttributesRequested = \Magento\Framework\GraphQl\Query\FieldExtractor::$fieldsUsedInQuery; - if (!isset($arrayOfAttributesRequested[$fieldName])) { + if (!isset($fieldsInQuery[$fieldName])) { unset($data['fields'][$fieldName]); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php b/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php deleted file mode 100644 index 429d03e93d1bb..0000000000000 --- a/lib/internal/Magento/Framework/GraphQl/Query/FieldExtractor.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Framework\GraphQl\Query; - -use GraphQL\Language\AST\ArgumentNode; -use GraphQL\Language\AST\DirectiveDefinitionNode; -use GraphQL\Language\AST\EnumTypeDefinitionNode; -use GraphQL\Language\AST\EnumTypeExtensionNode; -use GraphQL\Language\AST\EnumValueDefinitionNode; -use GraphQL\Language\AST\FieldDefinitionNode; -use GraphQL\Language\AST\InputObjectTypeDefinitionNode; -use GraphQL\Language\AST\InputObjectTypeExtensionNode; -use GraphQL\Language\AST\InputValueDefinitionNode; -use GraphQL\Language\AST\InterfaceTypeDefinitionNode; -use GraphQL\Language\AST\InterfaceTypeExtensionNode; -use GraphQL\Language\AST\ListValueNode; -use GraphQL\Language\AST\BooleanValueNode; -use GraphQL\Language\AST\DirectiveNode; -use GraphQL\Language\AST\DocumentNode; -use GraphQL\Language\AST\EnumValueNode; -use GraphQL\Language\AST\FieldNode; -use GraphQL\Language\AST\FloatValueNode; -use GraphQL\Language\AST\FragmentDefinitionNode; -use GraphQL\Language\AST\FragmentSpreadNode; -use GraphQL\Language\AST\InlineFragmentNode; -use GraphQL\Language\AST\IntValueNode; -use GraphQL\Language\AST\ListTypeNode; -use GraphQL\Language\AST\NamedTypeNode; -use GraphQL\Language\AST\Node; -use GraphQL\Language\AST\NodeKind; -use GraphQL\Language\AST\NonNullTypeNode; -use GraphQL\Language\AST\NullValueNode; -use GraphQL\Language\AST\ObjectFieldNode; -use GraphQL\Language\AST\ObjectTypeDefinitionNode; -use GraphQL\Language\AST\ObjectValueNode; -use GraphQL\Language\AST\OperationDefinitionNode; -use GraphQL\Language\AST\OperationTypeDefinitionNode; -use GraphQL\Language\AST\ScalarTypeDefinitionNode; -use GraphQL\Language\AST\ScalarTypeExtensionNode; -use GraphQL\Language\AST\SchemaDefinitionNode; -use GraphQL\Language\AST\SelectionSetNode; -use GraphQL\Language\AST\StringValueNode; -use GraphQL\Language\AST\ObjectTypeExtensionNode; -use GraphQL\Language\AST\UnionTypeDefinitionNode; -use GraphQL\Language\AST\UnionTypeExtensionNode; -use GraphQL\Language\AST\VariableDefinitionNode; -use GraphQL\Utils\Utils; - -/** - * Prints AST to string. Capable of printing GraphQL queries and Type definition language. - * Useful for pretty-printing queries or printing back AST for logging, documentation, etc. - * - * Usage example: - * - * ```php - * $query = 'query myQuery {someField}'; - * $ast = GraphQL\Language\Parser::parse($query); - * $printed = GraphQL\Language\Printer::doPrint($ast); - * ``` - * This class was copied from \GraphQL\Language\Printer - */ -class FieldExtractor -{ - - public static $fieldsUsedInQuery = []; - /** - * Prints AST to string. Capable of printing GraphQL queries and Type definition language. - * - * @api - * @param Node $ast - * @return string - */ - public static function doExtract($ast) - { - static $instance; - $instance = $instance ?: new static(); - return $instance->extract($ast); - } - - public function extract($ast) - { - return \GraphQL\Language\Visitor::visit($ast, [ - 'leave' => [ - NodeKind::NAME => function(Node $node) { - self::$fieldsUsedInQuery[$node->value] = $node->value; - } - ] - ]); - } -} diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Fields.php b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php new file mode 100644 index 0000000000000..fb18fa1bfab8a --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\GraphQl\Query; + +use GraphQL\Language\AST\Node; +use GraphQL\Language\AST\NodeKind; + +/** + * This class holds a list of all queried fields and is used to enable performance optimization for schema loading. + */ +class Fields +{ + /** + * @var string[] + */ + private $fieldsUsedInQuery = []; + + /** + * Prints AST to string. Capable of printing GraphQL queries and Type definition language. + * + * @param string $query + * @return void + */ + public function setQuery($query) + { + $queryFields = []; + try { + $queryAst = \GraphQL\Language\Parser::parse(new \GraphQL\Language\Source($query ?: '', 'GraphQL')); + \GraphQL\Language\Visitor::visit( + $queryAst, + [ + 'leave' => [ + NodeKind::NAME => function (Node $node) use (&$queryFields) { + $queryFields[$node->value] = $node->value; + } + ] + ] + ); + } catch (\Exception $e) { + } + if (isset($queryFields['IntrospectionQuery'])) { + // It must be possible to query any fields during introspection query + $queryFields = []; + } + $this->fieldsUsedInQuery = $queryFields; + } + + /** + * Get list of fields used in GraphQL query. + * + * This method is stateful and relies on the query being set with setQuery. + * + * @return string[] + */ + public function getFieldsUsedInQuery() + { + return $this->fieldsUsedInQuery; + } +} From ee4e6fdd384f7249028aa5f19b6fff9c419dda64 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 5 Oct 2018 13:48:23 -0500 Subject: [PATCH 0382/1415] MAGETWO-95346: Configurable and Bundled Product InvoiceOrder Api Service - Fixed static test and soap tests --- app/code/Magento/Sales/Model/Service/InvoiceService.php | 5 +++-- .../Magento/Sales/Service/V1/OrderInvoiceCreateTest.php | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Service/InvoiceService.php b/app/code/Magento/Sales/Model/Service/InvoiceService.php index fa2dcff191775..2806f76b1389b 100644 --- a/app/code/Magento/Sales/Model/Service/InvoiceService.php +++ b/app/code/Magento/Sales/Model/Service/InvoiceService.php @@ -125,6 +125,8 @@ public function setVoid($id) } /** + * Creates an invoice based on the order and quantities provided + * * @param Order $order * @param array $qtys * @return \Magento\Sales\Model\Order\Invoice @@ -192,8 +194,7 @@ private function prepareItemsQty(Order $order, array $qtys = []) } /** - * Check if order item can be invoiced. Dummy item can be invoiced or with his children or - * with parent item which is included to invoice + * Check if order item can be invoiced. * * @param \Magento\Sales\Api\Data\OrderItemInterface $item * @param array $qtys diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php index 941421d456ca9..f6194db6d8ebb 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php @@ -96,7 +96,7 @@ public function testInvoiceCreate() * * @expectedException \Exception * @codingStandardsIgnoreStart - * @expectedExceptionMessage {"message":"Invoice Document Validation Error(s):\nThe invoice can't be created without products. Add products and try again."} + * @expectedExceptionMessageRegExp /Invoice Document Validation Error\(s\):(?:\n|\\n)The invoice can't be created without products. Add products and try again./ * @codingStandardsIgnoreEnd * @magentoApiDataFixture Magento/Sales/_files/order_with_bundle.php */ @@ -119,6 +119,7 @@ public function testOrderWithBundleInvoicedWithInvalidQuantitiesReturnsError() ]; $requestData = [ + 'orderId' => $existingOrder->getId(), 'notify' => true, 'appendComment' => true, 'items' => [ @@ -129,6 +130,7 @@ public function testOrderWithBundleInvoicedWithInvalidQuantitiesReturnsError() ], 'comment' => [ 'comment' => 'Test offline', + 'isVisibleOnFront' => 1, ], ]; @@ -140,7 +142,7 @@ public function testOrderWithBundleInvoicedWithInvalidQuantitiesReturnsError() * * @expectedException \Exception * @codingStandardsIgnoreStart - * @expectedExceptionMessage {"message":"Invoice Document Validation Error(s):\nThe invoice can't be created without products. Add products and try again."} + * @expectedExceptionMessageRegExp /Invoice Document Validation Error\(s\):(?:\n|\\n)The invoice can't be created without products. Add products and try again./ * @codingStandardsIgnoreEnd * @magentoApiDataFixture Magento/Sales/_files/order_configurable_product.php */ @@ -163,6 +165,7 @@ public function testOrderWithConfigurableProductInvoicedWithInvalidQuantitiesRet ]; $requestData = [ + 'orderId' => $existingOrder->getId(), 'notify' => true, 'appendComment' => true, 'items' => [ @@ -173,6 +176,7 @@ public function testOrderWithConfigurableProductInvoicedWithInvalidQuantitiesRet ], 'comment' => [ 'comment' => 'Test offline', + 'isVisibleOnFront' => 1, ], ]; From 0ae24277ba359cc0e338ffdb626c36e485175586 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 5 Oct 2018 14:48:56 -0500 Subject: [PATCH 0383/1415] MAGETWO-91057: MFTF Test failure - Add products to wishlist from different stores - unskip test --- .../Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml index c9a0c0cc0f8bc..f8a1707e6c23a 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml @@ -15,9 +15,6 @@ <description value="All products added to wishlist should be visible on any store. Even if product visibility was set to 'Not Visible Individually' for this store"/> <group value="wishlist"/> <severity value="AVERAGE"/> - <skip> - <issueId value="MAGETWO-93980"/> - </skip> </annotations> <before> <createData entity="customStoreGroup" stepKey="storeGroup"/> From 9134496c5d649932a5315f92191e88c8cbcc2015 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 5 Oct 2018 14:54:25 -0500 Subject: [PATCH 0384/1415] MC-3857: Products Content Type is broken on Dynamic Block page - fix static test failures --- app/code/Magento/CatalogWidget/Block/Product/ProductsList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 8bec76428316b..ed17634aa48c1 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -227,7 +227,7 @@ public function getProductPriceHtml( /** * Before rendering html, but after trying to load cache * - * {@inheritdoc} + * @return $this */ protected function _beforeToHtml() { From 436d8a65b2988b851e6331b63ca6fe5f71d05885 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Fri, 5 Oct 2018 16:05:58 -0500 Subject: [PATCH 0385/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Optimized category data loading for products query --- .../Model/Category/Hydrator.php | 14 +++++--- .../Model/Resolver/Categories.php | 33 ++++++++----------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index da4ec37c51da4..f0cdab9498abb 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Category; use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Catalog\Model\Category; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CustomAttributesFlattener; use Magento\Framework\Reflection\DataObjectProcessor; @@ -41,14 +42,19 @@ public function __construct( /** * Hydrate and flatten category object to flat array * - * @param CategoryInterface $category + * @param Category $category + * @param bool $basicFieldsOnly Set to false to avoid expensive hydration, used for performance optimization * @return array */ - public function hydrateCategory(CategoryInterface $category) : array + public function hydrateCategory(Category $category, $basicFieldsOnly = false) : array { - $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); + if ($basicFieldsOnly) { + $categoryData = $category->getData(); + } else { + $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); + $categoryData['product_count'] = $category->getProductCount(); + } $categoryData['id'] = $category->getId(); - $categoryData['product_count'] = $category->getProductCount(); $categoryData['children'] = []; $categoryData['available_sort_by'] = $category->getAvailableSortBy(); return $this->flattener->flatten($categoryData); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index 11614e79bba22..7fe679b18d866 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -17,7 +17,7 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; -use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\CatalogGraphQl\Model\Category\Hydrator as CategoryHydrator; /** * Resolver for category objects the product is assigned to. @@ -36,11 +36,6 @@ class Categories implements ResolverInterface */ private $categoryIds = []; - /** - * @var DataObjectProcessor - */ - private $dataObjectProcessor; - /** * @var AttributesJoiner */ @@ -57,25 +52,29 @@ class Categories implements ResolverInterface private $valueFactory; /** - * Category constructor. + * @var CategoryHydrator + */ + private $categoryHydrator; + + /** * @param CollectionFactory $collectionFactory - * @param DataObjectProcessor $dataObjectProcessor * @param AttributesJoiner $attributesJoiner * @param CustomAttributesFlattener $customAttributesFlattener * @param ValueFactory $valueFactory + * @param CategoryHydrator $categoryHydrator */ public function __construct( CollectionFactory $collectionFactory, - DataObjectProcessor $dataObjectProcessor, AttributesJoiner $attributesJoiner, CustomAttributesFlattener $customAttributesFlattener, - ValueFactory $valueFactory + ValueFactory $valueFactory, + CategoryHydrator $categoryHydrator ) { $this->collection = $collectionFactory->create(); - $this->dataObjectProcessor = $dataObjectProcessor; $this->attributesJoiner = $attributesJoiner; $this->customAttributesFlattener = $customAttributesFlattener; $this->valueFactory = $valueFactory; + $this->categoryHydrator = $categoryHydrator; } /** @@ -109,8 +108,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (in_array($item->getId(), $categoryIds)) { // Try to extract all requested fields from the loaded collection data - $categories[$item->getId()] = $item->getData(); - $categories[$item->getId()]['id'] = $item->getId(); + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); $extractedFields = array_keys($categories[$item->getId()]); $foundFields = array_intersect($requestedFields, $extractedFields); @@ -119,13 +117,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } // If not all requested fields were extracted from the collection, start more complex extraction - $categories[$item->getId()] = $this->dataObjectProcessor->buildOutputDataArray( - $item, - CategoryInterface::class - ); - $categories[$item->getId()] = $this->customAttributesFlattener - ->flatten($categories[$item->getId()]); - $categories[$item->getId()]['product_count'] = $item->getProductCount(); + $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); + } } From 87bb433ce2ccc3de2a3f89de9e40f70515d43fa5 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 5 Oct 2018 17:28:11 -0500 Subject: [PATCH 0386/1415] MAGETWO-95130: CMS block cannot be deleted - added functional test to cover the bug fix --- .../SearchBlockOnGridPageActionGroup.xml | 23 +++++++++++++++++++ .../CmsNewBlockBlockActionsSection.xml | 4 ++++ .../Mftf/Test/AdminCreateCmsBlockTest.xml | 3 +++ 3 files changed, 30 insertions(+) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/SearchBlockOnGridPageActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/SearchBlockOnGridPageActionGroup.xml index e31eb44146af4..12205aeed8fa3 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/SearchBlockOnGridPageActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/SearchBlockOnGridPageActionGroup.xml @@ -16,4 +16,27 @@ <waitForLoadingMaskToDisappear stepKey="waitForSecondIdSortDescendingToFinish2" /> <waitForElementVisible selector="{{WidgetSection.BlockPage(Block.identifier)}}" stepKey="waitForBlockTitle" /> </actionGroup> + <actionGroup name ="deleteBlock"> + <arguments> + <argument name="Block" defaultValue=""/> + </arguments> + <amOnPage url="{{CmsBlocksPage.url}}" stepKey="navigateToCMSBlocksGrid"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <conditionalClick selector="{{BlockPageActionsSection.clearAll}}" dependentSelector="{{BlockPageActionsSection.activeFilters}}" stepKey="clickToResetFilter" visible="true"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{BlockPageActionsSection.FilterBtn}}" stepKey="clickFilterBtn"/> + <fillField selector="{{BlockPageActionsSection.URLKey}}" userInput="{{Block.identifier}}" stepKey="fillBlockIdentifierInput"/> + <click selector="{{BlockPageActionsSection.ApplyFiltersBtn}}" stepKey="applyFilter"/> + <waitForLoadingMaskToDisappear stepKey="waitForGridToLoadResults" /> + <waitForElementVisible selector="{{BlockPageActionsSection.select(Block.identifier)}}" stepKey="waitForCMSPageGrid" /> + <click selector="{{BlockPageActionsSection.select(Block.identifier)}}" stepKey="clickSelect" /> + <waitForElementVisible selector="{{BlockPageActionsSection.edit(Block.identifier)}}" stepKey="waitForEditLink" /> + <click selector="{{BlockPageActionsSection.edit(Block.identifier)}}" stepKey="clickEdit" /> + <waitForLoadingMaskToDisappear stepKey="waitForPageToLoad" /> + <click selector="{{CmsBlockBlockActionSection.deleteBlock}}" stepKey="deleteBlock"/> + <waitForElementVisible selector="{{CmsBlockBlockActionSection.deleteConfirm}}" stepKey="waitForOkButtonToBeVisible"/> + <click selector="{{CmsBlockBlockActionSection.deleteConfirm}}" stepKey="clickOkButton"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> + <see userInput="You deleted the block." stepKey="seeSuccessMessage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml index 2e783af6bfc6a..4c6014af51264 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml @@ -24,4 +24,8 @@ <section name="BlockContentSection"> <element name="TextArea" type="input" selector="#cms_block_form_content"/> </section> + <section name="CmsBlockBlockActionSection"> + <element name="deleteBlock" type="button" selector="#delete" timeout="30"/> + <element name="deleteConfirm" type="button" selector=".action-primary.action-accept" timeout="60"/> + </section> </sections> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsBlockTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsBlockTest.xml index e2c74823dfffb..7ab0d9209dde3 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsBlockTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsBlockTest.xml @@ -23,6 +23,9 @@ <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> </before> <after> + <actionGroup ref="deleteBlock" stepKey="deleteCreatedBlock"> + <argument name="Block" value="_defaultBlock"/> + </actionGroup> <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage url="{{CmsNewBlock.url}}" stepKey="amOnBlocksCreationForm"/> From 2bee3660f183af1439b111557b3b958b3c812b25 Mon Sep 17 00:00:00 2001 From: Peter O'Callaghan <contact@peterocallaghan.co.uk> Date: Sat, 6 Oct 2018 10:28:25 +0100 Subject: [PATCH 0387/1415] Fixes #18357 - SQL error when table prefix used. --- .../Model/ResourceModel/Agreement/Grid/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php index 70794d24a64eb..78ad7b32330ad 100644 --- a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php +++ b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php @@ -64,7 +64,7 @@ private function getStoresForAgreements() if (!empty($agreementId)) { $select = $this->getConnection()->select()->from( - ['agreement_store' => 'checkout_agreement_store'] + ['agreement_store' => $this->getResource()->getTable('checkout_agreement_store')] )->where( 'agreement_store.agreement_id IN (?)', $agreementId From 87cfb718edcde6b21375e398dbc8fd35cb84dcbe Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sat, 6 Oct 2018 12:40:15 +0200 Subject: [PATCH 0388/1415] Working concept for setting shipping address for a shopping cart --- .../SetShippingMethodsOnCart.php | 81 +++++++++++++------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 8 +- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index f2e1be3bb0508..c2d14668a2e70 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -7,7 +7,8 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; -use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Checkout\Api\ShippingInformationManagementInterface; +use Magento\Checkout\Model\ShippingInformation; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; @@ -19,8 +20,10 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\ShippingMethodManagementInterface; use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; +use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; +use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; +use Magento\Checkout\Model\ShippingInformationFactory; /** * Class SetShippingMethodsOnCart @@ -29,41 +32,64 @@ */ class SetShippingMethodsOnCart implements ResolverInterface { + /** + * @var ShippingInformationFactory + */ + private $shippingInformationFactory; + + /** + * @var QuoteAddressFactory + */ + private $quoteAddressFactory; + + /** + * @var QuoteAddressResource + */ + private $quoteAddressResource; + /** * @var MaskedQuoteIdToQuoteIdInterface */ private $maskedQuoteIdToQuoteId; + /** * @var ArrayManager */ private $arrayManager; /** - * @var ShippingMethodManagementInterface + * @var IsCartMutationAllowedForCurrentUser */ - private $shippingMethodManagement; + private $isCartMutationAllowedForCurrentUser; /** - * @var IsCartMutationAllowedForCurrentUser + * @var ShippingInformationManagementInterface */ - private $isCartMutationAllowedForCurrentUser; + private $shippingInformationManagement; /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param ShippingMethodManagementInterface $shippingMethodManagement + * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - ShippingMethodManagementInterface $shippingMethodManagement, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, + ShippingInformationManagementInterface $shippingInformationManagement, + QuoteAddressFactory $quoteAddressFacrory, + QuoteAddressResource $quoteAddressResource, + ShippingInformationFactory $shippingInformationFactory ) { $this->arrayManager = $arrayManager; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->shippingMethodManagement = $shippingMethodManagement; $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; + $this->shippingInformationManagement = $shippingInformationManagement; + + $this->quoteAddressResource = $quoteAddressResource; + $this->quoteAddressFactory = $quoteAddressFacrory; + $this->shippingInformationFactory = $shippingInformationFactory; } /** @@ -77,17 +103,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!$maskedCartId) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } - if (!$shippingMethods) { throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping + if (!$shippingMethod['cart_address_id']) { + throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); + } if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); } @@ -109,22 +136,28 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value ); } + $quoteAddress = $this->quoteAddressFactory->create(); + $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); + + /** @var ShippingInformation $shippingInformation */ + $shippingInformation = $this->shippingInformationFactory->create(); + + /* If the address is not a shipping address (but billing) the system will find the proper shipping address for + the selected cart and set the information there (actual for single shipping address) */ + $shippingInformation->setShippingAddress($quoteAddress); + $shippingInformation->setShippingCarrierCode($shippingMethod['shipping_carrier_code']); + $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); + try { - $this->shippingMethodManagement->set( - $cartId, - $shippingMethods['shipping_carrier_code'], - $shippingMethods['shipping_method_code'] - ); - } catch (InputException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); - } catch (CouldNotSaveException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); - } catch (StateException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); + $this->shippingInformationManagement->saveAddressInformation($cartId, $shippingInformation); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException(__($exception->getMessage())); + } catch (StateException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (InputException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); } return 'Success!'; // TODO we should return cart here } -} \ No newline at end of file +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 45f98daeaed06..730a54377b370 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,9 +6,9 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") - applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") - removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") + applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") + removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") @@ -53,7 +53,7 @@ input SetShippingMethodsOnCartInput { } input ShippingMethodForAddressInput { - cart_address_id: int + cart_address_id: Int! shipping_carrier_code: String! shipping_method_code: String! } From 8f36157cae89483469d567710aaba1d728328dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sat, 6 Oct 2018 16:57:46 +0200 Subject: [PATCH 0389/1415] fix issue 12399 --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index bad1118e3ae72..4d3b36c7fe69c 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -61,6 +61,17 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); + + $filterValues = ['from_date' => $this->_dateFilter]; + if ($this->getRequest()->getParam('to_date')) { + $filterValues['to_date'] = $this->_dateFilter; + } + $inputFilter = new \Zend_Filter_Input( + $filterValues, + [], + $data + ); + $data = $inputFilter->getUnescaped(); $id = $this->getRequest()->getParam('rule_id'); if ($id) { $model = $ruleRepository->get($id); From 320c0aab8787cfc3f63a4f170f4711c614c0e715 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Sun, 7 Oct 2018 08:48:28 +0300 Subject: [PATCH 0390/1415] Support of error pages behind a load balancer that serves HTTPS Use strict comparison --- pub/errors/processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 3958c6d152c9d..2bb25f3fd587d 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,7 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] !== 'off') || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); $url = ($isSecure ? 'https://' : 'http://') . $host; From 0d97a1600e3ccb3b3cf5c024a971b6f7b3597a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sun, 7 Oct 2018 10:41:26 +0200 Subject: [PATCH 0391/1415] fix documentation for phpcs --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 4d3b36c7fe69c..b09598d4fd76f 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -14,7 +14,8 @@ use Magento\Framework\App\Request\DataPersistorInterface; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * Save action for catalog rule + * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface { @@ -40,7 +41,9 @@ public function __construct( } /** - * @return void + * Execute save action from catalog rule + * + * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() From 745e7575a7e41fa5dfd086d0ad067c990781c553 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:12:30 +0300 Subject: [PATCH 0392/1415] MAGETWO-81469: Cached Config is Different From DB --- .../Magento/Config/App/Config/Type/System.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index f5d109b198d5a..d120b80fc2750 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -121,7 +121,7 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->loadAllData(), $this->data); + $this->data = array_replace_recursive($this->data, $this->loadAllData()); return $this->data; } @@ -142,7 +142,7 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { $data = $this->readData(); - $this->data = array_replace_recursive($data, $this->data); + $this->data = $this->postProcessor->process($data); } return $this->data[$pathParts[0]]; @@ -152,7 +152,7 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->loadDefaultScopeData($scopeType), $this->data); + $this->data = array_replace_recursive($this->data, $this->loadDefaultScopeData($scopeType)); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -162,10 +162,7 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); - - if (!isset($this->data[$scopeType][$scopeId])) { - $this->data = array_replace_recursive($scopeData, $this->data); - } + $this->data = array_replace_recursive($this->data, $scopeData); } return isset($this->data[$scopeType][$scopeId]) @@ -187,6 +184,7 @@ private function loadAllData() } else { $data = $this->serializer->unserialize($cachedData); } + $data = $this->postProcessor->process($data); return $data; } @@ -207,6 +205,7 @@ private function loadDefaultScopeData($scopeType) } else { $data = [$scopeType => $this->serializer->unserialize($cachedData)]; } + $data = $this->postProcessor->process($data); return $data; } @@ -237,6 +236,7 @@ private function loadScopeData($scopeType, $scopeId) } else { $data = [$scopeType => [$scopeId => $this->serializer->unserialize($cachedData)]]; } + $data = $this->postProcessor->process($data); return $data; } @@ -308,9 +308,6 @@ private function getDataByPathParts($data, $pathParts) private function readData(): array { $this->data = $this->reader->read(); - $this->data = $this->postProcessor->process( - $this->data - ); return $this->data; } From 2f655dd50fb276ff5d567165074264a5a6b778bd Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:14:11 +0300 Subject: [PATCH 0393/1415] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index d120b80fc2750..ab4e985ee4a6e 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -101,6 +101,8 @@ public function __construct( } /** + * Get config value by path. + * * System configuration is separated by scopes (default, websites, stores). Configuration of a scope is inherited * from its parent scope (store inherits website). * @@ -243,6 +245,7 @@ private function loadScopeData($scopeType, $scopeId) /** * Cache configuration data. + * * Caches data per scope to avoid reading data for all scopes on every request * * @param array $data From e1e7b14ecb70e295f0e9a9cdc806712fe3a16c57 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:59:57 +0300 Subject: [PATCH 0394/1415] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index ab4e985ee4a6e..1fff1aedcfac1 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -123,7 +123,9 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->data, $this->loadAllData()); + $this->data = array_replace_recursive($this->data, $allData = $this->loadAllData()); + $allData = $this->postProcessor->process($allData); + $this->data = array_replace_recursive($this->data, $allData); return $this->data; } @@ -154,7 +156,9 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->data, $this->loadDefaultScopeData($scopeType)); + $this->data = array_replace_recursive($this->data, $scopeData = $this->loadDefaultScopeData($scopeType)); + $scopeData = $this->postProcessor->process($scopeData); + $this->data = array_replace_recursive($this->data, $scopeData); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -165,6 +169,8 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); $this->data = array_replace_recursive($this->data, $scopeData); + $scopeData = $this->postProcessor->process($scopeData); + $this->data = array_replace_recursive($this->data, $scopeData); } return isset($this->data[$scopeType][$scopeId]) @@ -186,7 +192,6 @@ private function loadAllData() } else { $data = $this->serializer->unserialize($cachedData); } - $data = $this->postProcessor->process($data); return $data; } @@ -207,7 +212,6 @@ private function loadDefaultScopeData($scopeType) } else { $data = [$scopeType => $this->serializer->unserialize($cachedData)]; } - $data = $this->postProcessor->process($data); return $data; } @@ -238,7 +242,6 @@ private function loadScopeData($scopeType, $scopeId) } else { $data = [$scopeType => [$scopeId => $this->serializer->unserialize($cachedData)]]; } - $data = $this->postProcessor->process($data); return $data; } From e4c752b54df53234c6501d6080a729a3fc038a86 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 13:06:28 +0300 Subject: [PATCH 0395/1415] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 1fff1aedcfac1..c80b2141294e6 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -156,7 +156,10 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->data, $scopeData = $this->loadDefaultScopeData($scopeType)); + $this->data = array_replace_recursive( + $this->data, + $scopeData = $this->loadDefaultScopeData($scopeType) + ); $scopeData = $this->postProcessor->process($scopeData); $this->data = array_replace_recursive($this->data, $scopeData); } From 2f4ad2f42dba88f53eb075b041465662061e2278 Mon Sep 17 00:00:00 2001 From: Roman Strilenko <strelenko.roman@gmail.com> Date: Sun, 7 Oct 2018 12:12:04 +0200 Subject: [PATCH 0396/1415] MAGENTO-18131: Fixed EAV attributes values query --- .../Magento/Eav/Model/Entity/Collection/AbstractCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php index fb1931ed57cb7..0eb87374f3ba3 100644 --- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php +++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php @@ -1243,7 +1243,7 @@ protected function _getLoadAttributesSelect($table, $attributeIds = []) if ($entity->getEntityTable() == \Magento\Eav\Model\Entity::DEFAULT_ENTITY_TABLE && $entity->getTypeId()) { $select->where( - 'entity_type_id =?', + 't_d.entity_type_id =?', $entity->getTypeId() ); } From cbea532e42e33e9e7778f3fd732a41404efb80b2 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 13:48:52 +0300 Subject: [PATCH 0397/1415] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index c80b2141294e6..2b65c2791365a 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -123,9 +123,7 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->data, $allData = $this->loadAllData()); - $allData = $this->postProcessor->process($allData); - $this->data = array_replace_recursive($this->data, $allData); + $this->data = array_replace_recursive($this->data, $this->loadAllData()); return $this->data; } @@ -146,7 +144,7 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { $data = $this->readData(); - $this->data = $this->postProcessor->process($data); + $this->data = array_replace_recursive($this->data, $this->postProcessor->process($data)); } return $this->data[$pathParts[0]]; @@ -194,9 +192,10 @@ private function loadAllData() $data = $this->readData(); } else { $data = $this->serializer->unserialize($cachedData); + $this->data = $data; } - return $data; + return $this->postProcessor->process($data); } /** From d4735edfa9ba6fb98007c9073339025571297d22 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Sun, 7 Oct 2018 14:19:30 +0300 Subject: [PATCH 0398/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...ontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 0283f6bd108ec..9d805589eb831 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -51,7 +51,7 @@ <!--Click "Save Addresses" --> <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> <waitForPageLoad stepKey="waitForAddressSaved"/> - <dontSeeElement selector="{{CheckoutNewAddressModalPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + <dontSeeElement selector="{{StorefrontCheckoutAddressPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> <!--Select Shipping Rate "Flat Rate"--> <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> @@ -63,7 +63,7 @@ </actionGroup> <!--Close Popup and click next--> - <click selector="{{CheckoutNewAddressModalPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <click selector="{{StorefrontCheckoutAddressPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> From ba703d7d22923239c4519616b6c6ab21124ec8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sun, 7 Oct 2018 14:24:52 +0200 Subject: [PATCH 0399/1415] fix one line for static test --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index b09598d4fd76f..d770d674bb3e6 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -15,6 +15,7 @@ /** * Save action for catalog rule + * * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface From d11ef56535da099158cc302eff104c2b466f2af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Mon, 8 Oct 2018 08:09:14 +0200 Subject: [PATCH 0400/1415] fix: add SuppressWarnings again --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index d770d674bb3e6..0ff12faf54cbf 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -15,8 +15,8 @@ /** * Save action for catalog rule - * - * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface { From 34e8f843b314da86a4294522e74142b82b89be05 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Mon, 8 Oct 2018 10:24:06 +0300 Subject: [PATCH 0401/1415] MAGETWO-95450: Unskip MFTF tests StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest --- ...ntTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml index 9bc44dec0b5b8..9ea4793242fe8 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml @@ -18,9 +18,6 @@ <testCaseId value="MAGETWO-41930"/> <group value="checkout"/> <group value="tax"/> - <skip> - <issueId value="MAGETWO-90966"/> - </skip> </annotations> <before> <!-- Preconditions --> From 18af30faafb267783d004617e75f998c97e3d84f Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Mon, 8 Oct 2018 10:55:38 +0300 Subject: [PATCH 0402/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...PlaceOrderWithNewAddressesThatWasEditedTest.xml | 2 +- .../StorefrontCustomerLogoutActionGroup.xml | 14 ++++++++++++++ .../Mftf/Page/StorefrontCustomerLogoutPage.xml | 11 +++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 9d805589eb831..274e32653d8e6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -86,6 +86,6 @@ selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> <!--Logout from customer account--> - <amOnPage url="customer/account/logout/" stepKey="logoutCustomer"/> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> </test> </tests> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml new file mode 100644 index 0000000000000..5497b083ab5ad --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontCustomerLogoutActionGroup"> + <amOnPage url="{{StorefrontCustomerLogoutPage.url}}" stepKey="storefrontSignOut"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml new file mode 100644 index 0000000000000..b3cea8f2c2939 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="StorefrontCustomerLogoutPage" url="customer/account/logout/" area="storefront" module="Magento_Customer"/> +</pages> From 65b4bf1be923344c575effb445444ac542f00712 Mon Sep 17 00:00:00 2001 From: Vincent MARMIESSE <vincent.marmiesse@ph2m.com> Date: Thu, 4 Oct 2018 19:32:37 +0200 Subject: [PATCH 0403/1415] Add class into image builder --- .../Magento/Catalog/Block/Product/Image.php | 3 +++ .../Catalog/Block/Product/ImageFactory.php | 24 +++++++++++++++---- .../Unit/Block/Product/ImageFactoryTest.php | 7 ++++-- .../product/image_with_borders.phtml | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/Image.php b/app/code/Magento/Catalog/Block/Product/Image.php index 20a556ab41451..7a7f9c0affc7d 100644 --- a/app/code/Magento/Catalog/Block/Product/Image.php +++ b/app/code/Magento/Catalog/Block/Product/Image.php @@ -6,6 +6,8 @@ namespace Magento\Catalog\Block\Product; /** + * Product image block + * * @api * @method string getImageUrl() * @method string getWidth() @@ -13,6 +15,7 @@ * @method string getLabel() * @method float getRatio() * @method string getCustomAttributes() + * @method string getClass() * @since 100.0.2 */ class Image extends \Magento\Framework\View\Element\Template diff --git a/app/code/Magento/Catalog/Block/Product/ImageFactory.php b/app/code/Magento/Catalog/Block/Product/ImageFactory.php index f9a576367ddeb..aa303af656a5b 100644 --- a/app/code/Magento/Catalog/Block/Product/ImageFactory.php +++ b/app/code/Magento/Catalog/Block/Product/ImageFactory.php @@ -77,16 +77,29 @@ private function getStringCustomAttributes(array $attributes): string { $result = []; foreach ($attributes as $name => $value) { - $result[] = $name . '="' . $value . '"'; + if ($name != 'class') { + $result[] = $name . '="' . $value . '"'; + } } return !empty($result) ? implode(' ', $result) : ''; } + /** + * Retrieve image class for HTML element + * + * @param array $attributes + * @return string + */ + private function getClass(array $attributes): string + { + return $attributes['class'] ?? 'product-image-photo'; + } + /** * Calculate image ratio * - * @param $width - * @param $height + * @param int $width + * @param int $height * @return float */ private function getRatio(int $width, int $height): float @@ -98,8 +111,9 @@ private function getRatio(int $width, int $height): float } /** - * @param Product $product + * Get image label * + * @param Product $product * @param string $imageType * @return string */ @@ -114,6 +128,7 @@ private function getLabel(Product $product, string $imageType): string /** * Create image block from product + * * @param Product $product * @param string $imageId * @param array|null $attributes @@ -154,6 +169,7 @@ public function create(Product $product, string $imageId, array $attributes = nu 'label' => $this->getLabel($product, $imageMiscParams['image_type']), 'ratio' => $this->getRatio($imageMiscParams['image_width'], $imageMiscParams['image_height']), 'custom_attributes' => $this->getStringCustomAttributes($attributes), + 'class' => $this->getClass($attributes), 'product_id' => $product->getId() ], ]; diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php index 8a42865a3fe4d..95b06e40602bf 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php @@ -145,7 +145,8 @@ private function getTestDataWithoutAttributes(): array 'label' => 'test_image_label', 'ratio' => 1, 'custom_attributes' => '', - 'product_id' => null + 'product_id' => null, + 'class' => 'product-image-photo' ], ], ]; @@ -190,6 +191,7 @@ private function getTestDataWithAttributes(): array 'custom_attributes' => [ 'name_1' => 'value_1', 'name_2' => 'value_2', + 'class' => 'my-class' ], ], 'expected' => [ @@ -201,7 +203,8 @@ private function getTestDataWithAttributes(): array 'label' => 'test_product_name', 'ratio' => 0.5, // <== 'custom_attributes' => 'name_1="value_1" name_2="value_2"', - 'product_id' => null + 'product_id' => null, + 'class' => 'my-class' ], ], ]; diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml index 74a0b2d7cf1a3..8a907bd54aa6a 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml @@ -10,7 +10,7 @@ style="width:<?= /* @escapeNotVerified */ $block->getWidth() ?>px;"> <span class="product-image-wrapper" style="padding-bottom: <?= /* @escapeNotVerified */ ($block->getRatio() * 100) ?>%;"> - <img class="product-image-photo" + <img class="<?= /* @escapeNotVerified */ $block->getClass() ?>" <?= /* @escapeNotVerified */ $block->getCustomAttributes() ?> src="<?= /* @escapeNotVerified */ $block->getImageUrl() ?>" max-width="<?= /* @escapeNotVerified */ $block->getWidth() ?>" From c510fd217e7bf27cca98dfc49daf18a2ae56774b Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 11:35:11 +0300 Subject: [PATCH 0404/1415] MAGETWO-81469: Cached Config is Different From DB --- .../App/Config/MetadataConfigTypeProcessor.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php index 6eb5fd7e9d3b1..0b6630c4d6c0a 100644 --- a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php +++ b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php @@ -114,9 +114,14 @@ private function processScopeData( $scopeCode = null ) { foreach ($this->_metadata as $path => $metadata) { - $configPath = $this->configPathResolver->resolve($path, $scope, $scopeCode); - if (!empty($this->configSource->get($configPath))) { - continue; + try { + $configPath = $this->configPathResolver->resolve($path, $scope, $scopeCode); + if (!empty($this->configSource->get($configPath))) { + continue; + } + } catch (\Throwable $exception) { + //Failed to load scopes or config source, perhaps config data received is outdated. + return $data; } /** @var \Magento\Framework\App\Config\Data\ProcessorInterface $processor */ $processor = $this->_processorFactory->get($metadata['backendModel']); From 4da3b5410e7525a4ea00b4df7c1c6f5a3f2ae5b4 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Mon, 8 Oct 2018 11:56:39 +0300 Subject: [PATCH 0405/1415] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...tCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 274e32653d8e6..cc5e723c72ea0 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -26,6 +26,9 @@ <createData entity="Simple_US_Customer" stepKey="createCustomer"/> </before> <after> + <!--Logout from customer account--> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> @@ -84,8 +87,5 @@ selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> - - <!--Logout from customer account--> - <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> </test> </tests> From 57807206530e19e86501d2f2248911464f03ee99 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 12:39:25 +0300 Subject: [PATCH 0406/1415] MAGETWO-81469: Cached Config is Different From DB --- .../Framework/App/Config/MetadataConfigTypeProcessor.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php index 0b6630c4d6c0a..bc23032903d23 100644 --- a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php +++ b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php @@ -11,6 +11,9 @@ use Magento\Framework\App\Config\Spi\PostProcessorInterface; use Magento\Framework\App\ObjectManager; +/** + * Post-process config values using their backend models. + */ class MetadataConfigTypeProcessor implements PostProcessorInterface { /** From 96f608cca3e89f21bfc4a15e84c18220e5b99dca Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 13:17:58 +0300 Subject: [PATCH 0407/1415] MAGETWO-94173: Disable backups by default --- .../Block/System/Store/Delete/Form.php | 34 ++- .../Controller/Adminhtml/System/Store.php | 3 + .../Backup/Controller/Adminhtml/Index.php | 26 +- .../Controller/Adminhtml/Index/Disabled.php | 48 ++++ app/code/Magento/Backup/Cron/SystemBackup.php | 7 + app/code/Magento/Backup/Helper/Data.php | 13 + app/code/Magento/Backup/Model/Db.php | 38 ++- .../Test/Unit/Cron/SystemBackupTest.php | 128 ++------- .../Magento/Backup/Test/Unit/Model/DbTest.php | 243 ------------------ .../Magento/Backup/etc/adminhtml/system.xml | 12 +- app/code/Magento/Backup/etc/config.xml | 16 ++ .../layout/backup_index_disabled.xml | 17 ++ .../adminhtml/templates/backup/disabled.phtml | 7 + .../Backup/Test/Repository/ConfigData.xml | 24 ++ .../Backup/Test/TestCase/NavigateMenuTest.xml | 16 -- .../Test/TestCase/DeleteStoreEntityTest.php | 11 +- .../TestCase/DeleteStoreGroupEntityTest.php | 11 +- .../Test/TestCase/DeleteWebsiteEntityTest.php | 11 +- .../TestStep/DeleteWebsitesEntityStep.php | 16 ++ .../Magento/Framework/Backup/DbTest.php | 1 + .../Framework/Backup/BackupInterface.php | 2 + .../Framework/Backup/Db/BackupDbInterface.php | 2 + .../Framework/Backup/Db/BackupInterface.php | 2 + 23 files changed, 304 insertions(+), 384 deletions(-) create mode 100644 app/code/Magento/Backup/Controller/Adminhtml/Index/Disabled.php delete mode 100644 app/code/Magento/Backup/Test/Unit/Model/DbTest.php create mode 100644 app/code/Magento/Backup/etc/config.xml create mode 100644 app/code/Magento/Backup/view/adminhtml/layout/backup_index_disabled.xml create mode 100644 app/code/Magento/Backup/view/adminhtml/templates/backup/disabled.phtml create mode 100644 dev/tests/functional/tests/app/Magento/Backup/Test/Repository/ConfigData.xml delete mode 100644 dev/tests/functional/tests/app/Magento/Backup/Test/TestCase/NavigateMenuTest.xml diff --git a/app/code/Magento/Backend/Block/System/Store/Delete/Form.php b/app/code/Magento/Backend/Block/System/Store/Delete/Form.php index e479e8f560dae..47a156c16ce3e 100644 --- a/app/code/Magento/Backend/Block/System/Store/Delete/Form.php +++ b/app/code/Magento/Backend/Block/System/Store/Delete/Form.php @@ -5,6 +5,9 @@ */ namespace Magento\Backend\Block\System\Store\Delete; +use Magento\Backup\Helper\Data as BackupHelper; +use Magento\Framework\App\ObjectManager; + /** * Adminhtml cms block edit form * @@ -12,6 +15,25 @@ */ class Form extends \Magento\Backend\Block\Widget\Form\Generic { + /** + * @var BackupHelper + */ + private $backup; + + /** + * @inheritDoc + */ + public function __construct( + \Magento\Backend\Block\Template\Context $context, + \Magento\Framework\Registry $registry, + \Magento\Framework\Data\FormFactory $formFactory, + array $data = [], + ?BackupHelper $backup = null + ) { + parent::__construct($context, $registry, $formFactory, $data); + $this->backup = $backup ?? ObjectManager::getInstance()->get(BackupHelper::class); + } + /** * Init form * @@ -25,7 +47,7 @@ protected function _construct() } /** - * {@inheritdoc} + * @inheritDoc */ protected function _prepareForm() { @@ -45,6 +67,12 @@ protected function _prepareForm() $fieldset->addField('item_id', 'hidden', ['name' => 'item_id', 'value' => $dataObject->getId()]); + $backupOptions = ['0' => __('No')]; + $backupSelected = '0'; + if ($this->backup->isEnabled()) { + $backupOptions['1'] = __('Yes'); + $backupSelected = '1'; + } $fieldset->addField( 'create_backup', 'select', @@ -52,8 +80,8 @@ protected function _prepareForm() 'label' => __('Create DB Backup'), 'title' => __('Create DB Backup'), 'name' => 'create_backup', - 'options' => ['1' => __('Yes'), '0' => __('No')], - 'value' => '1' + 'options' => $backupOptions, + 'value' => $backupSelected ] ); diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php index 0beeb5168b6d1..a9be14b77b29c 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php @@ -14,6 +14,7 @@ * Store controller * * @author Magento Core Team <core@magentocommerce.com> + * @SuppressWarnings(PHPMD.AllPurposeAction) */ abstract class Store extends Action { @@ -86,6 +87,8 @@ protected function createPage() * Backup database * * @return bool + * + * @deprecated Backup module is to be removed. */ protected function _backupDatabase() { diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index dcafbc7370d2d..1878c7abc9dd5 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -5,12 +5,16 @@ */ namespace Magento\Backup\Controller\Adminhtml; +use Magento\Backup\Helper\Data as Helper; +use Magento\Framework\App\ObjectManager; + /** * Backup admin controller * * @author Magento Core Team <core@magentocommerce.com> * @api * @since 100.0.2 + * @SuppressWarnings(PHPMD.AllPurposeAction) */ abstract class Index extends \Magento\Backend\App\Action { @@ -48,6 +52,11 @@ abstract class Index extends \Magento\Backend\App\Action */ protected $maintenanceMode; + /** + * @var Helper + */ + private $helper; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Registry $coreRegistry @@ -55,6 +64,7 @@ abstract class Index extends \Magento\Backend\App\Action * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory * @param \Magento\Backup\Model\BackupFactory $backupModelFactory * @param \Magento\Framework\App\MaintenanceMode $maintenanceMode + * @param Helper|null $helper */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -62,13 +72,27 @@ public function __construct( \Magento\Framework\Backup\Factory $backupFactory, \Magento\Framework\App\Response\Http\FileFactory $fileFactory, \Magento\Backup\Model\BackupFactory $backupModelFactory, - \Magento\Framework\App\MaintenanceMode $maintenanceMode + \Magento\Framework\App\MaintenanceMode $maintenanceMode, + ?Helper $helper = null ) { $this->_coreRegistry = $coreRegistry; $this->_backupFactory = $backupFactory; $this->_fileFactory = $fileFactory; $this->_backupModelFactory = $backupModelFactory; $this->maintenanceMode = $maintenanceMode; + $this->helper = $helper ?? ObjectManager::getInstance()->get(Helper::class); parent::__construct($context); } + + /** + * @inheritDoc + */ + public function dispatch(\Magento\Framework\App\RequestInterface $request) + { + if (!$this->helper->isEnabled()) { + return $this->_redirect('*/*/disabled'); + } + + return parent::dispatch($request); + } } diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Disabled.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Disabled.php new file mode 100644 index 0000000000000..f6fe430ae0838 --- /dev/null +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Disabled.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Backup\Controller\Adminhtml\Index; + +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\View\Result\PageFactory; + +/** + * Inform that backup is disabled. + */ +class Disabled extends Action implements HttpGetActionInterface +{ + /** + * @see _isAllowed() + */ + const ADMIN_RESOURCE = 'Magento_Backend::backup'; + + /** + * @var PageFactory + */ + private $pageFactory; + + /** + * @param Context $context + * @param PageFactory $pageFactory + */ + public function __construct(Context $context, PageFactory $pageFactory) + { + parent::__construct($context); + $this->pageFactory = $pageFactory; + } + + /** + * @inheritDoc + */ + public function execute() + { + return $this->pageFactory->create(); + } +} diff --git a/app/code/Magento/Backup/Cron/SystemBackup.php b/app/code/Magento/Backup/Cron/SystemBackup.php index 750262ab1c14a..9502377a39d06 100644 --- a/app/code/Magento/Backup/Cron/SystemBackup.php +++ b/app/code/Magento/Backup/Cron/SystemBackup.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Store\Model\ScopeInterface; +/** + * Performs scheduled backup. + */ class SystemBackup { const XML_PATH_BACKUP_ENABLED = 'system/backup/enabled'; @@ -101,6 +104,10 @@ public function __construct( */ public function execute() { + if (!$this->_backupData->isEnabled()) { + return $this; + } + if (!$this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_ENABLED, ScopeInterface::SCOPE_STORE)) { return $this; } diff --git a/app/code/Magento/Backup/Helper/Data.php b/app/code/Magento/Backup/Helper/Data.php index b0bc292ffe926..c6df6a7366852 100644 --- a/app/code/Magento/Backup/Helper/Data.php +++ b/app/code/Magento/Backup/Helper/Data.php @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Backup\Helper; use Magento\Framework\App\Filesystem\DirectoryList; @@ -285,4 +288,14 @@ public function extractDataFromFilename($filename) return $result; } + + /** + * Is backup functionality enabled. + * + * @return bool + */ + public function isEnabled(): bool + { + return $this->scopeConfig->isSetFlag('system/backup/functionality_enabled'); + } } diff --git a/app/code/Magento/Backup/Model/Db.php b/app/code/Magento/Backup/Model/Db.php index 8fbd5da1c9842..bc458a0a8e4bf 100644 --- a/app/code/Magento/Backup/Model/Db.php +++ b/app/code/Magento/Backup/Model/Db.php @@ -5,11 +5,16 @@ */ namespace Magento\Backup\Model; +use Magento\Backup\Helper\Data as Helper; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\RuntimeException; + /** * Database backup model * * @api * @since 100.0.2 + * @deprecated Backup module is to be removed. */ class Db implements \Magento\Framework\Backup\Db\BackupDbInterface { @@ -33,16 +38,24 @@ class Db implements \Magento\Framework\Backup\Db\BackupDbInterface */ protected $_resource = null; + /** + * @var Helper + */ + private $helper; + /** * @param \Magento\Backup\Model\ResourceModel\Db $resourceDb * @param \Magento\Framework\App\ResourceConnection $resource + * @param Helper|null $helper */ public function __construct( \Magento\Backup\Model\ResourceModel\Db $resourceDb, - \Magento\Framework\App\ResourceConnection $resource + \Magento\Framework\App\ResourceConnection $resource, + ?Helper $helper = null ) { $this->_resourceDb = $resourceDb; $this->_resource = $resource; + $this->helper = $helper ?? ObjectManager::getInstance()->get(Helper::class); } /** @@ -63,6 +76,8 @@ public function getResource() } /** + * Tables list. + * * @return array */ public function getTables() @@ -71,6 +86,8 @@ public function getTables() } /** + * Command to recreate given table. + * * @param string $tableName * @param bool $addDropIfExists * @return string @@ -81,6 +98,8 @@ public function getTableCreateScript($tableName, $addDropIfExists = false) } /** + * Generate table's data dump. + * * @param string $tableName * @return string */ @@ -90,6 +109,8 @@ public function getTableDataDump($tableName) } /** + * Header for dumps. + * * @return string */ public function getHeader() @@ -98,6 +119,8 @@ public function getHeader() } /** + * Footer for dumps. + * * @return string */ public function getFooter() @@ -106,6 +129,8 @@ public function getFooter() } /** + * Get backup SQL. + * * @return string */ public function renderSql() @@ -124,13 +149,14 @@ public function renderSql() } /** - * Create backup and stream write to adapter - * - * @param \Magento\Framework\Backup\Db\BackupInterface $backup - * @return $this + * @inheritDoc */ public function createBackup(\Magento\Framework\Backup\Db\BackupInterface $backup) { + if (!$this->helper->isEnabled()) { + throw new RuntimeException(__('Backup functionality is disabled')); + } + $backup->open(true); $this->getResource()->beginTransaction(); @@ -179,8 +205,6 @@ public function createBackup(\Magento\Framework\Backup\Db\BackupInterface $backu $this->getResource()->commitTransaction(); $backup->close(); - - return $this; } /** diff --git a/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php b/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php index b7dfb30c0a1b3..56a7ef42a0bc2 100644 --- a/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php +++ b/app/code/Magento/Backup/Test/Unit/Cron/SystemBackupTest.php @@ -3,134 +3,44 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Backup\Test\Unit\Cron; +use Magento\Backup\Cron\SystemBackup; +use PHPUnit\Framework\TestCase; +use Magento\Backup\Helper\Data as Helper; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -class SystemBackupTest extends \PHPUnit\Framework\TestCase +class SystemBackupTest extends TestCase { /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager - */ - private $objectManager; - - /** - * @var \Magento\Backup\Cron\SystemBackup - */ - private $systemBackup; - - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $scopeConfigMock; - - /** - * @var \Magento\Backup\Helper\Data|\PHPUnit_Framework_MockObject_MockObject - */ - private $backupDataMock; - - /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject - */ - private $registryMock; - - /** - * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Helper|\PHPUnit_Framework_MockObject_MockObject */ - private $loggerMock; + private $helperMock; /** - * Filesystem facade - * - * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject + * @var SystemBackup */ - private $filesystemMock; + private $cron; /** - * @var \Magento\Framework\Backup\Factory|\PHPUnit_Framework_MockObject_MockObject + * @inheritDoc */ - private $backupFactoryMock; - - /** - * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject - */ - private $maintenanceModeMock; - - /** - * @var \Magento\Framework\Backup\Db|\PHPUnit_Framework_MockObject_MockObject - */ - private $backupDbMock; - - /** - * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $objectManagerMock; - protected function setUp() { - $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->getMock(); - $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) - ->getMock(); - $this->backupDataMock = $this->getMockBuilder(\Magento\Backup\Helper\Data::class) - ->disableOriginalConstructor() - ->getMock(); - $this->registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->getMock(); - $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) - ->getMock(); - $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) - ->disableOriginalConstructor() - ->getMock(); - $this->backupFactoryMock = $this->getMockBuilder(\Magento\Framework\Backup\Factory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->maintenanceModeMock = $this->getMockBuilder(\Magento\Framework\App\MaintenanceMode::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->backupDbMock = $this->getMockBuilder(\Magento\Framework\Backup\Db::class) - ->disableOriginalConstructor() - ->getMock(); - $this->backupDbMock->expects($this->any())->method('setBackupExtension')->willReturnSelf(); - $this->backupDbMock->expects($this->any())->method('setTime')->willReturnSelf(); - $this->backupDbMock->expects($this->any())->method('setBackupsDir')->willReturnSelf(); - - $this->objectManager = new ObjectManager($this); - $this->systemBackup = $this->objectManager->getObject( - \Magento\Backup\Cron\SystemBackup::class, - [ - 'backupData' => $this->backupDataMock, - 'coreRegistry' => $this->registryMock, - 'logger' => $this->loggerMock, - 'scopeConfig' => $this->scopeConfigMock, - 'filesystem' => $this->filesystemMock, - 'backupFactory' => $this->backupFactoryMock, - 'maintenanceMode' => $this->maintenanceModeMock, - ] - ); + $objectManager = new ObjectManager($this); + $this->helperMock = $this->getMockBuilder(Helper::class)->disableOriginalConstructor()->getMock(); + $this->cron = $objectManager->getObject(SystemBackup::class, ['backupData' => $this->helperMock]); } /** - * @expectedException \Exception + * Test that cron doesn't do anything if backups are disabled. */ - public function testExecuteThrowsException() + public function testDisabled() { - $type = 'db'; - $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->willReturn(true); - - $this->scopeConfigMock->expects($this->once())->method('getValue') - ->with('system/backup/type', 'store') - ->willReturn($type); - - $this->backupFactoryMock->expects($this->once())->method('create')->willReturn($this->backupDbMock); - - $this->backupDbMock->expects($this->once())->method('create')->willThrowException(new \Exception); - - $this->backupDataMock->expects($this->never())->method('getCreateSuccessMessageByType')->with($type); - $this->loggerMock->expects($this->never())->method('info'); - - $this->systemBackup->execute(); + $this->helperMock->expects($this->any())->method('isEnabled')->willReturn(false); + $this->cron->execute(); } } diff --git a/app/code/Magento/Backup/Test/Unit/Model/DbTest.php b/app/code/Magento/Backup/Test/Unit/Model/DbTest.php deleted file mode 100644 index 0cab5f0ad1e99..0000000000000 --- a/app/code/Magento/Backup/Test/Unit/Model/DbTest.php +++ /dev/null @@ -1,243 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Backup\Test\Unit\Model; - -use Magento\Backup\Model\Db; -use Magento\Backup\Model\ResourceModel\Db as DbResource; -use Magento\Framework\App\ResourceConnection; -use Magento\Framework\Backup\Db\BackupInterface; -use Magento\Framework\DataObject; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; - -class DbTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var ObjectManager - */ - private $objectManager; - - /** - * @var Db - */ - private $dbModel; - - /** - * @var DbResource|\PHPUnit_Framework_MockObject_MockObject - */ - private $dbResourceMock; - - /** - * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject - */ - private $connectionResourceMock; - - protected function setUp() - { - $this->dbResourceMock = $this->getMockBuilder(DbResource::class) - ->disableOriginalConstructor() - ->getMock(); - $this->connectionResourceMock = $this->getMockBuilder(ResourceConnection::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManager = new ObjectManager($this); - $this->dbModel = $this->objectManager->getObject( - Db::class, - [ - 'resourceDb' => $this->dbResourceMock, - 'resource' => $this->connectionResourceMock - ] - ); - } - - public function testGetResource() - { - self::assertEquals($this->dbResourceMock, $this->dbModel->getResource()); - } - - public function testGetTables() - { - $tables = []; - $this->dbResourceMock->expects($this->once()) - ->method('getTables') - ->willReturn($tables); - - self::assertEquals($tables, $this->dbModel->getTables()); - } - - public function testGetTableCreateScript() - { - $tableName = 'some_table'; - $script = 'script'; - $this->dbResourceMock->expects($this->once()) - ->method('getTableCreateScript') - ->with($tableName, false) - ->willReturn($script); - - self::assertEquals($script, $this->dbModel->getTableCreateScript($tableName, false)); - } - - public function testGetTableDataDump() - { - $tableName = 'some_table'; - $dump = 'dump'; - $this->dbResourceMock->expects($this->once()) - ->method('getTableDataDump') - ->with($tableName) - ->willReturn($dump); - - self::assertEquals($dump, $this->dbModel->getTableDataDump($tableName)); - } - - public function testGetHeader() - { - $header = 'header'; - $this->dbResourceMock->expects($this->once()) - ->method('getHeader') - ->willReturn($header); - - self::assertEquals($header, $this->dbModel->getHeader()); - } - - public function testGetFooter() - { - $footer = 'footer'; - $this->dbResourceMock->expects($this->once()) - ->method('getFooter') - ->willReturn($footer); - - self::assertEquals($footer, $this->dbModel->getFooter()); - } - - public function testRenderSql() - { - $header = 'header'; - $script = 'script'; - $tableName = 'some_table'; - $tables = [$tableName, $tableName]; - $dump = 'dump'; - $footer = 'footer'; - - $this->dbResourceMock->expects($this->once()) - ->method('getTables') - ->willReturn($tables); - $this->dbResourceMock->expects($this->once()) - ->method('getHeader') - ->willReturn($header); - $this->dbResourceMock->expects($this->exactly(2)) - ->method('getTableCreateScript') - ->with($tableName, true) - ->willReturn($script); - $this->dbResourceMock->expects($this->exactly(2)) - ->method('getTableDataDump') - ->with($tableName) - ->willReturn($dump); - $this->dbResourceMock->expects($this->once()) - ->method('getFooter') - ->willReturn($footer); - - self::assertEquals( - $header . $script . $dump . $script . $dump . $footer, - $this->dbModel->renderSql() - ); - } - - public function testCreateBackup() - { - /** @var BackupInterface|\PHPUnit_Framework_MockObject_MockObject $backupMock */ - $backupMock = $this->getMockBuilder(BackupInterface::class)->getMock(); - /** @var DataObject $tableStatus */ - $tableStatus = new DataObject(); - - $tableName = 'some_table'; - $tables = [$tableName]; - $header = 'header'; - $footer = 'footer'; - $dropSql = 'drop_sql'; - $createSql = 'create_sql'; - $beforeSql = 'before_sql'; - $afterSql = 'after_sql'; - $dataSql = 'data_sql'; - $foreignKeysSql = 'foreign_keys'; - $triggersSql = 'triggers_sql'; - $rowsCount = 2; - $dataLength = 1; - - $this->dbResourceMock->expects($this->once()) - ->method('beginTransaction'); - $this->dbResourceMock->expects($this->once()) - ->method('commitTransaction'); - $this->dbResourceMock->expects($this->once()) - ->method('getTables') - ->willReturn($tables); - $this->dbResourceMock->expects($this->once()) - ->method('getTableDropSql') - ->willReturn($dropSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableCreateSql') - ->with($tableName, false) - ->willReturn($createSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableDataBeforeSql') - ->with($tableName) - ->willReturn($beforeSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableDataAfterSql') - ->with($tableName) - ->willReturn($afterSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableDataSql') - ->with($tableName, $rowsCount, 0) - ->willReturn($dataSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableStatus') - ->with($tableName) - ->willReturn($tableStatus); - $this->dbResourceMock->expects($this->once()) - ->method('getTables') - ->willReturn($createSql); - $this->dbResourceMock->expects($this->once()) - ->method('getHeader') - ->willReturn($header); - $this->dbResourceMock->expects($this->once()) - ->method('getTableHeader') - ->willReturn($header); - $this->dbResourceMock->expects($this->once()) - ->method('getFooter') - ->willReturn($footer); - $this->dbResourceMock->expects($this->once()) - ->method('getTableForeignKeysSql') - ->willReturn($foreignKeysSql); - $this->dbResourceMock->expects($this->once()) - ->method('getTableTriggersSql') - ->willReturn($triggersSql); - $backupMock->expects($this->once()) - ->method('open'); - $backupMock->expects($this->once()) - ->method('close'); - - $tableStatus->setRows($rowsCount); - $tableStatus->setDataLength($dataLength); - - $backupMock->expects($this->any()) - ->method('write') - ->withConsecutive( - [$this->equalTo($header)], - [$this->equalTo($header . $dropSql . "\n")], - [$this->equalTo($createSql . "\n")], - [$this->equalTo($beforeSql)], - [$this->equalTo($dataSql)], - [$this->equalTo($afterSql)], - [$this->equalTo($foreignKeysSql)], - [$this->equalTo($triggersSql)], - [$this->equalTo($footer)] - ); - - $this->dbModel->createBackup($backupMock); - } -} diff --git a/app/code/Magento/Backup/etc/adminhtml/system.xml b/app/code/Magento/Backup/etc/adminhtml/system.xml index 4028452d04439..90f6fa861b40f 100644 --- a/app/code/Magento/Backup/etc/adminhtml/system.xml +++ b/app/code/Magento/Backup/etc/adminhtml/system.xml @@ -9,13 +9,21 @@ <system> <section id="system"> <group id="backup" translate="label" type="text" sortOrder="500" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Scheduled Backup Settings</label> + <label>Backup Settings</label> + <field id="functionality_enabled" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Enable Backup</label> + <comment>Disabled by default for security reasons</comment> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + </field> <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Enable Scheduled Backup</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <depends> + <field id="functionality_enabled">1</field> + </depends> </field> <field id="type" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Backup Type</label> + <label>Scheduled Backup Type</label> <depends> <field id="enabled">1</field> </depends> diff --git a/app/code/Magento/Backup/etc/config.xml b/app/code/Magento/Backup/etc/config.xml new file mode 100644 index 0000000000000..fb0808983b9c8 --- /dev/null +++ b/app/code/Magento/Backup/etc/config.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <system> + <backup> + <functionality_enabled>0</functionality_enabled> + </backup> + </system> + </default> +</config> diff --git a/app/code/Magento/Backup/view/adminhtml/layout/backup_index_disabled.xml b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_disabled.xml new file mode 100644 index 0000000000000..3470f528e5ceb --- /dev/null +++ b/app/code/Magento/Backup/view/adminhtml/layout/backup_index_disabled.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <title>Backup functionality is disabled + + + + + + + diff --git a/app/code/Magento/Backup/view/adminhtml/templates/backup/disabled.phtml b/app/code/Magento/Backup/view/adminhtml/templates/backup/disabled.phtml new file mode 100644 index 0000000000000..a5308dce5cc52 --- /dev/null +++ b/app/code/Magento/Backup/view/adminhtml/templates/backup/disabled.phtml @@ -0,0 +1,7 @@ + +

    Backup functionality is currently disabled. Please use other means for backups

    diff --git a/dev/tests/functional/tests/app/Magento/Backup/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Backup/Test/Repository/ConfigData.xml new file mode 100644 index 0000000000000..c8b19aa2bd32b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backup/Test/Repository/ConfigData.xml @@ -0,0 +1,24 @@ + + + + + + + Yes + 1 + + + + + No + 0 + + + + diff --git a/dev/tests/functional/tests/app/Magento/Backup/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Backup/Test/TestCase/NavigateMenuTest.xml deleted file mode 100644 index 0c024f0e3f5aa..0000000000000 --- a/dev/tests/functional/tests/app/Magento/Backup/Test/TestCase/NavigateMenuTest.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - System > Backups - Backups - - - - diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php index e867ebe399784..c1fe9ca45972d 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php @@ -12,6 +12,7 @@ use Magento\Backup\Test\Page\Adminhtml\BackupIndex; use Magento\Store\Test\Fixture\Store; use Magento\Mtf\TestCase\Injectable; +use Magento\Config\Test\TestStep\SetupConfigurationStep; /** * Test Creation for DeleteStoreEntity @@ -100,7 +101,15 @@ public function test(Store $store, $createBackup) { // Preconditions: $store->persist(); - $this->backupIndex->open()->getBackupGrid()->massaction([], 'Delete', true, 'Select All'); + /** @var SetupConfigurationStep $enableBackupsStep */ + $enableBackupsStep = $this->objectManager->create( + SetupConfigurationStep::class, + ['configData' => 'enable_backups_functionality'] + ); + $enableBackupsStep->run(); + $this->backupIndex->open() + ->getBackupGrid() + ->massaction([], 'Delete', true, 'Select All'); // Steps: $this->storeIndex->open(); diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php index cd37576443cdb..c332b83a22deb 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php @@ -12,6 +12,7 @@ use Magento\Backup\Test\Page\Adminhtml\BackupIndex; use Magento\Store\Test\Fixture\StoreGroup; use Magento\Mtf\TestCase\Injectable; +use Magento\Config\Test\TestStep\SetupConfigurationStep; /** * Delete StoreGroup (Store Management) @@ -101,7 +102,15 @@ public function test(StoreGroup $storeGroup, $createBackup) { //Preconditions $storeGroup->persist(); - $this->backupIndex->open()->getBackupGrid()->massaction([], 'Delete', true, 'Select All'); + /** @var SetupConfigurationStep $enableBackupsStep */ + $enableBackupsStep = $this->objectManager->create( + SetupConfigurationStep::class, + ['configData' => 'enable_backups_functionality'] + ); + $enableBackupsStep->run(); + $this->backupIndex->open() + ->getBackupGrid() + ->massaction([], 'Delete', true, 'Select All'); //Steps $this->storeIndex->open(); diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php index 2431cb3e065d2..22259a30b1538 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php @@ -12,6 +12,7 @@ use Magento\Backup\Test\Page\Adminhtml\BackupIndex; use Magento\Store\Test\Fixture\Website; use Magento\Mtf\TestCase\Injectable; +use Magento\Config\Test\TestStep\SetupConfigurationStep; /** * Delete Website (Store Management) @@ -102,7 +103,15 @@ public function test(Website $website, $createBackup) { //Preconditions $website->persist(); - $this->backupIndex->open()->getBackupGrid()->massaction([], 'Delete', true, 'Select All'); + /** @var SetupConfigurationStep $enableBackupsStep */ + $enableBackupsStep = $this->objectManager->create( + SetupConfigurationStep::class, + ['configData' => 'enable_backups_functionality'] + ); + $enableBackupsStep->run(); + $this->backupIndex->open() + ->getBackupGrid() + ->massaction([], 'Delete', true, 'Select All'); //Steps $this->storeIndex->open(); diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php index 155ed21064bcf..03486f337d74f 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php @@ -10,10 +10,12 @@ use Magento\Backend\Test\Page\Adminhtml\DeleteWebsite; use Magento\Backend\Test\Page\Adminhtml\StoreIndex; use Magento\Backup\Test\Page\Adminhtml\BackupIndex; +use Magento\Config\Test\TestStep\SetupConfigurationStep; use Magento\Store\Test\Fixture\Store; use Magento\Mtf\TestStep\TestStepInterface; use Magento\Mtf\Fixture\FixtureFactory; use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\TestStep\TestStepFactory; /** * Test Step for DeleteWebsitesEntity. @@ -60,6 +62,11 @@ class DeleteWebsitesEntityStep implements TestStepInterface */ private $createBackup; + /** + * @var TestStepFactory + */ + private $stepFactory; + /** * Prepare pages for test. * @@ -69,6 +76,7 @@ class DeleteWebsitesEntityStep implements TestStepInterface * @param DeleteWebsite $deleteWebsite * @param FixtureFactory $fixtureFactory * @param FixtureInterface $item + * @param TestStepFactory $testStepFactory * @param string $createBackup */ public function __construct( @@ -78,6 +86,7 @@ public function __construct( DeleteWebsite $deleteWebsite, FixtureFactory $fixtureFactory, FixtureInterface $item, + TestStepFactory $testStepFactory, $createBackup = 'No' ) { $this->storeIndex = $storeIndex; @@ -87,6 +96,7 @@ public function __construct( $this->item = $item; $this->createBackup = $createBackup; $this->fixtureFactory = $fixtureFactory; + $this->stepFactory = $testStepFactory; } /** @@ -96,6 +106,12 @@ public function __construct( */ public function run() { + /** @var SetupConfigurationStep $enableBackupsStep */ + $enableBackupsStep = $this->stepFactory->create( + SetupConfigurationStep::class, + ['configData' => 'enable_backups_functionality'] + ); + $enableBackupsStep->run(); $this->backupIndex->open()->getBackupGrid()->massaction([], 'Delete', true, 'Select All'); $this->storeIndex->open(); $websiteNames = $this->item->getWebsiteIds(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Backup/DbTest.php b/dev/tests/integration/testsuite/Magento/Framework/Backup/DbTest.php index 9d149eceb4542..3ee68b1012c4e 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Backup/DbTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Backup/DbTest.php @@ -34,6 +34,7 @@ public static function setUpBeforeClass() /** * Test db backup includes triggers. * + * @magentoConfigFixture default/system/backup/functionality_enabled 1 * @magentoDataFixture Magento/Framework/Backup/_files/trigger.php * @magentoDbIsolation disabled */ diff --git a/lib/internal/Magento/Framework/Backup/BackupInterface.php b/lib/internal/Magento/Framework/Backup/BackupInterface.php index 3d054bdbd1a9c..16aada9689c11 100644 --- a/lib/internal/Magento/Framework/Backup/BackupInterface.php +++ b/lib/internal/Magento/Framework/Backup/BackupInterface.php @@ -13,6 +13,8 @@ /** * @api + * + * @deprecated Backups should be done using other means. */ interface BackupInterface { diff --git a/lib/internal/Magento/Framework/Backup/Db/BackupDbInterface.php b/lib/internal/Magento/Framework/Backup/Db/BackupDbInterface.php index 13e3c562bb527..a019ccac06b66 100644 --- a/lib/internal/Magento/Framework/Backup/Db/BackupDbInterface.php +++ b/lib/internal/Magento/Framework/Backup/Db/BackupDbInterface.php @@ -7,6 +7,8 @@ /** * @api + * + * @deprecated Backups should be done using other means. */ interface BackupDbInterface { diff --git a/lib/internal/Magento/Framework/Backup/Db/BackupInterface.php b/lib/internal/Magento/Framework/Backup/Db/BackupInterface.php index f7459f629cb4a..ae5879290eb20 100644 --- a/lib/internal/Magento/Framework/Backup/Db/BackupInterface.php +++ b/lib/internal/Magento/Framework/Backup/Db/BackupInterface.php @@ -7,6 +7,8 @@ /** * @api + * + * @deprecated Backups should be done using other means. */ interface BackupInterface { From 99788b8236a068d4d4a5d74ed039cc443126fd19 Mon Sep 17 00:00:00 2001 From: Vadim Justus Date: Mon, 8 Oct 2018 11:07:08 +0200 Subject: [PATCH 0408/1415] MSI-1735: Add @deprecation notice to all interfaces and extension points --- .../CatalogInventory/Api/Data/StockCollectionInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/Data/StockInterface.php | 3 +++ .../CatalogInventory/Api/Data/StockItemCollectionInterface.php | 3 +++ .../Magento/CatalogInventory/Api/Data/StockItemInterface.php | 3 +++ .../Api/Data/StockStatusCollectionInterface.php | 3 +++ .../Magento/CatalogInventory/Api/Data/StockStatusInterface.php | 3 +++ .../CatalogInventory/Api/RegisterProductSaleInterface.php | 3 +++ .../CatalogInventory/Api/RevertProductSaleInterface.php | 3 +++ .../CatalogInventory/Api/StockConfigurationInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockCriteriaInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/StockIndexInterface.php | 3 +++ .../CatalogInventory/Api/StockItemCriteriaInterface.php | 3 +++ .../CatalogInventory/Api/StockItemRepositoryInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockManagementInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockRegistryInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockRepositoryInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/StockStateInterface.php | 3 +++ .../CatalogInventory/Api/StockStatusCriteriaInterface.php | 3 +++ .../CatalogInventory/Api/StockStatusRepositoryInterface.php | 3 +++ .../CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php | 3 +++ .../CatalogInventory/Block/Adminhtml/Form/Field/Stock.php | 3 +++ app/code/Magento/CatalogInventory/Block/Qtyincrements.php | 3 +++ .../CatalogInventory/Block/Stockqty/DefaultStockqty.php | 3 +++ app/code/Magento/CatalogInventory/Helper/Stock.php | 3 +++ .../Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php | 3 +++ .../CatalogInventory/Model/Quote/Item/QuantityValidator.php | 3 +++ .../Model/ResourceModel/Indexer/Stock/DefaultStock.php | 3 +++ .../ResourceModel/Indexer/Stock/QueryProcessorInterface.php | 3 +++ .../Model/ResourceModel/Indexer/Stock/StockInterface.php | 3 +++ .../Model/ResourceModel/Indexer/StockFactory.php | 3 +++ .../CatalogInventory/Model/ResourceModel/Stock/Status.php | 3 +++ app/code/Magento/CatalogInventory/Model/Source/Backorders.php | 3 +++ app/code/Magento/CatalogInventory/Model/Source/Stock.php | 3 +++ app/code/Magento/CatalogInventory/composer.json | 3 ++- 34 files changed, 101 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php index c2521f77ca24a..a0f06cd406b14 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php @@ -15,6 +15,9 @@ * Interface StockCollectionInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php index 53e95921ea955..2bc9b474ff298 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php @@ -11,6 +11,9 @@ * Interface Stock * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php index 038174c8e52be..dbb8602678d80 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php @@ -15,6 +15,9 @@ * Interface StockItemCollectionInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php index b876615468ba9..2daebf96c6c02 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php @@ -11,6 +11,9 @@ * Interface StockItem * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php index 70a2c29ff9a6e..35959017606ad 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php @@ -11,6 +11,9 @@ * Stock Status collection interface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php index c9ae6a96a3671..397048cb04628 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php @@ -11,6 +11,9 @@ * Interface StockStatusInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php index 9122fb0038646..2f2b97bf1fa93 100644 --- a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php @@ -12,6 +12,9 @@ /** * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface RegisterProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php index ed496f3882fc2..0f441ee6268a1 100644 --- a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php @@ -9,6 +9,9 @@ /** * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface RevertProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php index a23d5030b8242..be815c3145607 100644 --- a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php @@ -9,6 +9,9 @@ * Interface StockConfigurationInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockConfigurationInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php index 969af6481cb4a..d92d2931867bc 100644 --- a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php index 1521b34c715b0..5a4c4b7ef52a1 100644 --- a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php @@ -9,6 +9,9 @@ * Interface StockIndexInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockIndexInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php index a2fc7801b1d13..5d129c199fc8a 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockItemCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php index 2732048d1445f..90f7d993e3607 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockItemRepository * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php index ddb84abf3d1a5..dcd611a148398 100644 --- a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php @@ -9,6 +9,9 @@ * Interface StockManagementInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockManagementInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php index 2d011e24f4105..7e3ee63d33aee 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php @@ -9,6 +9,9 @@ * Interface StockRegistryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockRegistryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php index 80a7e79289cff..2b0c40582932d 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockRepositoryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php index 8a1f7da5158ed..49cc746e79d39 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php @@ -9,6 +9,9 @@ * Interface StockStateInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStateInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php index e504e6355a15a..f57db6b2cef0a 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockStatusCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php index 94d4998c1e318..8be61afbbce11 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockStatusRepositoryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php index 15dfbd122e950..38d3c33a9a1f8 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php @@ -10,6 +10,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Minsaleqty extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php index 2c41e1798921a..74e062b7e07ca 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php @@ -14,6 +14,9 @@ /** * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock extends \Magento\Framework\Data\Form\Element\Select { diff --git a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php index adaa762f3279b..9551e06264c1b 100644 --- a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php +++ b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php @@ -14,6 +14,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Qtyincrements extends Template implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php index c315338be0de0..cb8741c88b09d 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php @@ -11,6 +11,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class DefaultStockqty extends AbstractStockqty implements \Magento\Framework\DataObject\IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index 494d440eeed89..eb76dd5fce057 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -18,6 +18,9 @@ * Class Stock * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock { diff --git a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php index 36721db874887..29f7aa61ab8b1 100644 --- a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php @@ -20,6 +20,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Item extends \Magento\CatalogInventory\Model\Stock\Item implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index b86c3cf13f31b..c13a2560c6ac2 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -25,6 +25,9 @@ * @api * @since 100.0.2 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class QuantityValidator { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index 366cb1c3902a3..ef43010826523 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -18,6 +18,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class DefaultStock extends AbstractIndexer implements StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php index abe473bd9682b..a24a10d7433c2 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php @@ -11,6 +11,9 @@ /** * @api * @since 100.1.0 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface QueryProcessorInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php index 5ced55edf208b..3f0523e8fba6c 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php @@ -9,6 +9,9 @@ * CatalogInventory Stock Indexer Interface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php index f9738484766b9..fae1ee72ac34f 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php @@ -12,6 +12,9 @@ /** * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class StockFactory { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php index bc5fda4939adc..1e826ef229f13 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php @@ -13,6 +13,9 @@ * CatalogInventory Stock Status per website Resource Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php index 1d200d27a4445..b13f7e570d859 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php @@ -9,6 +9,9 @@ * Back orders source class * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Backorders implements \Magento\Framework\Option\ArrayInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Stock.php b/app/code/Magento/CatalogInventory/Model/Source/Stock.php index 9ed891d1dcc0f..992709419fa25 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Stock.php @@ -11,6 +11,9 @@ * CatalogInventory Stock source model * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock extends AbstractSource { diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 8b55b6f327988..007d744b2296f 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -27,5 +27,6 @@ "psr-4": { "Magento\\CatalogInventory\\": "" } - } + }, + "abandoned": "magento/inventory-composer-metapackage" } From 5f1b4014093e062169dd9597752eac1c970898e2 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Mon, 8 Oct 2018 14:10:04 +0300 Subject: [PATCH 0409/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 37 +++++++++++++++++++ .../Magento/Backend/Block/Media/Uploader.php | 10 ----- .../adminhtml/templates/media/uploader.phtml | 2 +- .../Product/Helper/Form/Gallery/Content.php | 20 ++++++++-- .../layout/cms_wysiwyg_images_index.xml | 6 ++- .../templates/browser/content/uploader.phtml | 6 +-- 6 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php new file mode 100644 index 0000000000000..1ba3daf35d2cf --- /dev/null +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -0,0 +1,37 @@ +imageUploadConfig = $imageUploadConfig; + } + + /** + * Get image resize configuration + * + * @return int + */ + public function getIsResizeEnabled(): int + { + return (int)$this->imageUploadConfig->isResizeEnabled(); + } +} diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 22e9197418e4c..c332c91b54b27 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -127,16 +127,6 @@ public function getImageUploadMaxHeight() return $this->imageUploadConfig->getMaxHeight(); } - /** - * Get image resize configuration - * - * @return int - */ - public function getIsResizeEnabled(): int - { - return (int)$this->imageUploadConfig->isResizeEnabled(); - } - /** * Prepares layout and set element renderer * diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index d6e97cf4d58e3..4d9ba6a8c4bad 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -15,7 +15,7 @@ "maxFileSize": getFileSizeService()->getMaxFileSize() ?>, "maxWidth": getImageUploadMaxWidth() ?>, "maxHeight": getImageUploadMaxHeight() ?>, - "isResizeEnabled": getIsResizeEnabled() ?> + "isResizeEnabled": getImageUploadConfigData()->getIsResizeEnabled() ?> } }' > diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index e1208e25cc7c8..d9e343fd2b3f0 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -13,11 +13,12 @@ */ namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery; +use Magento\Framework\App\ObjectManager; use Magento\Backend\Block\Media\Uploader; use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; - +use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; /** * Block for gallery content. */ @@ -43,21 +44,30 @@ class Content extends \Magento\Backend\Block\Widget */ private $imageHelper; + /** + * @var ImageUploadConfigDataProvider + */ + private $imageUploadConfigDataProvider; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param array $data + * @param ImageUploadConfigDataProvider $imageUploadConfigDataProvider */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, - array $data = [] + array $data = [], + ImageUploadConfigDataProvider $imageUploadConfigDataProvider = null ) { $this->_jsonEncoder = $jsonEncoder; $this->_mediaConfig = $mediaConfig; parent::__construct($context, $data); + $this->imageUploadConfigDataProvider = $imageUploadConfigDataProvider + ?: ObjectManager::getInstance()->get(ImageUploadConfigDataProvider::class); } /** @@ -67,7 +77,11 @@ public function __construct( */ protected function _prepareLayout() { - $this->addChild('uploader', \Magento\Backend\Block\Media\Uploader::class); + $this->addChild( + 'uploader', + \Magento\Backend\Block\Media\Uploader::class, + ['image_upload_config_data' => $this->imageUploadConfigDataProvider] + ); $this->getUploader()->getConfig()->setUrl( $this->_urlBuilder->addSessionParam()->getUrl('catalog/product_gallery/upload') diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml index 1bc8828ef6c8e..6703b6c277123 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml @@ -9,7 +9,11 @@ - + + + Magento\Backend\Block\DataProviders\ImageUploadConfig + + diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index b1824f639c940..c6810f774238c 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,11 +17,11 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } -$resizeConfig = ($block->getIsResizeEnabled()) +$resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) ? "{action: 'resize', maxWidth: " - . $block->getImageUploadMaxWidth() + . $block->escapeHtml($block->getImageUploadMaxWidth()) . ", maxHeight: " - . $block->getImageUploadMaxHeight() + . $block->escapeHtml($block->getImageUploadMaxHeight()) . "}" : "{action: 'resize'}"; ?> From d921849d060864994249f387487d743dce85fc06 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak Date: Mon, 8 Oct 2018 14:12:59 +0300 Subject: [PATCH 0410/1415] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../view/frontend/web/js/model/checkout-data-resolver.js | 1 + .../Checkout/view/frontend/web/js/view/form/element/email.js | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 4abb4c4d61700..cd4c59df51187 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -75,6 +75,7 @@ define([ } newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); + if (newCustomerShippingAddress) { createShippingAddress(newCustomerShippingAddress); } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 37a785e292365..4d883fb1373bd 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -27,6 +27,7 @@ define([ } validatedEmail = checkoutData.getValidatedEmailValue(); + if (validatedEmail && !customer.isLoggedIn()) { quote.guestEmail = validatedEmail; } From e258878dbf07fcb14449b8253adb2f8f35b6ebcf Mon Sep 17 00:00:00 2001 From: Valentin Boyanov Date: Mon, 8 Oct 2018 14:02:48 +0200 Subject: [PATCH 0411/1415] MAGETWO-34709 Changing empty label value for first option. --- app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php index dc928b4c7942d..4f4ed9de03e43 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php @@ -250,7 +250,7 @@ protected function _getSelectHtmlWithValue(Attribute $attribute, $value) if ('' === $firstOption['value']) { $options[key($options)]['label'] = ''; } else { - array_unshift($options, ['value' => '', 'label' => '']); + array_unshift($options, ['value' => '', 'label' => __('-- Not Selected --')]); } $arguments = [ 'name' => $this->getFilterElementName($attribute->getAttributeCode()), From 1b03c19021957d85e625eeb5bb61cd3921b31937 Mon Sep 17 00:00:00 2001 From: Bunyamin Date: Mon, 8 Oct 2018 09:16:07 -0300 Subject: [PATCH 0412/1415] Revert back change --- app/code/Magento/Newsletter/Model/Queue.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 67f8cadbfaed4..efb68fd4243d1 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,8 +196,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $startAt = $this->timezone->convertConfigTimeToUtcWithPattern($startAt, 'Y-m-d H:i:s', null); - $this->setQueueStartAt($startAt); + $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); } return $this; } From c6c2ffe214f45366e81e3644b7ddadb2b2fce383 Mon Sep 17 00:00:00 2001 From: Bunyamin Date: Mon, 8 Oct 2018 09:17:39 -0300 Subject: [PATCH 0413/1415] Rever-back unit test --- .../Test/Unit/DateTime/TimezoneTest.php | 29 ++----------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index ea761db902674..d57525590b9e8 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -124,15 +124,11 @@ public function dateIncludeTimeDataProvider() * @param string $expectedResult * @dataProvider getConvertConfigTimeToUtcFixtures */ - public function testConvertConfigTimeToUtc($date, $configuredTimezone, $configuredLocale, $expectedResult) + public function testConvertConfigTimeToUtc($date, $configuredTimezone, $expectedResult) { - $this->localeResolver - ->method('getLocale') - ->willReturn($configuredLocale); - $this->scopeConfigWillReturnConfiguredTimezone($configuredTimezone); - $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtcWithPattern($date)); + $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtc($date)); } /** @@ -145,37 +141,16 @@ public function getConvertConfigTimeToUtcFixtures() 'string' => [ '2016-10-10 10:00:00', 'UTC', - null, '2016-10-10 10:00:00' ], - 'string-en_US' => [ - 'Sep 29, 2018, 6:07:38 PM', - 'UTC', - 'en_US', - '2018-09-29 18:07:38' - ], - 'string-pt_BR' => [ - '29 de set de 2018 18:07:38', - 'UTC', - 'pt_BR', - '2018-09-29 18:07:38' - ], - 'string-tr_TR' => [ - '29 Eyl 2018 18:07:38', - 'UTC', - 'tr_TR', - '2018-09-29 18:07:38' - ], 'datetime' => [ new \DateTime('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', - null, '2016-10-10 10:00:00' ], 'datetimeimmutable' => [ new \DateTimeImmutable('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', - null, '2016-10-10 10:00:00' ] ]; From cc16df90455a510083f4d4bebda27566c23e221e Mon Sep 17 00:00:00 2001 From: Thiago Lima Date: Mon, 8 Oct 2018 14:27:56 +0200 Subject: [PATCH 0414/1415] fix issue Fatal Error when save configurable product in Magento 2.2.5 #18082 --- .../Product/Initialization/Helper/Plugin/Configurable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php index 5cd8b6a7d0b95..556939ec112f1 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php @@ -158,7 +158,7 @@ protected function getVariationMatrix() $configurableMatrix = json_decode($configurableMatrix, true); foreach ($configurableMatrix as $item) { - if ($item['newProduct']) { + if (isset($item['newProduct'])) { $result[$item['variationKey']] = $this->mapData($item); if (isset($item['qty'])) { From 502e5ac6941a10e39ef1e559c91565bdb07a4d14 Mon Sep 17 00:00:00 2001 From: Bunyamin Date: Mon, 8 Oct 2018 09:34:26 -0300 Subject: [PATCH 0415/1415] New class and interface created for time format convertion --- app/code/Magento/Store/etc/di.xml | 6 ++ app/etc/di.xml | 1 + .../Timezone/LocalizedDateToUtcConverter.php | 86 +++++++++++++++++++ .../LocalizedDateToUtcConverterInterface.php | 17 ++++ 4 files changed, 110 insertions(+) create mode 100644 lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php create mode 100644 lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index be005264b7bbf..f9e003aca69af 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,6 +294,12 @@ Magento\Store\Model\ScopeInterface::SCOPE_STORE + + + Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE + Magento\Store\Model\ScopeInterface::SCOPE_STORE + + Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE diff --git a/app/etc/di.xml b/app/etc/di.xml index db979f9b76382..282a0af4f46a5 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -146,6 +146,7 @@ + diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php new file mode 100644 index 0000000000000..23dadc11cc6ef --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -0,0 +1,86 @@ +localeResolver = $localeResolver; + $this->scopeConfig = $scopeConfig; + $this->scopeType = $scopeType; + $this->defaultTimezonePath = $defaultTimezonePath; + } + + /** + * @inheritdoc + */ + public function convertLocalizedDateToUtc($date) + { + $locale = $this->localeResolver->getLocale(); + $formatter = new \IntlDateFormatter( + $locale, + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + null + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); + $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + + $date->setTimezone(new \DateTimeZone('UTC')); + + return $date->format($this->defaultFormat); + } +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php new file mode 100644 index 0000000000000..277900c46badf --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -0,0 +1,17 @@ + Date: Mon, 8 Oct 2018 10:07:17 -0300 Subject: [PATCH 0416/1415] Convert local timestamp into GMT timestamp --- app/code/Magento/Newsletter/Model/Queue.php | 18 +++++--- app/code/Magento/Store/etc/di.xml | 6 --- .../Timezone/LocalizedDateToUtcConverter.php | 44 +++++++------------ 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index efb68fd4243d1..58c5ba8a7e04a 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -7,6 +7,7 @@ use Magento\Framework\App\TemplateTypesInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverterInterface; /** * Newsletter queue model. @@ -117,6 +118,11 @@ class Queue extends \Magento\Framework\Model\AbstractModel implements TemplateTy */ private $timezone; + /** + * @var LocalizedDateToUtcConverterInterface + */ + private $utcConverter; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -144,7 +150,8 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - TimezoneInterface $timezone = null + TimezoneInterface $timezone = null, + LocalizedDateToUtcConverterInterface $utcConverter = null ) { parent::__construct( $context, @@ -159,9 +166,10 @@ public function __construct( $this->_problemFactory = $problemFactory; $this->_subscribersCollection = $subscriberCollectionFactory->create(); $this->_transportBuilder = $transportBuilder; - $this->timezone = $timezone ?: \Magento\Framework\App\ObjectManager::getInstance()->get( - TimezoneInterface::class - ); + + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $this->timezone = $timezone ?: $objectManager->get(TimezoneInterface::class); + $this->utcConverter = $utcConverter ?? $objectManager->get(LocalizedDateToUtcConverterInterface::class); } /** @@ -196,7 +204,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); + $this->setQueueStartAt($this->utcConverter->convertLocalizedDateToUtc($startAt)); } return $this; } diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index f9e003aca69af..be005264b7bbf 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,12 +294,6 @@ Magento\Store\Model\ScopeInterface::SCOPE_STORE - - - Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE - Magento\Store\Model\ScopeInterface::SCOPE_STORE - - Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php index 23dadc11cc6ef..721ed9a384dad 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -7,6 +7,7 @@ namespace Magento\Framework\Stdlib\DateTime\Timezone; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Framework\Locale\ResolverInterface; use Magento\Framework\App\Config\ScopeConfigInterface; @@ -23,24 +24,14 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac private $defaultFormat = 'Y-m-d H:i:s'; /** - * @var ResolverInterface - */ - private $localeResolver; - - /** - * @var ScopeConfigInterface - */ - private $scopeConfig; - - /** - * @var string + * @var TimezoneInterface */ - private $scopeType; + private $timezone; /** - * @var string + * @var ResolverInterface */ - private $defaultTimezonePath; + private $localeResolver; /** * LocalizedDateToUtcConverter constructor. @@ -48,16 +39,12 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac * @param ResolverInterface $localeResolver */ public function __construct( - ResolverInterface $localeResolver, - ScopeConfigInterface $scopeConfig, - $scopeType, - $defaultTimezonePath + TimezoneInterface $timezone, + ResolverInterface $localeResolver ) { + $this->timezone = $timezone; $this->localeResolver = $localeResolver; - $this->scopeConfig = $scopeConfig; - $this->scopeType = $scopeType; - $this->defaultTimezonePath = $defaultTimezonePath; } /** @@ -65,20 +52,21 @@ public function __construct( */ public function convertLocalizedDateToUtc($date) { + $configTimezone = $this->timezone->getConfigTimezone(); $locale = $this->localeResolver->getLocale(); + $formatter = new \IntlDateFormatter( $locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - null + $configTimezone ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - $dateUniversal = $dateTime->gmtDate(null, $unixTime); - $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + $localTimestamp = $formatter->parse($date); + $gmtTimestamp = $this->timezone->date($localTimestamp)->getTimestamp(); + $formattedUniversalTime = date($this->defaultFormat, $gmtTimestamp); + + $date = new \DateTime($formattedUniversalTime, new \DateTimeZone($configTimezone)); $date->setTimezone(new \DateTimeZone('UTC')); return $date->format($this->defaultFormat); From e32303ab2a4eeb4001a1b8627f60ae8ba993d919 Mon Sep 17 00:00:00 2001 From: Daniel Renaud Date: Mon, 8 Oct 2018 08:15:23 -0500 Subject: [PATCH 0417/1415] MAGETWO-83089: Functional test failure in UpdateAdminUserRoleEntityTest --- .../Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml index 1f1530b08b28a..224ccbce10f96 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml @@ -17,7 +17,6 @@ - MAGETWO-65658: [FT] User with restricted access can't log in to Admin in UpdateAdminUserEntityTest default Custom Sales From 9d824af97af6d6ac34cf18b1c6086dc59ba58cdc Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Mon, 8 Oct 2018 16:39:07 +0300 Subject: [PATCH 0418/1415] ENGCOM-2998: Adding trimming sku value function to sku backend model. #18019. Fix static tests. --- .../Catalog/Model/Product/Attribute/Backend/Sku.php | 10 +++++----- .../Ui/DataProvider/Product/Form/Modifier/General.php | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php index 2ea3b9aaf10a8..98738e055ca8f 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php @@ -4,15 +4,13 @@ * See COPYING.txt for license details. */ -/** - * Catalog product SKU backend attribute model - * - * @author Magento Core Team - */ namespace Magento\Catalog\Model\Product\Attribute\Backend; use Magento\Catalog\Model\Product; +/** + * Catalog product SKU backend attribute model. + */ class Sku extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend { /** @@ -130,6 +128,8 @@ protected function _getLastSimilarAttributeValueIncrement($attribute, $object) } /** + * Remove extra spaces from attribute value before save. + * * @param Product $object * @return void */ diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index e0b0d066c1c1d..6ec1cc6c46d9d 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -58,8 +58,11 @@ public function __construct( } /** - * {@inheritdoc} + * Customize number fields for advanced price and weight fields. + * * @since 101.0.0 + * @param array $data + * @return array * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function modifyData(array $data) @@ -130,8 +133,11 @@ protected function customizeAdvancedPriceFormat(array $data) } /** - * {@inheritdoc} + * Customize product form fields. + * * @since 101.0.0 + * @param array $meta + * @return array */ public function modifyMeta(array $meta) { From b56aa55af499883d9c61aab7f86495d9dd2400c4 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 8 Oct 2018 17:45:30 +0300 Subject: [PATCH 0419/1415] MAGETWO-81469: Cached Config is Different From DB --- .../Test/Unit/App/Config/Type/SystemTest.php | 181 ------------------ 1 file changed, 181 deletions(-) delete mode 100644 app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php diff --git a/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php b/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php deleted file mode 100644 index 40aa110382ede..0000000000000 --- a/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php +++ /dev/null @@ -1,181 +0,0 @@ -source = $this->getMockBuilder(ConfigSourceInterface::class) - ->getMockForAbstractClass(); - $this->postProcessor = $this->getMockBuilder(PostProcessorInterface::class) - ->getMockForAbstractClass(); - $this->fallback = $this->getMockBuilder(Fallback::class) - ->disableOriginalConstructor() - ->getMock(); - $this->cache = $this->getMockBuilder(FrontendInterface::class) - ->getMockForAbstractClass(); - $this->preProcessor = $this->getMockBuilder(PreProcessorInterface::class) - ->getMockForAbstractClass(); - $this->serializer = $this->getMockBuilder(SerializerInterface::class) - ->getMock(); - $this->reader = $this->getMockBuilder(Reader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->configType = new System( - $this->source, - $this->postProcessor, - $this->fallback, - $this->cache, - $this->serializer, - $this->preProcessor, - 1, - 'system', - $this->reader - ); - } - - public function testGetCachedWithLoadDefaultScopeData() - { - $path = 'default/dev/unsecure/url'; - $url = 'http://magento.test/'; - $data = [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ]; - - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls('1', serialize($data)); - $this->serializer->expects($this->once()) - ->method('unserialize') - ->willReturn($data); - $this->assertEquals($url, $this->configType->get($path)); - } - - public function testGetCachedWithLoadAllData() - { - $url = 'http://magento.test/'; - $data = [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ]; - - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls('1', serialize($data)); - $this->serializer->expects($this->once()) - ->method('unserialize') - ->willReturn($data); - $this->assertEquals($data, $this->configType->get('')); - } - - public function testGetNotCached() - { - $path = 'stores/default/dev/unsecure/url'; - $url = 'http://magento.test/'; - - $dataToCache = [ - 'unsecure' => [ - 'url' => $url - ] - ]; - $data = [ - 'default' => [], - 'websites' => [], - 'stores' => [ - 'default' => [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ] - ] - ]; - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls(false, false); - - $this->serializer->expects($this->atLeastOnce()) - ->method('serialize') - ->willReturn(serialize($dataToCache)); - $this->cache->expects($this->atLeastOnce()) - ->method('save') - ->willReturnSelf(); - $this->reader->expects($this->once()) - ->method('read') - ->willReturn($data); - $this->postProcessor->expects($this->once()) - ->method('process') - ->with($data) - ->willReturn($data); - - $this->assertEquals($url, $this->configType->get($path)); - $this->assertEquals($url, $this->configType->get($path)); - } -} From 0b5258860d19ce8541d2043085b33ac8aee2c336 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 8 Oct 2018 09:46:05 -0500 Subject: [PATCH 0420/1415] MAGETWO-95534: Random integration test failure - Fixed Magento.Cms.Model.PageTest.testUpdateTime --- .../testsuite/Magento/Cms/Model/PageTest.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php index 42697e1b66b7f..83e7c678ffc51 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php @@ -6,6 +6,7 @@ namespace Magento\Cms\Model; use Magento\Cms\Api\PageRepositoryInterface; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\Stdlib\DateTime\DateTime; /** @@ -79,13 +80,27 @@ public function testGenerateIdentifierFromTitle($data, $expectedIdentifier) public function testUpdateTime() { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** + * @var $db \Magento\Framework\DB\Adapter\AdapterInterface + */ + $db = $objectManager->get(\Magento\Framework\App\ResourceConnection::class) + ->getConnection(ResourceConnection::DEFAULT_CONNECTION); + /** @var \Magento\Cms\Model\Page $page */ $page = $objectManager->create(\Magento\Cms\Model\Page::class); $page->setData(['title' => 'Test', 'stores' => [1]]); + $beforeTimestamp = $db->fetchCol('SELECT UNIX_TIMESTAMP()')[0]; $page->save(); + $afterTimestamp = $db->fetchCol('SELECT UNIX_TIMESTAMP()')[0]; $page = $objectManager->get(PageRepositoryInterface::class)->getById($page->getId()); - $date = $objectManager->get(DateTime::class)->date(); - $this->assertEquals($date, $page->getUpdateTime()); + $pageTimestamp = strtotime($page->getUpdateTime()); + + /* + * These checks prevent a race condition MAGETWO-95534 + */ + $this->assertGreaterThanOrEqual($beforeTimestamp, $pageTimestamp); + $this->assertLessThanOrEqual($afterTimestamp, $pageTimestamp); } public function generateIdentifierFromTitleDataProvider() : array From 1e28a8e25d1d43f02e090faf8aa77216a3a84738 Mon Sep 17 00:00:00 2001 From: Logan Stellway Date: Mon, 8 Oct 2018 09:10:59 -0700 Subject: [PATCH 0421/1415] Updates docblock comment for _renderPage() method --- pub/errors/processor.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 615a0c0f96ec3..8b37798f468b8 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -380,6 +380,8 @@ protected function _loadXml($xmlFile) } /** + * Render page + * * @param string $template * @return string */ From eb2dd92bfab57e45a50b60f7d29adb80bff27c38 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov Date: Mon, 8 Oct 2018 19:19:25 +0300 Subject: [PATCH 0422/1415] MAGETWO-91651: Navigation Menu problem on Mobile theme - Added scroll to top menu items --- lib/web/mage/menu.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index b8000640506f1..7096c4ecb7d6d 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -439,6 +439,7 @@ define([ event.preventDefault(); target = $(event.target).closest('.ui-menu-item'); + target.get(0).scrollIntoView(); if (!target.hasClass('level-top') || !target.has('.ui-menu').length) { window.location.href = target.find('> a').attr('href'); From 14d4016e68a6ceb9dbcb383253301917501885db Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 8 Oct 2018 11:25:29 -0500 Subject: [PATCH 0423/1415] MAGETWO-95429: ShipOrder API with No Tracking Number Error Message - Changed class to use existing collection - Added api test --- .../Magento/Sales/Model/Order/Shipment.php | 9 ++---- .../Sales/Service/V1/ShipOrderTest.php | 31 ++++++++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index 8be12ec6ad57f..1da9ff88c9a16 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -574,13 +574,10 @@ public function setItems($items) public function getTracks() { if ($this->getData(ShipmentInterface::TRACKS) === null) { - $collection = $this->_trackCollectionFactory->create()->setShipmentFilter($this->getId()); - if ($this->getId()) { - foreach ($collection as $item) { - $item->setShipment($this); - } - $this->setData(ShipmentInterface::TRACKS, $collection->getItems()); + foreach ($this->getTracksCollection() as $item) { + $item->setShipment($this); } + $this->setData(ShipmentInterface::TRACKS, $this->getTracksCollection()->getItems()); } return $this->getData(ShipmentInterface::TRACKS); } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php index 1d854331731ab..580de22855917 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php @@ -25,7 +25,6 @@ class ShipOrderTest extends \Magento\TestFramework\TestCase\WebapiAbstract protected function setUp() { - $this->markTestIncomplete('https://github.com/magento-engcom/msi/issues/1335'); $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $this->shipmentRepository = $this->objectManager->get( @@ -38,6 +37,7 @@ protected function setUp() */ public function testConfigurableShipOrder() { + $this->markTestIncomplete('https://github.com/magento-engcom/msi/issues/1335'); $productsQuantity = 1; /** @var \Magento\Sales\Model\Order $existingOrder */ @@ -132,6 +132,35 @@ public function testShipOrder() ); } + /** + * Tests that not providing a tracking number produces the correct error. See MAGETWO-95429 + * @expectedException \Exception + * @expectedExceptionMessageRegExp /Shipment Document Validation Error\(s\):(?:\n|\\n)Please enter a tracking number./ + * @magentoApiDataFixture Magento/Sales/_files/order_new.php + */ + public function testShipOrderWithoutTrackingNumberReturnsError() + { + /** @var \Magento\Sales\Model\Order $existingOrder */ + $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) + ->loadByIncrementId('100000001'); + + $requestData = [ + 'orderId' => $existingOrder->getId(), + 'comment' => [ + 'comment' => 'Test Comment', + 'is_visible_on_front' => 1, + ], + 'tracks' => [ + [ + 'title' => 'Simple shipment track', + 'carrier_code' => 'UPS' + ] + ] + ]; + + $this->_webApiCall($this->getServiceInfo($existingOrder), $requestData); + } + /** * @magentoApiDataFixture Magento/Bundle/_files/order_with_bundle_shipped_separately.php */ From a52725d41187e32c30864a5c754efbdff8c2fd72 Mon Sep 17 00:00:00 2001 From: Alex Paliarush Date: Mon, 8 Oct 2018 11:27:41 -0500 Subject: [PATCH 0424/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization - Fixed code style violations --- .../Catalog/Model/Product/Media/Config.php | 41 +++++++++++-------- .../Model/Resolver/Categories.php | 5 +-- .../Magento/Framework/GraphQl/Config.php | 11 ++--- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Media/Config.php b/app/code/Magento/Catalog/Model/Product/Media/Config.php index b01f254b8377b..33af93db13b4c 100644 --- a/app/code/Magento/Catalog/Model/Product/Media/Config.php +++ b/app/code/Magento/Catalog/Model/Product/Media/Config.php @@ -10,11 +10,9 @@ use Magento\Store\Model\StoreManagerInterface; /** - * Catalog product media config + * Catalog product media config. * * @api - * - * @author Magento Core Team * @since 100.0.2 */ class Config implements ConfigInterface @@ -45,8 +43,7 @@ public function __construct(StoreManagerInterface $storeManager) } /** - * Filesystem directory path of product images - * relatively to media folder + * Get filesystem directory path for product images relative to the media directory. * * @return string */ @@ -56,8 +53,7 @@ public function getBaseMediaPathAddition() } /** - * Web-based directory path of product images - * relatively to media folder + * Get web-based directory path for product images relative to the media directory. * * @return string */ @@ -67,7 +63,7 @@ public function getBaseMediaUrlAddition() } /** - * @return string + * @inheritdoc */ public function getBaseMediaPath() { @@ -75,7 +71,7 @@ public function getBaseMediaPath() } /** - * @return string + * @inheritdoc */ public function getBaseMediaUrl() { @@ -84,8 +80,7 @@ public function getBaseMediaUrl() } /** - * Filesystem directory path of temporary product images - * relatively to media folder + * Filesystem directory path of temporary product images relative to the media directory. * * @return string */ @@ -95,6 +90,8 @@ public function getBaseTmpMediaPath() } /** + * Get temporary base media URL. + * * @return string */ public function getBaseTmpMediaUrl() @@ -105,8 +102,7 @@ public function getBaseTmpMediaUrl() } /** - * @param string $file - * @return string + * @inheritdoc */ public function getMediaUrl($file) { @@ -114,8 +110,7 @@ public function getMediaUrl($file) } /** - * @param string $file - * @return string + * @inheritdoc */ public function getMediaPath($file) { @@ -123,6 +118,8 @@ public function getMediaPath($file) } /** + * Get temporary media URL. + * * @param string $file * @return string */ @@ -132,8 +129,7 @@ public function getTmpMediaUrl($file) } /** - * Part of URL of temporary product images - * relatively to media folder + * Part of URL of temporary product images relative to the media directory. * * @param string $file * @return string @@ -144,7 +140,7 @@ public function getTmpMediaShortUrl($file) } /** - * Part of URL of product images relatively to media folder + * Part of URL of product images relatively to media folder. * * @param string $file * @return string @@ -155,6 +151,8 @@ public function getMediaShortUrl($file) } /** + * Get path to the temporary media. + * * @param string $file * @return string */ @@ -164,6 +162,8 @@ public function getTmpMediaPath($file) } /** + * Process file path. + * * @param string $file * @return string */ @@ -173,18 +173,23 @@ protected function _prepareFile($file) } /** + * Get codes of media attribute. + * * @return array * @since 100.0.4 */ public function getMediaAttributeCodes() { if (!isset($this->mediaAttributeCodes)) { + // the in-memory object-level caching allows to prevent unnecessary calls to the DB $this->mediaAttributeCodes = $this->getAttributeHelper()->getAttributeCodesByFrontendType('media_image'); } return $this->mediaAttributeCodes; } /** + * Get attribute helper. + * * @return Attribute */ private function getAttributeHelper() diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index 7fe679b18d866..fdc9e5f083b72 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -78,7 +78,8 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc + * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) @@ -106,7 +107,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ foreach ($this->collection as $item) { if (in_array($item->getId(), $categoryIds)) { - // Try to extract all requested fields from the loaded collection data $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true); $requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0]); @@ -118,7 +118,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value // If not all requested fields were extracted from the collection, start more complex extraction $categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item); - } } diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 52735acc6d70f..ff4c920d2cd6a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -53,6 +53,7 @@ public function __construct( * @param string $configElementName * @return ConfigElementInterface * @throws \LogicException + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function getConfigElement(string $configElementName) : ConfigElementInterface { @@ -65,11 +66,11 @@ public function getConfigElement(string $configElementName) : ConfigElementInter $fieldsInQuery = $this->queryFields->getFieldsUsedInQuery(); if (isset($data['fields']) && !empty($fieldsInQuery)) { - foreach ($data['fields'] as $fieldName => $fieldConfig) { - if (!isset($fieldsInQuery[$fieldName])) { - unset($data['fields'][$fieldName]); - } - } + foreach ($data['fields'] as $fieldName => $fieldConfig) { + if (!isset($fieldsInQuery[$fieldName])) { + unset($data['fields'][$fieldName]); + } + } } return $this->configElementFactory->createFromConfigData($data); From e4094c93a041251075b25f4889a171c64ef37d0c Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 8 Oct 2018 12:42:27 -0500 Subject: [PATCH 0425/1415] MAGETWO-95429: ShipOrder API with No Tracking Number Error Message - Build stabilization --- app/code/Magento/Sales/Model/Order/Shipment.php | 17 +++++++++++++++-- .../Magento/Sales/Service/V1/ShipOrderTest.php | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index 1da9ff88c9a16..ebedc869e14bd 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -277,6 +277,8 @@ public function register() } /** + * Retrieves the collection used to track the shipment's items + * * @return mixed */ public function getItemsCollection() @@ -295,6 +297,8 @@ public function getItemsCollection() } /** + * Retrieves all non-deleted items from the shipment + * * @return array */ public function getAllItems() @@ -309,6 +313,8 @@ public function getAllItems() } /** + * Retrieves an item from the shipment using its ID + * * @param string|int $itemId * @return bool|\Magento\Sales\Model\Order\Shipment\Item */ @@ -323,6 +329,8 @@ public function getItemById($itemId) } /** + * Adds an item to the shipment + * * @param \Magento\Sales\Model\Order\Shipment\Item $item * @return $this */ @@ -353,6 +361,8 @@ public function getTracksCollection() } /** + * Retrieves all available tracks in the collection that aren't deleted + * * @return array */ public function getAllTracks() @@ -367,6 +377,8 @@ public function getAllTracks() } /** + * Retrieves a track using its ID + * * @param string|int $trackId * @return bool|\Magento\Sales\Model\Order\Shipment\Track */ @@ -381,6 +393,8 @@ public function getTrackById($trackId) } /** + * Addes a track to the collection and associates the shipment to the track + * * @param \Magento\Sales\Model\Order\Shipment\Track $track * @return $this */ @@ -409,8 +423,7 @@ public function addTrack(\Magento\Sales\Model\Order\Shipment\Track $track) } /** - * Adds comment to shipment with additional possibility to send it to customer via email - * and show it in customer account + * Adds comment to shipment with option to send it to customer via email and show it in customer account * * @param \Magento\Sales\Model\Order\Shipment\Comment|string $comment * @param bool $notify diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php index 580de22855917..e2a156cc6fbfc 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php @@ -135,11 +135,15 @@ public function testShipOrder() /** * Tests that not providing a tracking number produces the correct error. See MAGETWO-95429 * @expectedException \Exception + * @codingStandardsIgnoreStart * @expectedExceptionMessageRegExp /Shipment Document Validation Error\(s\):(?:\n|\\n)Please enter a tracking number./ + * @codingStandardsIgnoreEnd * @magentoApiDataFixture Magento/Sales/_files/order_new.php */ public function testShipOrderWithoutTrackingNumberReturnsError() { + $this->_markTestAsRestOnly('SOAP requires an tracking number to be provided so this case is not possible.'); + /** @var \Magento\Sales\Model\Order $existingOrder */ $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) ->loadByIncrementId('100000001'); From 1fa4f0d29dcf67634a65ca62cc7b68b394e2231c Mon Sep 17 00:00:00 2001 From: Iryna Lagno Date: Mon, 8 Oct 2018 13:54:34 -0500 Subject: [PATCH 0426/1415] MAGETWO-87454: Catalog Products List widget doesn't work with 'contains/not contains' operator --- .../CatalogWidget/Block/Product/ProductListTest.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php index 2f2029d2f13e1..2695948e78314 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php @@ -136,12 +136,14 @@ private function performAssertions(int $count) * Check that collection returns correct result if use not contains operator for string attribute * * @magentoDbIsolation disabled - * @magentoDataFixture Magento/Catalog/_files/product_special_price.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_xss.php * @magentoDataFixture Magento/Catalog/_files/product_virtual.php * @dataProvider createCollectionForSkuDataProvider + * @param string $encodedConditions + * @param string $sku * @return void */ - public function testCreateCollectionForSku($encodedConditions) + public function testCreateCollectionForSku($encodedConditions, $sku) { $this->block->setData('conditions_encoded', $encodedConditions); $productCollection = $this->block->createCollection(); @@ -151,7 +153,7 @@ public function testCreateCollectionForSku($encodedConditions) $productCollection->count(), "Product collection was not filtered according to the widget condition." ); - $this->assertEquals('virtual-product', $productCollection->getFirstItem()->getSku()); + $this->assertEquals($sku, $productCollection->getFirstItem()->getSku()); } /** @@ -163,11 +165,11 @@ public function createCollectionForSkuDataProvider() 'contains' => ['^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' . '`aggregator`:`all`,`value`:`1`,`new_child`:``^],' . '`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,' - . '`attribute`:`sku`,`operator`:`^[^]`,`value`:`virtual`^]^]'], + . '`attribute`:`sku`,`operator`:`^[^]`,`value`:`virtual`^]^]' , 'virtual-product'], 'not contains' => ['^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' . '`aggregator`:`all`,`value`:`1`,`new_child`:``^],' . '`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,' - . '`attribute`:`sku`,`operator`:`!^[^]`,`value`:`simple`^]^]'] + . '`attribute`:`sku`,`operator`:`!^[^]`,`value`:`virtual`^]^]', 'product-with-xss'] ]; } } From 40c809f0d82e6bdd49f8624c42907d451f6924fb Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 8 Oct 2018 15:28:28 -0500 Subject: [PATCH 0427/1415] MAGETWO-94962: Unable to set default option for swatch attribute --- .../AdminCreateProductAttributeSection.xml | 3 + .../AdminProductAttributeOptionsSection.xml | 14 ++++ ...dminCreateDropdownProductAttributeTest.xml | 74 +++++++++++++++++++ .../Mftf/Section/AdminManageSwatchSection.xml | 1 + ...ateVisualSwatchWithNonValidOptionsTest.xml | 39 +++++++++- 5 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index 17778c76da9b9..78d06afa7f003 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -23,6 +23,9 @@ +
    + +
    diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml new file mode 100644 index 0000000000000..17ca306eeccfa --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml @@ -0,0 +1,14 @@ + + + +
    + +
    +
    \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml new file mode 100644 index 0000000000000..d9942e9fc1b46 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -0,0 +1,74 @@ + + + + + + + + + <description value="Admin should be able to create dropdown product attribute"/> + <severity value="BLOCKER"/> + <testCaseId value="MC-4140"/> + <group value="attribute"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + <after> + <!-- Remove attribute --> + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="productDropDownAttribute"/> + </actionGroup> + <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> + + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <amOnPage url="{{ProductAttributePage.url}}" stepKey="navigateToNewProductAttributePage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + + <!-- Set attribute properties --> + <fillField selector="{{AttributePropertiesSection.DefaultLabel}}" + userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="fillDefaultLabel"/> + <selectOption selector="{{AttributePropertiesSection.InputType}}" + userInput="{{productDropDownAttribute.frontend_input}}" stepKey="fillInputType"/> + + <!-- Set advanced attribute properties --> + <click selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" + stepKey="showAdvancedAttributePropertiesSection"/> + <waitForElementVisible selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + stepKey="waitForSlideOut"/> + <fillField selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + userInput="{{productDropDownAttribute.attribute_code}}" + stepKey="fillAttributeCode"/> + + <!-- Add new attribute options --> + <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption1"/> + <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('1')}}" + userInput="Fish and Chips" stepKey="fillAdminValue1"/> + + <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption2"/> + <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + userInput="Fish & Chips" stepKey="fillAdminValue2"/> + + <!-- Save the new product attribute --> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave1"/> + <waitForPageLoad stepKey="waitForGridPageLoad1"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" + stepKey="waitForSuccessMessage"/> + + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="productDropDownAttribute"/> + </actionGroup> + <!-- Check attribute data --> + <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + stepKey="secondOptionAdminLabel"/> + <assertEquals actual="$secondOptionAdminLabel" expected="Fish & Chips" + stepKey="assertSecondOption"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index 25e03676f6870..6538af3178060 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -15,6 +15,7 @@ <element name="addSwatchText" type="button" selector="#add_new_swatch_text_option_button"/> <element name="swatchTextByIndex" type="input" selector="input[name='swatchtext[value][option_{{index}}][0]']" parameterized="true"/> <element name="nthSwatchText" type="input" selector="#swatch-text-options-panel table tbody tr:nth-of-type({{var}}) td:nth-of-type(3) input" parameterized="true"/> + <element name="nthIsDefault" type="input" selector="(//input[@name='defaultvisual[]'])[{{var}}]" parameterized="true"/> <element name="nthSwatchAdminDescription" type="input" selector="#swatch-text-options-panel table tbody tr:nth-of-type({{var}}) td:nth-of-type(4) input" parameterized="true"/> <!-- Selector for Admin Description input where the index is zero-based --> <element name="swatchAdminDescriptionByIndex" type="input" selector="input[name='optiontext[value][option_{{index}}][0]']" parameterized="true"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 50dcfbf3da090..5d174e71012fd 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -49,7 +49,7 @@ <!-- Add new swatch option without label --> <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch1"/> - <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch1"> <argument name="index" value="0"/> </actionGroup> <click selector="{{AdminManageSwatchSection.nthChooseColor('1')}}" stepKey="clickChooseColor1"/> @@ -66,6 +66,34 @@ <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('0')}}" userInput="red" stepKey="fillAdmin1"/> + <!-- Add 2 additional new swatch options --> + <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch2"/> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> + <argument name="index" value="1"/> + </actionGroup> + <click selector="{{AdminManageSwatchSection.nthChooseColor('2')}}" stepKey="clickChooseColor2"/> + <actionGroup ref="setColorPickerByHex" stepKey="fillHex2"> + <argument name="nthColorPicker" value="2"/> + <argument name="hexColor" value="00ff00"/> + </actionGroup> + <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('1')}}" + userInput="green" stepKey="fillAdmin2"/> + + <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch3"/> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch3"> + <argument name="index" value="2"/> + </actionGroup> + <click selector="{{AdminManageSwatchSection.nthChooseColor('3')}}" stepKey="clickChooseColor3"/> + <actionGroup ref="setColorPickerByHex" stepKey="fillHex3"> + <argument name="nthColorPicker" value="3"/> + <argument name="hexColor" value="0000ff"/> + </actionGroup> + <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('2')}}" + userInput="blue" stepKey="fillAdmin3"/> + + <!-- Mark second option as default --> + <click selector="{{AdminManageSwatchSection.nthIsDefault('2')}}" stepKey="setSecondOptionAsDefault"/> + <!-- Go to Storefront Properties tab --> <scrollToTopOfPage stepKey="scrollToTop"/> <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="goToStorefrontPropertiesTab"/> @@ -73,7 +101,14 @@ <!-- Save the new product attribute --> <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave2"/> - <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" + <waitForPageLoad stepKey="waitForGridPageLoad"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="waitForSuccessMessage"/> + + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="visualSwatchAttribute"/> + </actionGroup> + <!-- Check attribute data --> + <seeCheckboxIsChecked selector="{{AdminManageSwatchSection.nthIsDefault('2')}}" stepKey="CheckDefaultOption"/> </test> </tests> \ No newline at end of file From 3aa29557064f31cb4bf8c72d3e8c3e3bff78ba99 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Mon, 8 Oct 2018 23:49:29 +0300 Subject: [PATCH 0428/1415] Declare index for schema consistency --- .../AsynchronousOperations/etc/db_schema.xml | 3 + .../etc/db_schema_whitelist.json | 88 ++++++++++--------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 94ee5a16b5b84..342326e6666f1 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -27,6 +27,9 @@ <constraint xsi:type="unique" name="MAGENTO_BULK_UUID"> <column name="uuid"/> </constraint> + <index name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> + <column name="user_id"/> + </index> </table> <table name="magento_operation" resource="default" engine="innodb" comment="Operation entity"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json index 365c8d5b9b0b1..423b7553ced2a 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json @@ -1,47 +1,51 @@ { - "magento_bulk": { - "column": { - "id": true, - "uuid": true, - "user_id": true, - "user_type": true, - "description": true, - "operation_count": true, - "start_time": true + "magento_bulk": { + "column": { + "id": true, + "uuid": true, + "user_id": true, + "user_type": true, + "description": true, + "operation_count": true, + "start_time": true + }, + "index": { + "MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID": true, + "MAGENTO_BULK_USER_ID": true + }, + "constraint": { + "PRIMARY": true, + "MAGENTO_BULK_UUID": true + } }, - "constraint": { - "PRIMARY": true, - "MAGENTO_BULK_UUID": true - } - }, - "magento_operation": { - "column": { - "id": true, - "bulk_uuid": true, - "topic_name": true, - "serialized_data": true, - "result_serialized_data": true, - "status": true, - "error_code": true, - "result_message": true - }, - "index": { - "MAGENTO_OPERATION_BULK_UUID_ERROR_CODE": true - }, - "constraint": { - "PRIMARY": true, - "MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID": true - } - }, - "magento_acknowledged_bulk": { - "column": { - "id": true, - "bulk_uuid": true + "magento_operation": { + "column": { + "id": true, + "bulk_uuid": true, + "topic_name": true, + "serialized_data": true, + "result_serialized_data": true, + "status": true, + "error_code": true, + "result_message": true + }, + "index": { + "MAGENTO_OPERATION_BULK_UUID_ERROR_CODE": true + }, + "constraint": { + "PRIMARY": true, + "MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID": true + } }, - "constraint": { - "PRIMARY": true, - "MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID": true, - "MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID": true + "magento_acknowledged_bulk": { + "column": { + "id": true, + "bulk_uuid": true + }, + "constraint": { + "PRIMARY": true, + "MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID": true, + "MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID": true + } } - } } \ No newline at end of file From f7088960e269d2614258a39d9d97dc8ffe1c067d Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Mon, 8 Oct 2018 23:49:41 +0300 Subject: [PATCH 0429/1415] Fixed code style --- .../Api/Data/BulkSummaryInterface.php | 1 + .../AsynchronousOperations/Model/MassSchedule.php | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php index 9593cb983950a..a433ec0953a83 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/BulkSummaryInterface.php @@ -43,6 +43,7 @@ public function getUserType(); /** * Set user type + * * @param int $userType * @return $this */ diff --git a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php index 28a360adc5101..eae92e1663fc8 100644 --- a/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php +++ b/app/code/Magento/AsynchronousOperations/Model/MassSchedule.php @@ -23,6 +23,8 @@ /** * Class MassSchedule used for adding multiple entities as Operations to Bulk Management with the status tracking + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) Suppressed without refactoring to not introduce BiC */ class MassSchedule { @@ -93,10 +95,10 @@ public function __construct( /** * Schedule new bulk operation based on the list of entities * - * @param $topicName - * @param $entitiesArray - * @param null $groupId - * @param null $userId + * @param string $topicName + * @param array $entitiesArray + * @param string $groupId + * @param string $userId * @return AsyncResponseInterface * @throws BulkException * @throws LocalizedException From 80f19c10e6786f375bd7574ca7cb22b3ac37b8cc Mon Sep 17 00:00:00 2001 From: Zack Craig <zack@zack6849.com> Date: Mon, 8 Oct 2018 17:23:48 -0400 Subject: [PATCH 0430/1415] Fix Typo in Data\Form\Element\Factory.php Sorry for the small PR! --- lib/internal/Magento/Framework/Data/Form/Element/Factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php index 69f9fb18411d9..25cf8d3fb3b54 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php @@ -81,7 +81,7 @@ public function create($elementType, array $config = []) $element = $this->_objectManager->create($className, $config); if (!$element instanceof AbstractElement) { throw new \InvalidArgumentException( - $className . ' doesn\'n extend \Magento\Framework\Data\Form\Element\AbstractElement' + $className . ' doesn\'t extend \Magento\Framework\Data\Form\Element\AbstractElement' ); } return $element; From 82df4f00588ded9c3aecdae744d7ecd76ebccc9f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 8 Oct 2018 16:24:03 -0500 Subject: [PATCH 0431/1415] MAGETWO-71660: "Recently Ordered" widget conatins no more 5 products if qty of products > 5 --- app/code/Magento/Sales/Model/Order.php | 9 ++- .../CustomerData/LastOrderedItemsTest.php | 46 +++++++++++ ...with_customer_and_multiple_order_items.php | 12 +++ .../_files/order_with_multiple_items.php | 81 +++++++++++++++++++ 4 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 14c6154f0cb0a..ca8063aa57884 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -1337,7 +1337,10 @@ public function getParentItemsRandomCollection($limit = 1) */ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false) { - $collection = $this->_orderItemCollectionFactory->create()->setOrderFilter($this)->setRandomOrder(); + $collection = $this->_orderItemCollectionFactory->create() + ->setOrderFilter($this) + ->setRandomOrder() + ->setPageSize($limit); if ($nonChildrenOnly) { $collection->filterByParent(); @@ -1351,9 +1354,7 @@ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false) $products )->setVisibility( $this->_productVisibility->getVisibleInSiteIds() - )->addPriceData()->setPageSize( - $limit - )->load(); + )->addPriceData()->load(); foreach ($collection as $item) { $product = $productsCollection->getItemById($item->getProductId()); diff --git a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php new file mode 100644 index 0000000000000..d0c2144c951e9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\CustomerData; + +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; +use Magento\Customer\Model\Session; + +/** + * @magentoAppIsolation enabled + */ +class LastOrderedItemsTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + public function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer_and_multiple_order_items.php + */ + public function testDefaultFormatterIsAppliedWhenBasicIntegration() + { + /** @var Session $customerSession */ + $customerSession = $this->objectManager->get(Session::class); + $customerSession->loginById(1); + + /** @var LastOrderedItems $customerDataSectionSource */ + $customerDataSectionSource = $this->objectManager->get(LastOrderedItems::class); + $data = $customerDataSectionSource->getSectionData(); + $this->assertEquals( + LastOrderedItems::SIDEBAR_ORDER_LIMIT, + count($data['items']), + 'Section items count should not be greater then ' . LastOrderedItems::SIDEBAR_ORDER_LIMIT + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php new file mode 100644 index 0000000000000..06d3667f4d057 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +include __DIR__ . '/order_with_multiple_items.php'; +include __DIR__ . '/../../../Magento/Customer/_files/customer.php'; + +$customerIdFromFixture = 1; +/** @var $order \Magento\Sales\Model\Order */ +$order->setCustomerId($customerIdFromFixture)->setCustomerIsGuest(false)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php new file mode 100644 index 0000000000000..4fa84e4e28f01 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'order.php'; +/** @var \Magento\Catalog\Model\Product $product */ +/** @var \Magento\Sales\Model\Order $order */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_duplicated.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_full_option_set.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_url_key.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_all_fields.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_custom_attribute.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +/** @var array $orderItemData */ +foreach ($orderItems as $orderItemData) { + /** @var $orderItem \Magento\Sales\Model\Order\Item */ + $orderItem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Item::class + ); + $orderItem + ->setData($orderItemData) + ->save(); +} From fd226244e7350fd1ccad97c73ae53ff4d91dd706 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 8 Oct 2018 17:01:49 -0500 Subject: [PATCH 0432/1415] MAGETWO-94962: Unable to set default option for swatch attribute --- ...dminCreateDropdownProductAttributeTest.xml | 6 ++--- .../Catalog/view/adminhtml/web/js/options.js | 11 ++------ .../adminhtml/web/js/product-attributes.js | 13 +++------- .../Serialize/Serializer/FormData.php | 25 +------------------ 4 files changed, 9 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml index d9942e9fc1b46..c3e0b22bc5afd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -13,8 +13,8 @@ <title value="Admin should be able to create dropdown product attribute"/> <description value="Admin should be able to create dropdown product attribute"/> <severity value="BLOCKER"/> - <testCaseId value="MC-4140"/> - <group value="attribute"/> + <testCaseId value="MC-4982"/> + <group value="Catalog"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="login"/> @@ -68,7 +68,7 @@ <!-- Check attribute data --> <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" stepKey="secondOptionAdminLabel"/> - <assertEquals actual="$secondOptionAdminLabel" expected="Fish & Chips" + <assertEquals actual="$secondOptionAdminLabel" expected="'Fish & Chips'" stepKey="assertSecondOption"/> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 24870a9e675f3..5a8dc1df86074 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -182,22 +182,15 @@ define([ }); } editForm.on('beforeSubmit', function () { - var optionsValues = [], - optionContainer = optionPanel.find('table tbody'); + var optionContainer = optionPanel.find('table tbody'); if (optionPanel.hasClass(activePanelClass)) { - optionContainer.find('input,select,textarea') - .serializeArray() - .map(function (el) { - optionsValues.push(el.name + '=' + el.value); - }); - jQuery('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(JSON.stringify(optionsValues)) + .val(optionContainer.find('input, select, textarea').serialize()) .prependTo(editForm); } tableBody = optionContainer.detach(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index cf2b91e2df23b..2f8fcbdd7d40d 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -438,26 +438,19 @@ define([ .collapse('hide'); editForm.on('beforeSubmit', function () { - var swatchValues = [], - optionContainer; + var optionContainer; activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); if (activePanel.hasClass(activePanelClass)) { - optionContainer - .find('input,select,textarea') - .serializeArray() - .map(function (el) { - swatchValues.push(el.name + '=' + el.value); - }); - $('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(JSON.stringify(swatchValues)) + .val(optionContainer + .find('input, select, textarea').serialize()) .prependTo(editForm); } diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php index a945822d92f97..b2597afdf92a5 100644 --- a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php +++ b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php @@ -13,19 +13,6 @@ */ class FormData { - /** - * @var Json - */ - private $serializer; - - /** - * @param Json $serializer - */ - public function __construct(Json $serializer) - { - $this->serializer = $serializer; - } - /** * Provides form data from the serialized data. * @@ -35,18 +22,8 @@ public function __construct(Json $serializer) */ public function unserialize(string $serializedData): array { - $encodedFields = $this->serializer->unserialize($serializedData); - - if (!is_array($encodedFields)) { - throw new \InvalidArgumentException('Unable to unserialize value.'); - } - $formData = []; - foreach ($encodedFields as $item) { - $decodedFieldData = []; - parse_str($item, $decodedFieldData); - $formData = array_replace_recursive($formData, $decodedFieldData); - } + parse_str($serializedData, $formData); return $formData; } From 02bdadd38cd023840ed85cca43b6091c3457d94a Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 9 Oct 2018 11:33:27 +0300 Subject: [PATCH 0433/1415] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../view/frontend/web/js/model/checkout-data-resolver.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index cd4c59df51187..1c2438889c170 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -214,6 +214,7 @@ define([ selectedBillingAddress = checkoutData.getSelectedBillingAddress(); newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); + if (selectedBillingAddress) { if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { //eslint-disable-line selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); From e819fc98e142b3f93a45cad3ae6ee061209265a5 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 13:00:35 +0300 Subject: [PATCH 0434/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Test/AdminSimpleProductImagesTest.xml | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index 69931395a35d5..b10c8e5ad54a0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -87,10 +87,9 @@ <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorMedium"/> <!-- 10~ mb is allowed --> - <!-- Skipped MAGETWO-94092 --> - <!--<attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge"/> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge"/> <waitForPageLoad stepKey="waitForUploadLarge"/> - <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge"/>--> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge"/> <!-- *.gif is allowed --> <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="gif.gif" stepKey="attachGif"/> @@ -115,8 +114,7 @@ <!-- See all of the images that we uploaded --> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('small')}}" stepKey="seeSmall"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('medium')}}" stepKey="seeMedium"/> - <!-- Skipped MAGETWO-94092 --> - <!--<seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge"/>--> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('gif')}}" stepKey="seeGif"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('jpg')}}" stepKey="seeJpg"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('png')}}" stepKey="seePng"/> @@ -136,9 +134,9 @@ <!-- Upload an image --> <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages2"/> - <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="medium.jpg" stepKey="attachMedium2"/> - <waitForPageLoad stepKey="waitForUploadMedium2"/> - <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorMedium2"/> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge2"/> + <waitForPageLoad stepKey="waitForUploadLarge2"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge2"/> <!-- Set url key --> <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection2"/> @@ -154,16 +152,16 @@ <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku3"> <argument name="product" value="$$secondProduct$$"/> </actionGroup> - <seeElement selector="img.admin__control-thumbnail[src*='/medium']" stepKey="seeImgInGrid"/> + <seeElement selector="img.admin__control-thumbnail[src*='/large']" stepKey="seeImgInGrid"/> <!-- Go to the category page and see the uploaded image --> <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage2"/> - <seeElement selector=".products-grid img[src*='/medium']" stepKey="seeUploadedImg"/> + <seeElement selector=".products-grid img[src*='/large']" stepKey="seeUploadedImg"/> <!-- Go to the product page and see the uploaded image --> <amOnPage url="$$secondProduct.name$$.html" stepKey="goToStorefront2"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('medium')}}" stepKey="seeMedium2"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('Large')}}" stepKey="seeLarge2"/> </test> <test name="AdminSimpleProductRemoveImagesTest"> From 152bbd9a0900257c6cf73381b8bc5a81fa2457d3 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Tue, 9 Oct 2018 15:01:53 +0300 Subject: [PATCH 0435/1415] MAGETWO-95512: [2.3] Unable to create invoice for an order via Braintree PayPal - Added an exception if Payment Token is not available --- .../Request/PayPal/VaultDataBuilder.php | 2 + .../Request/VaultCaptureDataBuilder.php | 5 + .../Request/VaultCaptureDataBuilderTest.php | 95 +++++++++++++------ app/code/Magento/Braintree/i18n/en_US.csv | 1 + 4 files changed, 72 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php index a035c84b4cafd..4d63ee4125b74 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php @@ -49,6 +49,8 @@ public function build(array $buildSubject) $payment = $paymentDO->getPayment(); $data = $payment->getAdditionalInformation(); + // the payment token could be stored only if a customer checks the Vault flow on storefront + // see https://developers.braintreepayments.com/guides/paypal/vault/javascript/v2#invoking-the-vault-flow if (!empty($data[VaultConfigProvider::IS_ACTIVE_CODE])) { $result[self::$optionsKey] = [ self::$storeInVaultOnSuccess => true diff --git a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php index 4280663178efb..950634ba2d9e2 100644 --- a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php @@ -6,6 +6,8 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Braintree\Gateway\SubjectReader; +use Magento\Framework\Exception\LocalizedException; +use Magento\Payment\Gateway\Command\CommandException; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; @@ -41,6 +43,9 @@ public function build(array $buildSubject) $payment = $paymentDO->getPayment(); $extensionAttributes = $payment->getExtensionAttributes(); $paymentToken = $extensionAttributes->getVaultPaymentToken(); + if ($paymentToken === null) { + throw new CommandException(__('The Payment Token is not available to perform the request.')); + } return [ 'amount' => $this->formatPrice($this->subjectReader->readAmount($buildSubject)), 'paymentMethodToken' => $paymentToken->getGatewayToken() diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php index 25ccd8b32d10e..d4e1f2745e3f3 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php @@ -3,10 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Braintree\Test\Unit\Gateway\Request; -use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Api\Data\OrderPaymentExtension; use Magento\Sales\Model\Order\Payment; @@ -26,47 +28,46 @@ class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase /** * @var PaymentDataObjectInterface|MockObject */ - private $paymentDOMock; + private $paymentDO; /** * @var Payment|MockObject */ - private $paymentMock; + private $payment; /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + * @var SubjectReader|MockObject */ - private $subjectReaderMock; + private $subjectReader; /** * @inheritdoc */ - protected function setUp() + protected function setUp(): void { - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->getMockBuilder(Payment::class) + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); + $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->paymentDOMock->expects(static::once()) - ->method('getPayment') - ->willReturn($this->paymentMock); + $this->paymentDO->method('getPayment') + ->willReturn($this->payment); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) ->disableOriginalConstructor() ->getMock(); - $this->builder = new VaultCaptureDataBuilder($this->subjectReaderMock); + $this->builder = new VaultCaptureDataBuilder($this->subjectReader); } /** - * \Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder::build + * Checks the result after builder execution. */ - public function testBuild() + public function testBuild(): void { $amount = 30.00; $token = '5tfm4c'; $buildSubject = [ - 'payment' => $this->paymentDOMock, + 'payment' => $this->paymentDO, 'amount' => $amount, ]; @@ -75,36 +76,68 @@ public function testBuild() 'paymentMethodToken' => $token, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($buildSubject) - ->willReturn($this->paymentDOMock); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') + ->willReturn($this->paymentDO); + $this->subjectReader->method('readAmount') ->with($buildSubject) ->willReturn($amount); - $paymentExtensionMock = $this->getMockBuilder(OrderPaymentExtension::class) + /** @var OrderPaymentExtension|MockObject $paymentExtension */ + $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) ->setMethods(['getVaultPaymentToken']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $paymentTokenMock = $this->getMockBuilder(PaymentToken::class) + /** @var PaymentToken|MockObject $paymentToken */ + $paymentToken = $this->getMockBuilder(PaymentToken::class) ->disableOriginalConstructor() ->getMock(); - $paymentExtensionMock->expects(static::once()) - ->method('getVaultPaymentToken') - ->willReturn($paymentTokenMock); - $this->paymentMock->expects(static::once()) - ->method('getExtensionAttributes') - ->willReturn($paymentExtensionMock); + $paymentExtension->method('getVaultPaymentToken') + ->willReturn($paymentToken); + $this->payment->method('getExtensionAttributes') + ->willReturn($paymentExtension); - $paymentTokenMock->expects(static::once()) - ->method('getGatewayToken') + $paymentToken->method('getGatewayToken') ->willReturn($token); $result = $this->builder->build($buildSubject); self::assertEquals($expected, $result); } + + /** + * Checks a builder execution if Payment Token doesn't exist. + * + * @expectedException \Magento\Payment\Gateway\Command\CommandException + * @expectedExceptionMessage The Payment Token is not available to perform the request. + */ + public function testBuildWithoutPaymentToken(): void + { + $amount = 30.00; + $buildSubject = [ + 'payment' => $this->paymentDO, + 'amount' => $amount, + ]; + + $this->subjectReader->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDO); + $this->subjectReader->method('readAmount') + ->with($buildSubject) + ->willReturn($amount); + + /** @var OrderPaymentExtension|MockObject $paymentExtension */ + $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) + ->setMethods(['getVaultPaymentToken']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->payment->method('getExtensionAttributes') + ->willReturn($paymentExtension); + $paymentExtension->method('getVaultPaymentToken') + ->willReturn(null); + + $this->builder->build($buildSubject); + } } diff --git a/app/code/Magento/Braintree/i18n/en_US.csv b/app/code/Magento/Braintree/i18n/en_US.csv index 6bf677151ed0d..7bd305f546dc6 100644 --- a/app/code/Magento/Braintree/i18n/en_US.csv +++ b/app/code/Magento/Braintree/i18n/en_US.csv @@ -192,3 +192,4 @@ Currency,Currency "Too many concurrent attempts to refund this transaction. Try again later.","Too many concurrent attempts to refund this transaction. Try again later." "Too many concurrent attempts to void this transaction. Try again later.","Too many concurrent attempts to void this transaction. Try again later." "Braintree Settlement","Braintree Settlement" +"The Payment Token is not available to perform the request.","The Payment Token is not available to perform the request." From b4181a0795e56c9954f6c03454af5e765727c597 Mon Sep 17 00:00:00 2001 From: Nick Shatilo <shatilo.nick@gmail.com> Date: Thu, 4 Oct 2018 12:29:02 +0300 Subject: [PATCH 0436/1415] fix(Webapi Xml Renderer - 18361): removed the not needed ampersand replacement, covered by tests --- .../Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php | 4 ++-- .../Webapi/Test/Unit/Rest/Response/Renderer/XmlTest.php | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php b/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php index b4cfc61611a93..62b0d30b294b6 100644 --- a/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php +++ b/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php @@ -111,8 +111,7 @@ protected function _formatValue($value) /** Without the following transformation boolean values are rendered incorrectly */ $value = $value ? 'true' : 'false'; } - $replacementMap = ['&' => '&']; - return str_replace(array_keys($replacementMap), array_values($replacementMap), $value); + return (string) $value; } /** @@ -166,3 +165,4 @@ protected function _prepareKey($key) return $key; } } + diff --git a/lib/internal/Magento/Framework/Webapi/Test/Unit/Rest/Response/Renderer/XmlTest.php b/lib/internal/Magento/Framework/Webapi/Test/Unit/Rest/Response/Renderer/XmlTest.php index 396fbcdb1978b..71fb41491cc74 100644 --- a/lib/internal/Magento/Framework/Webapi/Test/Unit/Rest/Response/Renderer/XmlTest.php +++ b/lib/internal/Magento/Framework/Webapi/Test/Unit/Rest/Response/Renderer/XmlTest.php @@ -76,6 +76,11 @@ public function providerXmlRender() '<?xml version="1.0"?><response><item_7key>value</item_7key></response>', 'Invalid XML render with numeric symbol in data index.' ], + [ + ['key' => 'test & foo'], + '<?xml version="1.0"?><response><key>test & foo</key></response>', + 'Invalid XML render with ampersand symbol in data index.' + ], [ ['.key' => 'value'], '<?xml version="1.0"?><response><item_key>value</item_key></response>', From 3370c8110ef6c479a1886722c447593b0437340a Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 9 Oct 2018 17:28:12 +0400 Subject: [PATCH 0437/1415] MAGETWO-91628: Bundle product price doubled when switching currency - Add minor changes in test --- .../Mftf/Test/CurrencyChangingBundleProductInCartTest.xml | 6 ++++++ .../Test/Mftf/Section/CurrencySetupSection.xml | 1 + 2 files changed, 7 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml index b7e716dc15ece..ded8bb3c83337 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml @@ -28,12 +28,16 @@ <argument name="product" value="BundleProduct"/> </actionGroup> <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <waitForPageLoad stepKey="waitForClearFilter"/> <!--Clear Configs--> <amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdmin"/> <waitForPageLoad stepKey="waitForAdminLoginPageLoad"/> <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> <waitForPageLoad stepKey="waitForConfigCurrencySetupPageForUnselectEuroCurrency"/> <unselectOption selector="{{CurrencySetupSection.allowCurrencies}}" userInput="Euro" stepKey="unselectEuro"/> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click selector="{{CurrencySetupSection.currencyOptions}}" stepKey="closeOptions"/> + <waitForPageLoad stepKey="waitForCloseOptions"/> <click stepKey="saveUnselectedConfigs" selector="{{AdminConfigSection.saveButton}}"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="logout"/> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> @@ -57,6 +61,8 @@ <actionGroup ref="saveProductForm" stepKey="saveProduct"/> <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> <waitForPageLoad stepKey="waitForConfigCurrencySetupPage"/> + <conditionalClick selector="{{CurrencySetupSection.currencyOptions}}" dependentSelector="{{CurrencySetupSection.allowCurrencies}}" visible="false" stepKey="openOptions"/> + <waitForPageLoad stepKey="waitForOptions"/> <selectOption selector="{{CurrencySetupSection.allowCurrencies}}" parameterArray="['Euro', 'US Dollar']" stepKey="selectCurrencies"/> <click stepKey="saveConfigs" selector="{{AdminConfigSection.saveButton}}"/> <!-- Go to storefront BundleProduct --> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml index 16101409ad7e8..20fcd1e89360c 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CurrencySetupSection"> <element name="allowCurrencies" type="select" selector="#currency_options_allow"/> + <element name="currencyOptions" type="select" selector="#currency_options-head"/> </section> </sections> \ No newline at end of file From e250cbf3d3f52ed2590f2ad69b10fd489c416c59 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 8 Oct 2018 16:51:15 -0500 Subject: [PATCH 0438/1415] MAGETWO-95140: Placeholder image does not display on Storefront products --- app/code/Magento/Config/Model/Config.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php index c6e2412f7e58f..d7cfab8ccf10f 100644 --- a/app/code/Magento/Config/Model/Config.php +++ b/app/code/Magento/Config/Model/Config.php @@ -12,8 +12,8 @@ /** * Backend config model - * Used to save configuration * + * Used to save configuration * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api @@ -122,6 +122,7 @@ public function __construct( /** * Save config section + * * Require set: section, website, store and groups * * @throws \Exception @@ -237,13 +238,14 @@ private function getField(string $sectionId, string $groupId, string $fieldId): * Get field path * * @param Field $field + * @param string $fieldId * @param array &$oldConfig Need for compatibility with _processGroup() * @param array &$extraOldGroups Need for compatibility with _processGroup() * @return string */ - private function getFieldPath(Field $field, array &$oldConfig, array &$extraOldGroups): string + private function getFieldPath(Field $field, string $fieldId, array &$oldConfig, array &$extraOldGroups): string { - $path = $field->getGroupPath() . '/' . $field->getId(); + $path = $field->getGroupPath() . '/' . $fieldId; /** * Look for custom defined field path @@ -303,7 +305,7 @@ private function getChangedPaths( if (isset($groupData['fields'])) { foreach ($groupData['fields'] as $fieldId => $fieldData) { $field = $this->getField($sectionId, $groupId, $fieldId); - $path = $this->getFieldPath($field, $oldConfig, $extraOldGroups); + $path = $this->getFieldPath($field, $fieldId, $oldConfig, $extraOldGroups); if ($this->isValueChanged($oldConfig, $path, $fieldData)) { $changedPaths[] = $path; } @@ -398,7 +400,7 @@ protected function _processGroup( $backendModel->addData($data); $this->_checkSingleStoreMode($field, $backendModel); - $path = $this->getFieldPath($field, $extraOldGroups, $oldConfig); + $path = $this->getFieldPath($field, $fieldId, $extraOldGroups, $oldConfig); $backendModel->setPath($path)->setValue($fieldData['value']); $inherit = !empty($fieldData['inherit']); @@ -504,6 +506,7 @@ public function setDataByPath($path, $value) /** * Get scope name and scopeId + * * @todo refactor to scope resolver * @return void */ From 2850e6ee21634c9251125cfca82fb83b600e29eb Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 16:40:16 +0300 Subject: [PATCH 0439/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 3 + .../Magento/Backend/Block/Media/Uploader.php | 11 +++- .../Product/Helper/Form/Gallery/Content.php | 1 + app/code/Magento/Catalog/Helper/Image.php | 6 ++ .../Magento/Catalog/Model/Product/Image.php | 58 +++++++++++++++++-- .../Model/Product/Image/ParamsBuilder.php | 7 +++ 6 files changed, 81 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php index 1ba3daf35d2cf..6ec40cfa0b2d4 100644 --- a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -20,6 +20,9 @@ class ImageUploadConfig implements ArgumentInterface */ private $imageUploadConfig; + /** + * @param ImageUploadConfigInterface $imageUploadConfig + */ public function __construct(ImageUploadConfigInterface $imageUploadConfig) { $this->imageUploadConfig = $imageUploadConfig; diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index c332c91b54b27..941d6f37737fe 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -44,6 +44,13 @@ class Uploader extends \Magento\Backend\Block\Widget */ private $imageUploadConfig; + /** + * @var UploadConfigInterface + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface + */ + private $imageConfig; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\File\Size $fileSize @@ -58,10 +65,12 @@ public function __construct( array $data = [], Json $jsonEncoder = null, UploadConfigInterface $imageConfig = null, - ImageUploadConfigInterface $imageUploadConfig = null + ImageUploadConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); + $this->imageConfig = $imageConfig + ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); parent::__construct($context, $data); diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index d9e343fd2b3f0..063503682f4db 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -19,6 +19,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; + /** * Block for gallery content. */ diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 74153267f41d6..4a12bf7093943 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -407,6 +407,7 @@ public function rotate($angle) /** * Add watermark to image + * * size param in format 100x200 * * @param string $fileName @@ -534,6 +535,8 @@ public function getUrl() } /** + * Save changes + * * @return $this */ public function save() @@ -554,6 +557,8 @@ public function getResizedImageInfo() } /** + * Getter for placeholder url + * * @param null|string $placeholder * @return string */ @@ -656,6 +661,7 @@ protected function getWatermarkPosition() /** * Set watermark size + * * param size in format 100x200 * * @param string $size diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 564b817fc167e..8ad4e89d7b480 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -15,6 +15,8 @@ use Magento\Catalog\Model\Product\Image\ParamsBuilder; /** + * Image operations + * * @method string getFile() * @method string getLabel() * @method string getPosition() @@ -209,16 +211,16 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Image\Factory $imageFactory * @param \Magento\Framework\View\Asset\Repository $assetRepo * @param \Magento\Framework\View\FileSystem $viewFileSystem + * @param ImageFactory $viewAssetImageFactory + * @param PlaceholderFactory $viewAssetPlaceholderFactory * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data - * @param ImageFactory|null $viewAssetImageFactory - * @param PlaceholderFactory|null $viewAssetPlaceholderFactory - * @param SerializerInterface|null $serializer + * @param SerializerInterface $serializer * @param ParamsBuilder $paramsBuilder * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * @SuppressWarnings(PHPMD.UnusedLocalVariable)1 */ public function __construct( \Magento\Framework\Model\Context $context, @@ -255,6 +257,8 @@ public function __construct( } /** + * Set image width property + * * @param int $width * @return $this */ @@ -265,6 +269,8 @@ public function setWidth($width) } /** + * Get image width property + * * @return int */ public function getWidth() @@ -273,6 +279,8 @@ public function getWidth() } /** + * Set image height property + * * @param int $height * @return $this */ @@ -283,6 +291,8 @@ public function setHeight($height) } /** + * Get image height property + * * @return int */ public function getHeight() @@ -316,6 +326,8 @@ public function getQuality() } /** + * Set _keepAspectRatio property + * * @param bool $keep * @return $this */ @@ -326,6 +338,8 @@ public function setKeepAspectRatio($keep) } /** + * Set _keepFrame property + * * @param bool $keep * @return $this */ @@ -336,6 +350,8 @@ public function setKeepFrame($keep) } /** + * Set _keepTransparency + * * @param bool $keep * @return $this */ @@ -346,6 +362,8 @@ public function setKeepTransparency($keep) } /** + * Set _constrainOnly + * * @param bool $flag * @return $this */ @@ -356,6 +374,8 @@ public function setConstrainOnly($flag) } /** + * Set background color + * * @param int[] $rgbArray * @return $this */ @@ -366,6 +386,8 @@ public function setBackgroundColor(array $rgbArray) } /** + * Set size + * * @param string $size * @return $this */ @@ -420,6 +442,8 @@ public function setBaseFile($file) } /** + * Get base filename + * * @return string */ public function getBaseFile() @@ -428,6 +452,8 @@ public function getBaseFile() } /** + * Get new file + * * @deprecated 101.1.0 * @return bool|string */ @@ -447,6 +473,8 @@ public function isBaseFilePlaceholder() } /** + * Set image processor + * * @param MagentoImage $processor * @return $this */ @@ -457,6 +485,8 @@ public function setImageProcessor($processor) } /** + * Get image processor + * * @return MagentoImage */ public function getImageProcessor() @@ -475,6 +505,8 @@ public function getImageProcessor() } /** + * Resize image + * * @see \Magento\Framework\Image\Adapter\AbstractAdapter * @return $this */ @@ -488,6 +520,8 @@ public function resize() } /** + * Rotate image + * * @param int $angle * @return $this */ @@ -514,6 +548,7 @@ public function setAngle($angle) /** * Add watermark to image + * * size param in format 100x200 * * @param string $file @@ -573,6 +608,8 @@ public function setWatermark( } /** + * Save file + * * @return $this */ public function saveFile() @@ -587,6 +624,8 @@ public function saveFile() } /** + * Get url + * * @return string */ public function getUrl() @@ -595,6 +634,8 @@ public function getUrl() } /** + * Set destination subdir + * * @param string $dir * @return $this */ @@ -605,6 +646,8 @@ public function setDestinationSubdir($dir) } /** + * Get destination subdir + * * @return string */ public function getDestinationSubdir() @@ -613,6 +656,8 @@ public function getDestinationSubdir() } /** + * Check is image cached + * * @return bool */ public function isCached() @@ -780,7 +825,10 @@ public function getWatermarkHeight() } /** + * Clear cache + * * @return void + * @throws \Magento\Framework\Exception\FileSystemException */ public function clearCache() { @@ -793,6 +841,7 @@ public function clearCache() /** * First check this file on FS + * * If it doesn't exist - try to download it from DB * * @param string $filename @@ -811,6 +860,7 @@ protected function _fileExists($filename) /** * Return resized product image information + * * @return array * @throws NotLoadInfoImageException */ diff --git a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php index 21fde84931fa6..f6be7f7392b5e 100644 --- a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php +++ b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php @@ -65,6 +65,8 @@ public function __construct( } /** + * Build image params + * * @param array $imageArguments * @return array * @SuppressWarnings(PHPMD.NPathComplexity) @@ -85,6 +87,8 @@ public function build(array $imageArguments): array } /** + * Overwrite default values + * * @param array $imageArguments * @return array */ @@ -110,6 +114,8 @@ private function overwriteDefaultValues(array $imageArguments): array } /** + * Get watermark + * * @param string $type * @return array */ @@ -150,6 +156,7 @@ private function getWatermark(string $type): array /** * Get frame from product_image_white_borders + * * @return bool */ private function hasDefaultFrame(): bool From 38abe3d4558df5ffaa91e3ba5ed7fa73c5172a42 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 16:50:25 +0300 Subject: [PATCH 0440/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Helper/Image.php | 4 ++-- app/code/Magento/Catalog/Model/Product/Image.php | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 4a12bf7093943..170f1209ad9e6 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -408,7 +408,7 @@ public function rotate($angle) /** * Add watermark to image * - * size param in format 100x200 + * Size param in format 100x200 * * @param string $fileName * @param string $position @@ -662,7 +662,7 @@ protected function getWatermarkPosition() /** * Set watermark size * - * param size in format 100x200 + * Param size in format 100x200 * * @param string $size * @return $this diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 8ad4e89d7b480..adde1263e1bf9 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -549,7 +549,7 @@ public function setAngle($angle) /** * Add watermark to image * - * size param in format 100x200 + * Size param in format 100x200 * * @param string $file * @param string $position @@ -690,7 +690,8 @@ public function getWatermarkFile() /** * Get relative watermark file path - * or false if file not found + * + * Return false if file not found * * @return string | bool */ From dd560f3c985e890fd21cb97b3fd6b5f5b190a312 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 9 Oct 2018 16:32:45 +0300 Subject: [PATCH 0441/1415] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Integration test fix --- .../integration/testsuite/Magento/Catalog/_files/categories.php | 2 +- .../Magento/CatalogImportExport/Model/Import/ProductTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index a903274793c34..9a1a6f24dffc8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -84,7 +84,7 @@ $category = $objectManager->create(\Magento\Catalog\Model\Category::class); $category->isObjectNew(true); $category->setId(6) - ->setName('Category 2') + ->setName('Category 2.1') ->setParentId(2) ->setPath('1/2/6') ->setLevel(2) diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 237d7660da9bd..296c36caed5a0 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -958,6 +958,7 @@ public function testInvalidSkuLink() $errors = $this->_model->setParameters( [ 'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, + Import::FIELD_NAME_VALIDATION_STRATEGY => null, 'entity' => 'catalog_product' ] )->setSource( From 6e03f0ff8d21259526d6948de51ed29266241d61 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 17:00:58 +0300 Subject: [PATCH 0442/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../view/adminhtml/templates/browser/content/uploader.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index c6810f774238c..54f42bb4ecc1f 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -19,9 +19,9 @@ foreach ($filters as $media_type) { $resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) ? "{action: 'resize', maxWidth: " - . $block->escapeHtml($block->getImageUploadMaxWidth()) + . $block->getImageUploadMaxWidth() . ", maxHeight: " - . $block->escapeHtml($block->getImageUploadMaxHeight()) + . $block->getImageUploadMaxHeight() . "}" : "{action: 'resize'}"; ?> @@ -153,7 +153,7 @@ require([ fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 }, - <?= /* @noEscape*/ $resizeConfig ?>, + <?= $block->escapeHtml($resizeConfig) ?>, { action: 'save' }] From 47978d74fb44398dd931cc762e53f1c802eab1a1 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <svizev.igor@gmail.com> Date: Tue, 9 Oct 2018 17:05:33 +0300 Subject: [PATCH 0443/1415] magento/magento2#18164 Checkout - Fix "Cannot read property 'code' on undefined" issue --- .../Checkout/view/frontend/web/js/view/progress-bar.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js index 683a18d0e4ead..b9233c8b702d9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js @@ -23,11 +23,17 @@ define([ /** @inheritdoc */ initialize: function () { + var steps; + this._super(); window.addEventListener('hashchange', _.bind(stepNavigator.handleHash, stepNavigator)); if (!window.location.hash) { - stepNavigator.setHash(stepNavigator.steps().sort(stepNavigator.sortItems)[0].code); + steps = stepNavigator.steps(); + + if (steps.length) { + stepNavigator.setHash(steps.sort(stepNavigator.sortItems)[0].code); + } } stepNavigator.handleHash(); From c010653dea66f41e758974d2ccb0df6222e40100 Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Fri, 5 Oct 2018 12:54:35 +0300 Subject: [PATCH 0444/1415] MAGETWO-95428: Recently viewed block shows the product which is currenly open --- .../view/frontend/web/js/product/provider.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/provider.js b/app/code/Magento/Catalog/view/frontend/web/js/product/provider.js index c53b2fa6e2a7a..b29ebe7d57d1c 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/provider.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/provider.js @@ -5,11 +5,13 @@ define([ 'underscore', + 'jquery', 'mageUtils', 'uiElement', 'Magento_Catalog/js/product/storage/storage-service', - 'Magento_Customer/js/customer-data' -], function (_, utils, Element, storage, customerData) { + 'Magento_Customer/js/customer-data', + 'Magento_Catalog/js/product/view/product-ids-resolver' +], function (_, $, utils, Element, storage, customerData, productResolver) { 'use strict'; return Element.extend({ @@ -135,11 +137,16 @@ define([ */ filterIds: function (ids) { var _ids = {}, - currentTime = new Date().getTime() / 1000; + currentTime = new Date().getTime() / 1000, + currentProductIds = productResolver($('#product_addtocart_form')); _.each(ids, function (id) { - if (currentTime - id['added_at'] < ~~this.idsStorage.lifetime) { + if ( + currentTime - id['added_at'] < ~~this.idsStorage.lifetime && + !_.contains(currentProductIds, id['product_id']) + ) { _ids[id['product_id']] = id; + } }, this); From 7d921b60f87eecd591194777f2bd8ab59fd37dd5 Mon Sep 17 00:00:00 2001 From: Logan Stellway <loganstellway@users.noreply.github.com> Date: Tue, 9 Oct 2018 07:52:02 -0700 Subject: [PATCH 0445/1415] Removes white space from end of line 384 --- pub/errors/processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 8b37798f468b8..e64956dce17c2 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -381,7 +381,7 @@ protected function _loadXml($xmlFile) /** * Render page - * + * * @param string $template * @return string */ From 65670eacceaa1d812ff251c2304540859e9b4142 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 18:18:57 +0300 Subject: [PATCH 0446/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/view/adminhtml/web/js/media-uploader.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 2a15f5262bda1..6789dfa3f2b8e 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -44,7 +44,9 @@ define([ }; if (isResizeEnabled === 0) { - resizeConfiguration = {action: 'resize'}; + resizeConfiguration = { + action: 'resize' + }; } this.element.find('input[type=file]').fileupload({ From 4811ede46c2446361c5bdcb9aeb879ed66ffebf0 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Fri, 5 Oct 2018 14:08:30 -0500 Subject: [PATCH 0447/1415] MAGETWO-95436: Unable to place orders with custom customer address attributes - Modified address-converter to suite QuoteShipmentEstimation endpoint payload. Fixed lint issues --- .../view/frontend/web/js/model/address-converter.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js index a1aacf6e80320..9b20a782c38d9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js @@ -58,6 +58,16 @@ define([ } delete addressData['region_id']; + if (addressData['custom_attributes']) { + addressData['custom_attributes'] = Object.entries(addressData['custom_attributes']) + .map(function (customAttribute) { + return { + 'attribute_code': customAttribute[0], + 'value': customAttribute[1] + }; + }); + } + return address(addressData); }, From 70b9091543b958f599249231e9f72a603c60c233 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Tue, 9 Oct 2018 12:04:56 -0500 Subject: [PATCH 0448/1415] MAGETWO-95111: Creating new storeview code uniqueness validation - added code change for validating the code uniqueness --- app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js b/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js index 0a692a9b868cc..c2a0d4dab1fb3 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js @@ -67,6 +67,7 @@ define([ * 'Confirm' action handler. */ confirm: function () { + $('body').trigger('processStart'); dataPost().postData(requestData); } } From 1550eb5e27f7e520612dcb4fe1d2c86de8ce42d6 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 9 Oct 2018 12:06:43 -0500 Subject: [PATCH 0449/1415] MAGETWO-94962: Unable to set default option for swatch attribute --- .../Catalog/view/adminhtml/web/js/options.js | 11 +++- .../adminhtml/web/js/product-attributes.js | 11 +++- .../Handler/CatalogProductAttribute/Curl.php | 62 +++++-------------- .../Handler/SwatchProductAttribute/Curl.php | 31 ++++++---- .../Adminhtml/Product/AttributeTest.php | 14 +++-- .../Adminhtml/Product/AttributeTest.php | 36 ++++++----- .../Serialize/Serializer/FormData.php | 25 +++++++- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 5a8dc1df86074..7adc0dcfdf408 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -182,15 +182,22 @@ define([ }); } editForm.on('beforeSubmit', function () { - var optionContainer = optionPanel.find('table tbody'); + var optionContainer = optionPanel.find('table tbody'), + optionsValues; if (optionPanel.hasClass(activePanelClass)) { + optionsValues = jQuery.map( + optionContainer.find('tr'), + function (row) { + return jQuery(row).find('input, select, textarea').serialize(); + } + ); jQuery('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(optionContainer.find('input, select, textarea').serialize()) + .val(JSON.stringify(optionsValues)) .prependTo(editForm); } tableBody = optionContainer.detach(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 2f8fcbdd7d40d..8b513bc8532db 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -438,19 +438,24 @@ define([ .collapse('hide'); editForm.on('beforeSubmit', function () { - var optionContainer; + var optionContainer, optionsValues; activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); if (activePanel.hasClass(activePanelClass)) { + optionsValues = $.map( + optionContainer.find('tr'), + function (row) { + return $(row).find('input, select, textarea').serialize(); + } + ); $('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(optionContainer - .find('input, select, textarea').serialize()) + .val(JSON.stringify(optionsValues)) .prependTo(editForm); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index 57d775cdeb736..7ecaeb5ea7b82 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -91,15 +91,18 @@ public function persist(FixtureInterface $fixture = null) $data['frontend_label'] = [0 => $data['frontend_label']]; if (isset($data['options'])) { + $optionsData = []; foreach ($data['options'] as $key => $values) { + $optionRowData = []; $index = 'option_' . $key; if ($values['is_default'] == 'Yes') { - $data['default'][] = $index; + $optionRowData['default'][] = $index; } - $data['option']['value'][$index] = [$values['admin'], $values['view']]; - $data['option']['order'][$index] = $key; + $optionRowData['option']['value'][$index] = [$values['admin'], $values['view']]; + $optionRowData['option']['order'][$index] = $key; + $optionsData[] = $optionRowData; } - unset($data['options']); + $data['options'] = $optionsData; } $data = $this->changeStructureOfTheData($data); @@ -139,12 +142,12 @@ public function persist(FixtureInterface $fixture = null) * @param array $data * @return array */ - protected function changeStructureOfTheData(array $data) + protected function changeStructureOfTheData(array $data): array { - $serializedOptions = $this->getSerializeOptions($data, ['option']); + $serializedOptions = $this->getSerializeOptions($data['options']); if ($serializedOptions) { $data['serialized_options'] = $serializedOptions; - unset($data['option']); + unset($data['options']); } return $data; @@ -154,52 +157,15 @@ protected function changeStructureOfTheData(array $data) * Provides serialized product attribute options. * * @param array $data - * @param array $optionKeys - * @return array + * @return string */ - protected function getSerializeOptions(array $data, array $optionKeys): string + protected function getSerializeOptions(array $data): string { $options = []; - foreach ($optionKeys as $optionKey) { - if (!empty($data[$optionKey])) { - $options = array_merge( - $options, - $this->getEncodedOptions([$optionKey => $data[$optionKey]]) - ); - } + foreach ($data as $optionRowData) { + $options[] = http_build_query($optionRowData); } return json_encode($options); } - - /** - * Provides encoded attribute values. - * - * @param array $data - * @return array - */ - private function getEncodedOptions(array $data): array - { - $optionsData = []; - $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($data)); - foreach ($iterator as $value) { - $depth = $iterator->getDepth(); - $option = ''; - - $level = 0; - $option .= $iterator->getSubIterator($level)->key(); - $level++; - - while ($level <= $depth) { - $option .= '[' . $iterator->getSubIterator($level)->key() . ']'; - $level++; - } - - $option .= '=' . $value; - - $optionsData[] = $option; - } - - return $optionsData; - } } diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php index 5e4a5cc45fe69..f4adb9dec1250 100644 --- a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php @@ -29,23 +29,32 @@ public function __construct(DataInterface $configuration, EventManagerInterface ]; } + /** + * @inheritdoc + */ + protected function changeStructureOfTheData(array $data): array + { + return parent::changeStructureOfTheData($data); + } + /** * Re-map options from default options structure to swatches structure, * as swatches was initially created with name convention differ from other attributes. * - * @param array $data - * @return array + * @inheritdoc */ - protected function changeStructureOfTheData(array $data) + protected function getSerializeOptions(array $data): string { - $data['optiontext'] = $data['option']; - $data['swatchtext'] = [ - 'value' => $data['option']['value'] - ]; - $data['serialized_options'] = $this->getSerializeOptions($data, ['optiontext', 'swatchtext']); - unset($data['option']); - $data = parent::changeStructureOfTheData($data); + $options = []; + foreach ($data as $optionRowData) { + $optionRowData['optiontext'] = $optionRowData['option']; + $optionRowData['swatchtext'] = [ + 'value' => $optionRowData['option']['value'] + ]; + unset($optionRowData['option']); + $options[] = http_build_query($optionRowData); + } - return $data; + return json_encode($options); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 1f70ad0f7df6b..101e9f596be52 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -298,13 +298,15 @@ public function testLargeOptionsDataSet() $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i . '_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "option[order][option_{$i}]={$order}"; - $optionsData []= "option[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "option[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "option[delete][option_{$i}="; + $optionId = 'option_' . $i; + $optionRowData = []; + $optionRowData["option"]["order"][$optionId] = $i + 1; + $optionRowData["option"]["value"][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData["option"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData["option"]["delete"][$optionId] = ''; + $optionsData[] = http_build_query($optionRowData); } $attributeData['serialized_options'] = json_encode($optionsData); $this->getRequest()->setMethod(HttpRequest::METHOD_POST); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 5b7a80bb38dfd..10f6703f583d7 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -55,15 +55,17 @@ private function getSwatchVisualDataSet(int $optionsCount) : array $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i .'_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "optionvisual[order][option_{$i}]={$order}"; - $optionsData []= "defaultvisual[]=option_{$i}"; - $optionsData []= "swatchvisual[value][option_{$i}]={$this->getRandomColor()}"; - $optionsData []= "optionvisual[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "optionvisual[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "optionvisual[delete][option_{$i}]="; + $optionId = 'option_' .$i; + $optionRowData = []; + $optionRowData["optionvisual"]["order"][$optionId] = $i + 1; + $optionRowData["defaultvisual"][] = $optionId; + $optionRowData["swatchvisual"]["value"][$optionId] = $this->getRandomColor(); + $optionRowData["optionvisual"]["value"][$optionId][0] = 'value_' . $i .'_admin'; + $optionRowData["optionvisual"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData["optionvisual"]["delete"][$optionId] = ''; + $optionsData[] = http_build_query($optionRowData); } return [ 'attribute_data' => array_merge_recursive( @@ -95,15 +97,17 @@ private function getSwatchTextDataSet(int $optionsCount) : array $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i . '_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "optiontext[order][option_{$i}]={$order}"; - $optionsData []= "defaulttext[]=option_{$i}"; - $optionsData []= "swatchtext[value][option_{$i}]=x{$i}"; - $optionsData []= "optiontext[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "optiontext[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "optiontext[delete][option_{$i}]="; + $optionId = 'option_' . $i; + $optionRowData = []; + $optionRowData["optiontext"]["order"][$optionId] = $i + 1; + $optionRowData["defaulttext"][] = $optionId; + $optionRowData["swatchtext"]["value"][$optionId] = 'x' . $i ; + $optionRowData["optiontext"]["value"][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData["optiontext"]["value"][$optionId][1]= $expectedOptionLabelOnStoreView; + $optionRowData["optiontext"]["delete"][$optionId]=''; + $optionsData[] = http_build_query($optionRowData); } return [ 'attribute_data' => array_merge_recursive( diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php index b2597afdf92a5..a945822d92f97 100644 --- a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php +++ b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php @@ -13,6 +13,19 @@ */ class FormData { + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct(Json $serializer) + { + $this->serializer = $serializer; + } + /** * Provides form data from the serialized data. * @@ -22,8 +35,18 @@ class FormData */ public function unserialize(string $serializedData): array { + $encodedFields = $this->serializer->unserialize($serializedData); + + if (!is_array($encodedFields)) { + throw new \InvalidArgumentException('Unable to unserialize value.'); + } + $formData = []; - parse_str($serializedData, $formData); + foreach ($encodedFields as $item) { + $decodedFieldData = []; + parse_str($item, $decodedFieldData); + $formData = array_replace_recursive($formData, $decodedFieldData); + } return $formData; } From 49058889979ca946e886b303541f4fdf116bc958 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 9 Oct 2018 14:06:13 -0500 Subject: [PATCH 0450/1415] MAGETWO-95505: Broken Swagger markup --- .../Swagger/view/frontend/templates/swagger-ui/index.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml b/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml index b20da68734579..4e1b50723782a 100644 --- a/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml +++ b/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml @@ -17,7 +17,7 @@ * @codingStandardsIgnoreFile */ -$schemaUrl = $block->getSchemaUrl(); +$schemaUrl = $block->escapeUrl($block->getSchemaUrl()); ?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0"> From f3b5613b878aa682aa3426374585bdf1b1cb58e1 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 9 Oct 2018 14:20:32 -0500 Subject: [PATCH 0451/1415] MAGETWO-95140: Placeholder image does not display on Storefront products - Add functional test --- .../Catalog/Test/Mftf/Data/ImageData.xml | 28 ++++ ...inProductImagePlaceholderConfigSection.xml | 37 +++++ ...inConfigureProductImagePlaceholderTest.xml | 145 ++++++++++++++++++ .../StorefrontMiniCartActionGroup.xml | 14 ++ .../Section/StorefrontMiniCartSection.xml | 1 + 5 files changed, 225 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml new file mode 100644 index 0000000000000..a2391dda54809 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="placeholderBaseImage" type="imageFile"> + <data key="file">adobe-base.jpg</data> + <data key="name">adobe-base</data> + <data key="extension">jpg</data> + </entity> + + <entity name="placeholderSmallImage" type="imageFile"> + <data key="file">adobe-small.jpg</data> + <data key="name">adobe-small</data> + <data key="extension">jpg</data> + </entity> + + <entity name="placeholderThumbnailImage" type="imageFile"> + <data key="file">adobe-thumb.jpg</data> + <data key="name">adobe-thumb</data> + <data key="extension">jpg</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml new file mode 100644 index 0000000000000..7558b13d624bb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminProductImagePlaceholderConfigSection"> + <element name="sectionHeader" type="text" selector="#catalog_placeholder-head"/> + <!--Base image placeholder--> + <element name="baseImageInput" type="file" selector="#catalog_placeholder_image_placeholder" timeout="10"/> + <element name="baseImageDelete" type="checkbox" selector="#catalog_placeholder_image_placeholder_delete"/> + <element name="baseImage" type="text" selector="#catalog_placeholder_image_placeholder_image"/> + <element name="baseImageBySrc" type="text" selector="#catalog_placeholder_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Small image placeholder--> + <element name="smallImageInput" type="file" selector="#catalog_placeholder_small_image_placeholder" timeout="10"/> + <element name="smallImageDelete" type="checkbox" selector="#catalog_placeholder_small_image_placeholder_delete"/> + <element name="smallImage" type="text" selector="#catalog_placeholder_small_image_placeholder_image"/> + <element name="smallImageBySrc" type="text" selector="#catalog_placeholder_small_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Swatch image placeholder--> + <element name="swatchImageInput" type="file" selector="#catalog_placeholder_swatch_image_placeholder" timeout="10"/> + <element name="swatchImageDelete" type="checkbox" selector="#catalog_placeholder_swatch_image_placeholder_delete"/> + <element name="swatchImage" type="text" selector="#catalog_placeholder_swatch_image_placeholder_image"/> + <element name="swatchImageBySrc" type="text" selector="#catalog_placeholder_swatch_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Thumbnail image placeholder--> + <element name="thumbnailImageInput" type="file" selector="#catalog_placeholder_thumbnail_placeholder" timeout="10"/> + <element name="thumbnailImageDelete" type="checkbox" selector="#catalog_placeholder_thumbnail_placeholder_delete"/> + <element name="thumbnailImage" type="text" selector="#catalog_placeholder_thumbnail_placeholder_image"/> + <element name="thumbnailImageBySrc" type="text" selector="#catalog_placeholder_thumbnail_placeholder_image[src*='{{var}}']" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml new file mode 100644 index 0000000000000..4d97dee56f059 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml @@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminConfigureProductImagePlaceholderTest"> + + <annotations> + <features value="Configuration"/> + <stories value="Configure product placeholder images"/> + <title value="Admin is able to configure product placeholder images"/> + <description value="Admin should be able to configure the images used for product image placeholders. The configured placeholders should be seen on the frontend when an image has no image."/> + <severity value="MAJOR"/> + <testCaseId value="MC-5005"/> + <group value="configuration"/> + </annotations> + + <before> + <createData entity="ApiCategory" stepKey="category"/> + <!--Create product with no images--> + <createData entity="ApiSimpleProduct" stepKey="productNoImages"> + <requiredEntity createDataKey="category"/> + </createData> + <!--Create product with small, base, and thumbnail image--> + <createData entity="ApiSimpleProduct" stepKey="productWithImages"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="productImage"> + <requiredEntity createDataKey="productWithImages"/> + </createData> + </before> + + <after> + <!--Unset product image placeholders--> + <amOnPage url="{{CatalogConfigPage.url}}" stepKey="goToCatalogConfigurationPageAfter"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoadAfter"/> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSectionAfter"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpenAfter"/> + <!--Delete base placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.baseImageDelete}}" stepKey="checkDeleteBasePlaceholder"/> + <!--Delete small placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.smallImageDelete}}" stepKey="checkDeleteSmallPlaceholder"/> + <!--Delete thumbnail placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageDelete}}" stepKey="checkDeleteThumbnailPlaceholder"/> + <!--Save config to delete placeholders--> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigWithPlaceholders"/> + <!--See placeholders are empty--> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection2"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen2"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.baseImage}}" stepKey="dontSeeBaseImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.smallImage}}" stepKey="dontSeeSmallImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImage}}" stepKey="dontSeeThumbnailImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.swatchImage}}" stepKey="dontSeeSwatchImageSet"/> + + <!--Delete prerequisite entities--> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="productNoImages" stepKey="deleteProductNoImages"/> + <deleteData createDataKey="productWithImages" stepKey="deleteProductWithImages"/> + </after> + + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminArea"/> + + <!--Admin area: configure Product Image Placeholders--> + <comment userInput="Configure product image placeholders in store config" stepKey="configurePlaceholderComment"/> + <amOnPage url="{{CatalogConfigPage.url}}" stepKey="goToCatalogConfigurationPage"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoad1"/> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection1"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen1"/> + <!--Set base placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" userInput="{{placeholderBaseImage.file}}" stepKey="uploadBasePlaceholder"/> + <!--Set small placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.smallImageInput}}" userInput="{{placeholderSmallImage.file}}" stepKey="uploadSmallPlaceholder"/> + <!--Set thumbnail placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageInput}}" userInput="{{placeholderThumbnailImage.file}}" stepKey="uploadThumbnailPlaceholder"/> + <!--Save config with placeholders--> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigWithPlaceholders"/> + <!--See images are saved--> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection2"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen2"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.baseImageBySrc(placeholderBaseImage.name)}}" stepKey="seeBasePlaceholderSet"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.smallImageBySrc(placeholderSmallImage.name)}}" stepKey="seeSmallPlaceholderSet"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageBySrc(placeholderThumbnailImage.name)}}" stepKey="seeThumbnailPlaceholderSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.swatchImage}}" stepKey="dontSeeSwatchImageSet"/> + + <!--See correct placeholder images on category page--> + <comment userInput="Check placeholder images on the storefront" stepKey="checkStorefrontComment"/> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryStorefront1"/> + <waitForPageLoad stepKey="waitForStorefrontCategory1"/> + <!--Product with no images uses placeholder--> + <seeElement selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" stepKey="seeProductNoImagesInCategory"/> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" userInput="src" stepKey="getSmallPlaceholderImageSrc"/> + <assertContains stepKey="checkSmallPlaceholderImage"> + <actualResult type="variable">$getSmallPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderSmallImage.name}}</expectedResult> + </assertContains> + <!--Product with images does not use placeholder--> + <seeElement selector="{{StorefrontCategoryProductSection.ProductTitleByName($$productWithImages.name$$)}}" stepKey="seeProductWithImagesInCategory"/> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$productWithImages.name$$)}}" userInput="src" stepKey="getSmallNonPlaceholderImageSrc"/> + <assertNotContains stepKey="checkSmallPlaceholderImageNotUsed"> + <actualResult type="variable">$getSmallNonPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderSmallImage.name}}</expectedResult> + </assertNotContains> + + <!--Check base image on product page--> + <!--Product which is using placeholder--> + <click selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" stepKey="goToProductNoImages"/> + <waitForPageLoad stepKey="waitForProductPageLoad1"/> + <seeInCurrentUrl url="$$productNoImages.sku$$" stepKey="seeCorrectProductPage1"/> + <seeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="seeBasePlaceholderImage"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart1"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded1"/> + <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart1"/> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productNoImages.name$$)}}" userInput="src" stepKey="getThumbnailPlaceholderImageSrc"/> + <assertContains stepKey="checkThumbnailPlaceholderImage"> + <actualResult type="variable">$getThumbnailPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderThumbnailImage.name}}</expectedResult> + </assertContains> + <actionGroup ref="removeProductFromMiniCart" stepKey="removeProductFromCart1"> + <argument name="productName" value="$$productNoImages.name$$"/> + </actionGroup> + <!--Product which is NOT using placeholder--> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryStorefront2"/> + <waitForPageLoad stepKey="waitForStorefrontCategory2"/> + <click selector="{{StorefrontCategoryProductSection.ProductImageByName($$productWithImages.name$$)}}" stepKey="goToProductWithImages"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <seeInCurrentUrl url="$$productWithImages.sku$$" stepKey="seeCorrectProductPage2"/> + <dontSeeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="dontSeeBasePlaceholderImage"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart2"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded2"/> + <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart2"/> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productWithImages.name$$)}}" userInput="src" stepKey="getThumbnailImageSrc"/> + <assertNotContains stepKey="checkThumbnailImage"> + <actualResult type="variable">$getThumbnailImageSrc</actualResult> + <expectedResult type="string">{{placeholderThumbnailImage.name}}</expectedResult> + </assertNotContains> + <actionGroup ref="removeProductFromMiniCart" stepKey="removeProductFromCart2"> + <argument name="productName" value="$$productWithImages.name$$"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml index cb53a2a4f381f..7a5c5e1d15872 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml @@ -21,4 +21,18 @@ <waitForElementVisible selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="waitForViewAndEditCartVisible"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="seeInMiniCart"/> </actionGroup> + + <!--Remove an item from the cart using minicart--> + <actionGroup name="removeProductFromMiniCart"> + <arguments> + <argument name="productName" type="string"/> + </arguments> + <conditionalClick selector="{{StorefrontMinicartSection.showCart}}" dependentSelector="{{StorefrontMinicartSection.miniCartOpened}}" visible="false" stepKey="openMiniCart"/> + <waitForElementVisible selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="waitForMiniCartOpen"/> + <click selector="{{StorefrontMinicartSection.deleteMiniCartItemByName(productName)}}" stepKey="clickDelete"/> + <waitForElementVisible selector="{{StoreFrontRemoveItemModalSection.message}}" stepKey="waitForConfirmationModal"/> + <see selector="{{StoreFrontRemoveItemModalSection.message}}" userInput="Are you sure you would like to remove this item from the shopping cart?" stepKey="seeDeleteConfirmationMessage"/> + <click selector="{{StoreFrontRemoveItemModalSection.ok}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="waitForDeleteToFinish"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index c8ff851ae54ab..231713075881e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -22,6 +22,7 @@ <element name="viewAndEditCart" type="button" selector=".action.viewcart" timeout="30"/> <element name="miniCartItemsText" type="text" selector=".minicart-items"/> <element name="deleteMiniCartItem" type="button" selector=".action.delete" timeout="30"/> + <element name="deleteMiniCartItemByName" type="button" selector="//ol[@id='mini-cart']//div[contains(., '{{var}}')]//a[contains(@class, 'delete')]" parameterized="true"/> <element name="miniCartSubtotalField" type="text" selector=".block-minicart .amount span.price"/> <element name="itemQuantity" type="input" selector="//a[text()='{{productName}}']/../..//input[contains(@class,'cart-item-qty')]" parameterized="true"/> <element name="itemQuantityUpdate" type="button" selector="//a[text()='{{productName}}']/../..//span[text()='Update']" parameterized="true"/> From ac2128993d3b0316ba6dc267d553a1d13001222b Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 9 Oct 2018 15:27:14 -0500 Subject: [PATCH 0452/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel --- .../Block/Adminhtml/Edit/ResetPasswordButton.php | 5 +---- .../Controller/Adminhtml/Index/ResetPassword.php | 4 ++-- .../view/adminhtml/web/edit/post-wrapper.js | 8 -------- .../Adminhtml/Index/ResetPasswordTest.php | 14 +++++++------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php index c38f182f275f2..aa93785116851 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php @@ -25,10 +25,7 @@ public function getButtonData() $data = [ 'label' => __('Reset Password'), 'class' => 'reset reset-password', - 'data_attribute' => [ - 'url' => $this->getResetPasswordUrl() - ], - 'on_click' => '', + 'on_click' => sprintf("location.href = '%s';", $this->getResetPasswordUrl()), 'sort_order' => 60, ]; } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 6ef6ddd0e732b..69af6f4fb1b27 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -5,11 +5,11 @@ */ namespace Magento\Customer\Controller\Adminhtml\Index; -use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\SecurityViolationException; -class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpPostActionInterface +class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** * Reset password handler diff --git a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js index 27fa5eb783bba..76b060015c5ff 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js +++ b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js @@ -44,12 +44,4 @@ define([ return false; }); - - $('#resetPassword').click(function () { - var url = $('#resetPassword').data('url'); - - getForm(url).appendTo('body').submit(); - - return false; - }); }); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php index 8fa77a7388be2..789978d8180d0 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -34,7 +34,7 @@ public function testResetPasswordSuccess() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -44,18 +44,18 @@ public function testResetPasswordSuccess() } /** - * Checks reset password functionality cannot be performed with GET request + * Checks reset password functionality cannot be performed with POST request * * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0 * @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0 * @magentoDataFixture Magento/Customer/_files/customer.php */ - public function testResetPasswordWithGet() + public function testResetPasswordWithPost() { $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); $this->dispatch('backend/customer/index/resetPassword'); $this->assertEquals('noroute', $this->getRequest()->getControllerName()); } @@ -74,7 +74,7 @@ public function testResetPasswordMinTimeError() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -97,7 +97,7 @@ public function testResetPasswordLimitError() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -122,7 +122,7 @@ public function testResetPasswordWithSecurityViolationException() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), From f7be8c8e1cc93bba9a5930ac72c839e7fc0127e4 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 9 Oct 2018 14:45:59 -0500 Subject: [PATCH 0453/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 --- app/code/Magento/Cms/Model/Wysiwyg/Config.php | 8 +++- .../Tinymce3/Model/Config/Gallery/Config.php | 48 +++++++++++++++++++ app/code/Magento/Tinymce3/composer.json | 2 + .../Magento/Tinymce3/etc/adminhtml/di.xml | 2 +- .../Wysiwyg/CompositeConfigProviderTest.php | 44 +++++++++++++++++ 5 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php create mode 100644 dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Config.php b/app/code/Magento/Cms/Model/Wysiwyg/Config.php index 5db3933dd1169..1da7b99c6d886 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Config.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Config.php @@ -89,8 +89,6 @@ class Config extends \Magento\Framework\DataObject implements ConfigInterface /** * @var array - * @deprecated - * @see \Magento\Cms\Model\Wysiwyg\Gallery\DefaultConfigProvider */ protected $_windowSize; @@ -207,6 +205,12 @@ public function getConfig($data = []) if ($this->_authorization->isAllowed('Magento_Cms::media_gallery')) { $this->configProvider->processGalleryConfig($config); + $config->addData( + [ + 'files_browser_window_width' => $this->_windowSize['width'], + 'files_browser_window_height' => $this->_windowSize['height'], + ] + ); } if ($config->getData('add_widgets')) { $this->configProvider->processWidgetConfig($config); diff --git a/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php b/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php new file mode 100644 index 0000000000000..d11a3fa6e8a0c --- /dev/null +++ b/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tinymce3\Model\Config\Gallery; + +/** + * Class Config adds information about required configurations to display media gallery of tinymce3 editor + * + * @deprecated use \Magento\Cms\Model\Wysiwyg\DefaultConfigProvider instead + */ +class Config implements \Magento\Framework\Data\Wysiwyg\ConfigProviderInterface +{ + /** + * @var \Magento\Backend\Model\UrlInterface + */ + private $backendUrl; + + /** + * @param \Magento\Backend\Model\UrlInterface $backendUrl + */ + public function __construct( + \Magento\Backend\Model\UrlInterface $backendUrl + ) { + $this->backendUrl = $backendUrl; + } + + /** + * Returns media gallery config + * + * @param \Magento\Framework\DataObject $config + * @return \Magento\Framework\DataObject + */ + public function getConfig(\Magento\Framework\DataObject $config) : \Magento\Framework\DataObject + { + $config->addData( + [ + 'add_images' => true, + 'files_browser_window_url' => $this->backendUrl->getUrl('cms/wysiwyg_images/index'), + ] + ); + + return $config; + } +} diff --git a/app/code/Magento/Tinymce3/composer.json b/app/code/Magento/Tinymce3/composer.json index 946bfe13f3473..52e980052a87f 100644 --- a/app/code/Magento/Tinymce3/composer.json +++ b/app/code/Magento/Tinymce3/composer.json @@ -4,9 +4,11 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", + "magento/module-backend": "*", "magento/module-ui": "*", "magento/module-variable": "*", "magento/module-widget": "*" + }, "suggest": { "magento/module-cms": "*" diff --git a/app/code/Magento/Tinymce3/etc/adminhtml/di.xml b/app/code/Magento/Tinymce3/etc/adminhtml/di.xml index bf1ec7748294e..53ab66c7ef21f 100644 --- a/app/code/Magento/Tinymce3/etc/adminhtml/di.xml +++ b/app/code/Magento/Tinymce3/etc/adminhtml/di.xml @@ -22,7 +22,7 @@ <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Tinymce3\Model\Config\Widget\Config</item> </argument> <argument name="galleryConfigProvider" xsi:type="array"> - <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Cms\Model\WysiwygDefaultConfig</item> + <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Tinymce3\Model\Config\Gallery\Config</item> </argument> </arguments> </type> diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php new file mode 100644 index 0000000000000..7e60039e86880 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\Tinymce3\Model\Wysiwyg; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\AuthorizationInterface; + +/** + * @magentoAppArea adminhtml + */ +class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase +{ + /** + * Test enabled module is able to modify WYSIWYG config + * + * @return void + * + * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter + */ + public function testTestModuleEnabledModuleIsAbleToModifyConfig() + { + $objectManager = Bootstrap::getObjectManager(); + $objectManager->configure([ + 'preferences' => [ + AuthorizationInterface::class => \Magento\Backend\Model\Search\AuthorizationMock::class + ] + ]); + $compositeConfigProvider = $objectManager->create(\Magento\Cms\Model\Wysiwyg\CompositeConfigProvider::class); + $model = $objectManager->create( + \Magento\Cms\Model\Wysiwyg\Config::class, + ['configProvider' => $compositeConfigProvider] + ); + $config = $model->getConfig(); + $this->assertArrayHasKey('add_images', $config); + $this->assertArrayHasKey('files_browser_window_url', $config); + $this->assertTrue($config['add_images']); + } +} From 3a7a1e358f8352f61c587f690850faf8b82b2282 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 9 Oct 2018 16:39:58 -0500 Subject: [PATCH 0454/1415] MAGETWO-94962: Unable to set default option for swatch attribute --- .../AdminProductAttributeActionGroup.xml | 7 ++++++ .../AdminProductAttributeOptionsSection.xml | 2 +- ...dminCreateDropdownProductAttributeTest.xml | 12 ++++------ ...ateVisualSwatchWithNonValidOptionsTest.xml | 4 +--- .../Adminhtml/Product/AttributeTest.php | 8 +++---- .../Adminhtml/Product/AttributeTest.php | 24 +++++++++---------- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 23687484f1012..5de3d40fff9b1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -20,4 +20,11 @@ <click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/> <waitForPageLoad stepKey="waitForPageLoad2" /> </actionGroup> + <actionGroup name="deleteProductAttribute" extends="navigateToCreatedProductAttribute"> + <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> + <click selector="{{ModalConfirmationSection.OkButton}}" stepKey="ClickOnDeleteButton"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" + stepKey="waitForSuccessMessage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml index 17ca306eeccfa..0f438540603d0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="DropdownAttributeOptionsSection"> - <element name="nthAdminLabel" type="input" + <element name="nthOptionAdminLabel" type="input" selector="(//*[@id='manage-options-panel']//tr[{{var}}]//input[contains(@name, 'option[value]')])[1]" parameterized="true"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml index c3e0b22bc5afd..525f81de6c48c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -12,7 +12,7 @@ <stories value="Create/configure Dropdown product attribute"/> <title value="Admin should be able to create dropdown product attribute"/> <description value="Admin should be able to create dropdown product attribute"/> - <severity value="BLOCKER"/> + <severity value="CRITICAL"/> <testCaseId value="MC-4982"/> <group value="Catalog"/> </annotations> @@ -21,11 +21,9 @@ </before> <after> <!-- Remove attribute --> - <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> <argument name="ProductAttribute" value="productDropDownAttribute"/> </actionGroup> - <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> - <actionGroup ref="logout" stepKey="logout"/> </after> @@ -49,11 +47,11 @@ <!-- Add new attribute options --> <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption1"/> - <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('1')}}" + <fillField selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('1')}}" userInput="Fish and Chips" stepKey="fillAdminValue1"/> <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption2"/> - <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + <fillField selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('2')}}" userInput="Fish & Chips" stepKey="fillAdminValue2"/> <!-- Save the new product attribute --> @@ -66,7 +64,7 @@ <argument name="ProductAttribute" value="productDropDownAttribute"/> </actionGroup> <!-- Check attribute data --> - <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('2')}}" stepKey="secondOptionAdminLabel"/> <assertEquals actual="$secondOptionAdminLabel" expected="'Fish & Chips'" stepKey="assertSecondOption"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 5d174e71012fd..b03f771875957 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -21,11 +21,9 @@ </before> <after> <!-- Remove attribute --> - <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> <argument name="ProductAttribute" value="visualSwatchAttribute"/> </actionGroup> - <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> - <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 101e9f596be52..ab8c29889eabd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -302,10 +302,10 @@ public function testLargeOptionsDataSet() $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' . $i; $optionRowData = []; - $optionRowData["option"]["order"][$optionId] = $i + 1; - $optionRowData["option"]["value"][$optionId][0] = 'value_' . $i . '_admin'; - $optionRowData["option"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; - $optionRowData["option"]["delete"][$optionId] = ''; + $optionRowData['option']['order'][$optionId] = $i + 1; + $optionRowData['option']['value'][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData['option']['value'][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData['option']['delete'][$optionId] = ''; $optionsData[] = http_build_query($optionRowData); } $attributeData['serialized_options'] = json_encode($optionsData); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 10f6703f583d7..f806674d29705 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -59,12 +59,12 @@ private function getSwatchVisualDataSet(int $optionsCount) : array $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' .$i; $optionRowData = []; - $optionRowData["optionvisual"]["order"][$optionId] = $i + 1; - $optionRowData["defaultvisual"][] = $optionId; - $optionRowData["swatchvisual"]["value"][$optionId] = $this->getRandomColor(); - $optionRowData["optionvisual"]["value"][$optionId][0] = 'value_' . $i .'_admin'; - $optionRowData["optionvisual"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; - $optionRowData["optionvisual"]["delete"][$optionId] = ''; + $optionRowData['optionvisual']['order'][$optionId] = $i + 1; + $optionRowData['defaultvisual'][] = $optionId; + $optionRowData['swatchvisual']['value'][$optionId] = $this->getRandomColor(); + $optionRowData['optionvisual']['value'][$optionId][0] = 'value_' . $i .'_admin'; + $optionRowData['optionvisual']['value'][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData['optionvisual']['delete'][$optionId] = ''; $optionsData[] = http_build_query($optionRowData); } return [ @@ -101,12 +101,12 @@ private function getSwatchTextDataSet(int $optionsCount) : array $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' . $i; $optionRowData = []; - $optionRowData["optiontext"]["order"][$optionId] = $i + 1; - $optionRowData["defaulttext"][] = $optionId; - $optionRowData["swatchtext"]["value"][$optionId] = 'x' . $i ; - $optionRowData["optiontext"]["value"][$optionId][0] = 'value_' . $i . '_admin'; - $optionRowData["optiontext"]["value"][$optionId][1]= $expectedOptionLabelOnStoreView; - $optionRowData["optiontext"]["delete"][$optionId]=''; + $optionRowData['optiontext']['order'][$optionId] = $i + 1; + $optionRowData['defaulttext'][] = $optionId; + $optionRowData['swatchtext']['value'][$optionId] = 'x' . $i ; + $optionRowData['optiontext']['value'][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData['optiontext']['value'][$optionId][1]= $expectedOptionLabelOnStoreView; + $optionRowData['optiontext']['delete'][$optionId]=''; $optionsData[] = http_build_query($optionRowData); } return [ From 0fcbe126eff6cc5268268ec1154a261d49369152 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Wed, 10 Oct 2018 11:55:29 +0300 Subject: [PATCH 0455/1415] magento/magento2#18164 Checkout - Fix "Cannot read property 'code' on undefined" issue --- .../Checkout/view/frontend/web/js/view/progress-bar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js index b9233c8b702d9..30ea9da1dd601 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js @@ -23,16 +23,16 @@ define([ /** @inheritdoc */ initialize: function () { - var steps; + var stepsValue; this._super(); window.addEventListener('hashchange', _.bind(stepNavigator.handleHash, stepNavigator)); if (!window.location.hash) { - steps = stepNavigator.steps(); + stepsValue = stepNavigator.steps(); - if (steps.length) { - stepNavigator.setHash(steps.sort(stepNavigator.sortItems)[0].code); + if (stepsValue.length) { + stepNavigator.setHash(stepsValue.sort(stepNavigator.sortItems)[0].code); } } From 77111659b520ebad13b53389f67144fddd5dfad6 Mon Sep 17 00:00:00 2001 From: Thiago Lima <thiagolimaufrj@gmail.com> Date: Wed, 10 Oct 2018 11:28:17 +0200 Subject: [PATCH 0456/1415] 18082 fix unit test --- .../Product/Initialization/Helper/Plugin/Configurable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php index 556939ec112f1..b5940e36aa792 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php @@ -158,7 +158,7 @@ protected function getVariationMatrix() $configurableMatrix = json_decode($configurableMatrix, true); foreach ($configurableMatrix as $item) { - if (isset($item['newProduct'])) { + if (isset($item['newProduct']) && $item['newProduct']) { $result[$item['variationKey']] = $this->mapData($item); if (isset($item['qty'])) { From 9b7d4ac8c03eade9c6e94262b2f868cdf3f36aca Mon Sep 17 00:00:00 2001 From: vaibhav <vaibhav.ahalpara@krishtechnolabs.com> Date: Sat, 8 Sep 2018 15:59:57 +0530 Subject: [PATCH 0457/1415] add error message in else condition --- .../OfflineShipping/Model/Carrier/Freeshipping.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php index b546237b82565..e85548b422201 100644 --- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php +++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php @@ -98,6 +98,20 @@ public function collectRates(RateRequest $request) $result->append($method); } + elseif ($this->getConfigData('showmethod')) + { + $error = $this->_rateErrorFactory->create(); + $error->setCarrier($this->_code); + $error->setCarrierTitle($this->getConfigData('title')); + $errorMsg = $this->getConfigData('specificerrmsg'); + $error->setErrorMessage( + $errorMsg ? $errorMsg : __( + 'Sorry, but we can\'t deliver to the destination country with this shipping module.' + ) + ); + + return $error; + } return $result; } From 67e1b01f6d8c90df57a70a3e9d56220234af27c2 Mon Sep 17 00:00:00 2001 From: vaibhav <vaibhav.ahalpara@krishtechnolabs.com> Date: Sun, 9 Sep 2018 18:27:00 +0530 Subject: [PATCH 0458/1415] Fix testCodeStyle issue --- .../Magento/OfflineShipping/Model/Carrier/Freeshipping.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php index e85548b422201..353f3c8e1f016 100644 --- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php +++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php @@ -109,10 +109,8 @@ public function collectRates(RateRequest $request) 'Sorry, but we can\'t deliver to the destination country with this shipping module.' ) ); - return $error; - } - + } return $result; } From 4938bbc5e51fc67cff8098719e7301d0cb4255d5 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 2 Oct 2018 15:33:55 -0500 Subject: [PATCH 0459/1415] Fixed codestyle --- .../Magento/OfflineShipping/Model/Carrier/Freeshipping.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php index 353f3c8e1f016..2373b5285ed00 100644 --- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php +++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php @@ -97,9 +97,7 @@ public function collectRates(RateRequest $request) $method->setCost('0.00'); $result->append($method); - } - elseif ($this->getConfigData('showmethod')) - { + } elseif ($this->getConfigData('showmethod')) { $error = $this->_rateErrorFactory->create(); $error->setCarrier($this->_code); $error->setCarrierTitle($this->getConfigData('title')); @@ -110,7 +108,7 @@ public function collectRates(RateRequest $request) ) ); return $error; - } + } return $result; } From 6ed47bb3ef8ad8b83b635f3b772a93319753be51 Mon Sep 17 00:00:00 2001 From: Volodymyr Hryvinskyi <volodymyr@hryvinskyi.com> Date: Wed, 10 Oct 2018 13:09:16 +0300 Subject: [PATCH 0460/1415] fix test --- .../testsuite/Magento/Framework/Session/SidResolverTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php index e67d9f8ad1846..5e70eb491b50c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php @@ -114,7 +114,7 @@ public function testGetSid($sid, $useFrontedSid, $isOwnOriginUrl, $testSid) $this->scopeConfig->expects( $this->any() )->method( - 'getValue' + 'isSetFlag' )->with( \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, \Magento\Store\Model\ScopeInterface::SCOPE_STORE From 9b2aeaae00187adf4fda25657757886d7f1a81d1 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Wed, 10 Oct 2018 13:15:26 +0300 Subject: [PATCH 0461/1415] MAGETWO-95313: [2.3] Missing URL Keys upon product import --- .../Model/Import/Product.php | 32 ++++++++++++++- .../Model/Import/ProductTest.php | 39 +++++++++++++++++++ ...ts_to_import_without_url_keys_and_name.csv | 3 ++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 7c56c266a64ef..2aae8fd808528 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1640,7 +1640,16 @@ protected function _saveProducts() } $rowScope = $this->getRowScope($rowData); - $rowData[self::URL_KEY] = $this->getUrlKey($rowData); + $urlKey = $this->getUrlKey($rowData); + if (!empty($rowData[self::URL_KEY])) { + // If url_key column and its value were in the CSV file + $rowData[self::URL_KEY] = $urlKey; + } else if($this->isNeedToChangeUrlKey($rowData)) { + // If url_key column was empty or even not declared in the CSV file but by the rules it is need to + // be setteed. In case when url_key is generating from name column we have to ensure that the bunch + // of products will pass for the event with url_key column. + $bunch[$rowNum][self::URL_KEY] = $rowData[self::URL_KEY] = $urlKey; + } $rowSku = $rowData[self::COL_SKU]; @@ -2889,6 +2898,27 @@ protected function getResource() return $this->_resource; } + /** + * Whether a url key is needed to be change. + * Returns false if + * + * @param array $rowData + * @return bool + */ + private function isNeedToChangeUrlKey(array $rowData): bool + { + $urlKey = $this->getUrlKey($rowData); + $productExists = $this->isSkuExist($rowData[self::COL_SKU]); + $markedToEraseUrlKey = isset($rowData[self::URL_KEY]); + // The product isn't new and the url key index wasn't marked for change. + if (!$urlKey && $productExists && !$markedToEraseUrlKey) { + // Seems there is no need to change the url key + return false; + } + + return true; + } + /** * Get product entity link field * diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 237d7660da9bd..0286cc184f0d5 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1643,6 +1643,45 @@ public function testImportWithoutUrlKeys() } } + /** + * Make sure the absence of a url_key column in the csv file won't erase the url key of the existing products. + * To reach the goal we need to not send the name column, as the url key is generated from it. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php + * @magentoDbIsolation disabled + * @magentoAppIsolation enabled + */ + public function testImportWithoutUrlKeysAndName() + { + $products = [ + 'simple1' => 'url-key', + 'simple2' => 'url-key2', + ]; + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); + $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $source = $this->objectManager->create( + \Magento\ImportExport\Model\Import\Source\Csv::class, + [ + 'file' => __DIR__ . '/_files/products_to_import_without_url_keys_and_name.csv', + 'directory' => $directory + ] + ); + + $errors = $this->_model->setParameters( + ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product'] + ) + ->setSource($source) + ->validateData(); + + $this->assertTrue($errors->getErrorsCount() == 0); + $this->_model->importData(); + + $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + foreach ($products as $productSku => $productUrlKey) { + $this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey()); + } + } + /** * @magentoAppIsolation enabled */ diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv new file mode 100644 index 0000000000000..8ea6ab92a0295 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv @@ -0,0 +1,3 @@ +sku,price +simple1,25 +simple2,34 From 7acbb9aafc28472e6d5695a47de25e99003c3405 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Wed, 10 Oct 2018 13:23:47 +0300 Subject: [PATCH 0462/1415] MAGETWO-95215: [GraphQL] Performance issue in filters realization --- lib/internal/Magento/Framework/GraphQl/Query/Fields.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Fields.php b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php index fb18fa1bfab8a..d0bc9591265eb 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/Fields.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php @@ -21,7 +21,7 @@ class Fields private $fieldsUsedInQuery = []; /** - * Prints AST to string. Capable of printing GraphQL queries and Type definition language. + * Set Query for extracting list of fields. * * @param string $query * @return void @@ -42,6 +42,7 @@ public function setQuery($query) ] ); } catch (\Exception $e) { + // If a syntax error is encountered do not collect fields } if (isset($queryFields['IntrospectionQuery'])) { // It must be possible to query any fields during introspection query From b0d7a268162d57f3f30a3488fca1afac104ae322 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 10 Oct 2018 13:53:30 +0300 Subject: [PATCH 0463/1415] MAGETWO-91679: Bundled SKUs are being assembled based on the product ID number - Integration test fix --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 67441cd944c4f..3729cd945758f 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -310,7 +310,7 @@ public function getSku($product) $selections = $this->getSelectionsByIds($selectionIds, $product); foreach ($selectionIds as $selectionId) { $entity = $selections->getItemByColumnValue('selection_id', $selectionId); - if ($entity->getEntityId()) { + if (isset($entity) && $entity->getEntityId()) { $skuParts[] = $entity->getSku(); } } From f7d55f4af8f1a27d9dcb8e4f93db0e0c78482ee4 Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Wed, 10 Oct 2018 14:51:54 +0300 Subject: [PATCH 0464/1415] MAGETWO-95491: Product Review "Save and Next" and "Save and Previous" not working --- .../Review/Model/ResourceModel/Review/Product/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 68dc8d753b5bd..145d9e48a8a7b 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -405,7 +405,7 @@ public function getResultingIds() $idsSelect = clone $this->getSelect(); $idsSelect->reset(Select::LIMIT_COUNT); $idsSelect->reset(Select::LIMIT_OFFSET); - $idsSelect->reset(Select::COLUMNS); + $idsSelect->columns('rt.review_id'); return $this->getConnection()->fetchCol($idsSelect); } From adb976306df15159bcc612b03ee962fa61ea465a Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Wed, 10 Oct 2018 15:05:02 +0300 Subject: [PATCH 0465/1415] MAGETWO-95313: [2.3] Missing URL Keys upon product import --- .../Magento/CatalogImportExport/Model/Import/Product.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 2aae8fd808528..6f8b2248d8d89 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1641,10 +1641,10 @@ protected function _saveProducts() $rowScope = $this->getRowScope($rowData); $urlKey = $this->getUrlKey($rowData); - if (!empty($rowData[self::URL_KEY])) { + if (!empty($rowData[self::URL_KEY])) { // If url_key column and its value were in the CSV file $rowData[self::URL_KEY] = $urlKey; - } else if($this->isNeedToChangeUrlKey($rowData)) { + } else if ($this->isNeedToChangeUrlKey($rowData)) { // If url_key column was empty or even not declared in the CSV file but by the rules it is need to // be setteed. In case when url_key is generating from name column we have to ensure that the bunch // of products will pass for the event with url_key column. @@ -2900,7 +2900,6 @@ protected function getResource() /** * Whether a url key is needed to be change. - * Returns false if * * @param array $rowData * @return bool From 87581cf49114445da5ac91b857c8415f5ffd0ab9 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Wed, 10 Oct 2018 07:22:46 -0500 Subject: [PATCH 0466/1415] MAGETWO-95111: Creating new store view with code uniqueness validation - added functional test to cover the bug fix --- .../Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 99ca7991e5e90..6ce33f3be3622 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -24,6 +24,7 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2" /> <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> From 38dadb1f19dfa304083c019ba619ccda4bb44426 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 10 Oct 2018 16:11:33 +0300 Subject: [PATCH 0467/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/view/adminhtml/web/js/media-uploader.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 6789dfa3f2b8e..e1d5a0a9debe5 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -135,8 +135,7 @@ define([ this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', - fileTypes: /^image\/(gif|jpeg|png)$/, - maxFileSize: this.options.maxFileSize + fileTypes: /^image\/(gif|jpeg|png)$/ }, resizeConfiguration, { From 9c19879740e5493eebf6b8e308cc57a26ac07eb1 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 10 Oct 2018 17:35:40 +0300 Subject: [PATCH 0468/1415] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Bug fix - Integration test fix --- .../Model/Metadata/CustomerMetadata.php | 27 +++++++++---------- app/code/Magento/Customer/etc/di.xml | 7 +++++ .../Customer/Model/CustomerMetadataTest.php | 19 ++++++++----- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php index 7e8f0b9236fe9..38f3fbcbdbded 100644 --- a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php +++ b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php @@ -33,16 +33,26 @@ class CustomerMetadata implements CustomerMetadataInterface */ private $attributeMetadataDataProvider; + /** + * List of system attributes which should be available to the clients. + * + * @var string[] + */ + private $systemAttributes; + /** * @param AttributeMetadataConverter $attributeMetadataConverter * @param AttributeMetadataDataProvider $attributeMetadataDataProvider + * @param string[] $systemAttributes */ public function __construct( AttributeMetadataConverter $attributeMetadataConverter, - AttributeMetadataDataProvider $attributeMetadataDataProvider + AttributeMetadataDataProvider $attributeMetadataDataProvider, + array $systemAttributes = [] ) { $this->attributeMetadataConverter = $attributeMetadataConverter; $this->attributeMetadataDataProvider = $attributeMetadataDataProvider; + $this->systemAttributes = $systemAttributes; } /** @@ -136,7 +146,7 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN if (!$isDataObjectMethod && (!$attributeMetadata->isSystem() - || in_array($attributeCode, $this->getAllowedSystemAttributesList()) + || in_array($attributeCode, $this->systemAttributes) ) ) { $customAttributes[] = $attributeMetadata; @@ -144,17 +154,4 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN } return $customAttributes; } - - /** - * Get list of system attributes which should be available to the clients - * - * @return array - */ - private function getAllowedSystemAttributesList() - { - return [ - 'disable_auto_group_change', - 'reward_update_notification' - ]; - } } diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 6e8c3dc68ed28..209f4794c6fcf 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -127,6 +127,13 @@ <argument name="groupManagement" xsi:type="object">Magento\Customer\Api\GroupManagementInterface\Proxy</argument> </arguments> </type> + <type name="Magento\Customer\Model\Metadata\CustomerMetadata"> + <arguments> + <argument name="systemAttributes" xsi:type="array"> + <item name="disable_auto_group_change" xsi:type="string">disable_auto_group_change</item> + </argument> + </arguments> + </type> <virtualType name="SectionInvalidationConfigReader" type="Magento\Framework\Config\Reader\Filesystem"> <arguments> <argument name="idAttributes" xsi:type="array"> diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php index 336b438661705..794fce17480fa 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php @@ -51,16 +51,23 @@ protected function setUp() public function testGetCustomAttributesMetadata() { - $customAttributesMetadata = $this->service->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata, "Invalid number of attributes returned."); + $customAttributesMetadataQty = count($this->service->getCustomAttributesMetadata()) ; // Verify the consistency of getCustomerAttributeMetadata() function from the 2nd call of the same service - $customAttributesMetadata1 = $this->service->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata1, "Invalid number of attributes returned."); + $customAttributesMetadata1Qty = count($this->service->getCustomAttributesMetadata()); + $this->assertEquals( + $customAttributesMetadataQty, + $customAttributesMetadata1Qty, + "Invalid number of attributes returned." + ); // Verify the consistency of getCustomAttributesMetadata() function from the 2nd service - $customAttributesMetadata2 = $this->serviceTwo->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata2, "Invalid number of attributes returned."); + $customAttributesMetadata2Qty = count($this->serviceTwo->getCustomAttributesMetadata()); + $this->assertEquals( + $customAttributesMetadataQty, + $customAttributesMetadata2Qty, + "Invalid number of attributes returned." + ); } public function testGetNestedOptionsCustomerAttributesMetadata() From cb15e6086ab62c76b02770ff2f15a3c9665b7eaa Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 10 Oct 2018 17:54:52 +0300 Subject: [PATCH 0469/1415] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Option/Type/File/ExistingValidate.php | 50 ++++ .../Option/Type/File/ValidateFactory.php | 2 +- .../Option/Type/File/ValidatorFile.php | 18 +- .../Option/Type/File/ValidatorInfo.php | 5 +- app/code/Magento/Sales/Model/Download.php | 3 +- .../Sales/Test/Unit/Model/DownloadTest.php | 262 ------------------ .../Controller/Index/DownloadCustomOption.php | 3 +- .../Index/DownloadCustomOptionTest.php | 154 ---------- .../Option/Type/File/ValidatorFileTest.php | 17 +- 9 files changed, 86 insertions(+), 428 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php delete mode 100644 app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php new file mode 100644 index 0000000000000..8d4aea135eabb --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\Product\Option\Type\File; + +/** + * Validator for existing (already saved) files. + */ +class ExistingValidate extends \Zend_Validate +{ + /** + * @inheritDoc + * + * @param string $value File's full path. + * @param string|null $originalName Original file's name (when uploaded). + */ + public function isValid($value, string $originalName = null) + { + $this->_messages = []; + $this->_errors = []; + + if (!is_string($value)) { + $this->_messages[] = __('Full file path is expected.')->render(); + return false; + } + + $result = true; + $fileInfo = null; + if ($originalName) { + $fileInfo = ['name' => $originalName]; + } + foreach ($this->_validators as $element) { + $validator = $element['instance']; + if ($validator->isValid($value, $fileInfo)) { + continue; + } + $result = false; + $messages = $validator->getMessages(); + $this->_messages = array_merge($this->_messages, $messages); + $this->_errors = array_merge($this->_errors, array_keys($messages)); + if ($element['breakChainOnFailure']) { + break; + } + } + return $result; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php index 32c901afe8e74..c0d10c720f6f6 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php @@ -13,6 +13,6 @@ class ValidateFactory */ public function create() { - return new \Zend_Validate(); + return new ExistingValidate(); } } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php index d6a5cb1cbc29d..7449c9ea78883 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php @@ -10,6 +10,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Catalog\Model\Product\Exception as ProductException; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Math\Random; +use Magento\Framework\App\ObjectManager; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -62,12 +64,18 @@ class ValidatorFile extends Validator */ protected $isImageValidator; + /** + * @var Random + */ + private $random; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize * @param \Magento\Framework\HTTP\Adapter\FileTransferFactory $httpFactory * @param \Magento\Framework\Validator\File\IsImage $isImageValidator + * @param Random|null $random * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -75,12 +83,15 @@ public function __construct( \Magento\Framework\Filesystem $filesystem, \Magento\Framework\File\Size $fileSize, \Magento\Framework\HTTP\Adapter\FileTransferFactory $httpFactory, - \Magento\Framework\Validator\File\IsImage $isImageValidator + \Magento\Framework\Validator\File\IsImage $isImageValidator, + Random $random = null ) { $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->filesystem = $filesystem; $this->httpFactory = $httpFactory; $this->isImageValidator = $isImageValidator; + $this->random = $random + ?? ObjectManager::getInstance()->get(Random::class); parent::__construct($scopeConfig, $filesystem, $fileSize); } @@ -154,8 +165,6 @@ public function validate($processingParams, $option) $userValue = []; if ($upload->isUploaded($file) && $upload->isValid($file)) { - $extension = pathinfo(strtolower($fileInfo['name']), PATHINFO_EXTENSION); - $fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($fileInfo['name']); $dispersion = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); @@ -163,7 +172,8 @@ public function validate($processingParams, $option) $tmpDirectory = $this->filesystem->getDirectoryRead(DirectoryList::SYS_TMP); $fileHash = md5($tmpDirectory->readFile($tmpDirectory->getRelativePath($fileInfo['tmp_name']))); - $filePath .= '/' . $fileHash . '.' . $extension; + $fileRandomName = $this->random->getRandomString(32); + $filePath .= '/' .$fileRandomName; $fileFullPath = $this->mediaDirectory->getAbsolutePath($this->quotePath . $filePath); $upload->addFilter(new \Zend_Filter_File_Rename(['target' => $fileFullPath, 'overwrite' => true])); diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php index 37e4c7b310a81..31e89d424e3b2 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php @@ -6,6 +6,9 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +/** + * Validator for existing files. + */ class ValidatorInfo extends Validator { /** @@ -90,7 +93,7 @@ public function validate($optionValue, $option) } $result = false; - if ($validatorChain->isValid($this->fileFullPath)) { + if ($validatorChain->isValid($this->fileFullPath, $optionValue['title'])) { $result = $this->rootDirectory->isReadable($this->fileRelativePath) && isset($optionValue['secret_key']) && $this->buildSecretKey($this->fileRelativePath) == $optionValue['secret_key']; diff --git a/app/code/Magento/Sales/Model/Download.php b/app/code/Magento/Sales/Model/Download.php index 6d3ad8491253a..14395bb9afedd 100644 --- a/app/code/Magento/Sales/Model/Download.php +++ b/app/code/Magento/Sales/Model/Download.php @@ -78,7 +78,8 @@ public function downloadFile($info) $this->_fileFactory->create( $info['title'], ['value' => $this->_rootDir->getRelativePath($relativePath), 'type' => 'filename'], - $this->rootDirBasePath + $this->rootDirBasePath, + $info['type'] ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php b/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php deleted file mode 100644 index dd430f8a03304..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php +++ /dev/null @@ -1,262 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Sales\Test\Unit\Model; - -use Magento\Framework\App\Filesystem\DirectoryList; - -class DownloadTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Sales\Model\Download - */ - protected $model; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $filesystemMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storageMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storageFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $httpFileFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $writeDirectoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $driverMock; - - protected function setUp() - { - $this->writeDirectoryMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\Write::class) - ->disableOriginalConstructor() - ->getMock(); - $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) - ->disableOriginalConstructor() - ->getMock(); - $this->filesystemMock->expects($this->any()) - ->method('getDirectoryWrite') - ->with(DirectoryList::MEDIA) - ->will($this->returnValue($this->writeDirectoryMock)); - - $this->driverMock = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\DriverInterface::class); - $this->storageMock = $this->getMockBuilder(\Magento\MediaStorage\Helper\File\Storage\Database::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storageFactoryMock = $this->getMockBuilder( - \Magento\MediaStorage\Model\File\Storage\DatabaseFactory::class - )->disableOriginalConstructor() - ->setMethods(['create', 'checkDbUsage']) - ->getMock(); - $this->httpFileFactoryMock = $this->getMockBuilder(\Magento\Framework\App\Response\Http\FileFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->model = new \Magento\Sales\Model\Download( - $this->filesystemMock, - $this->storageMock, - $this->storageFactoryMock, - $this->httpFileFactoryMock - ); - } - - public function testInstanceOf() - { - $model = new \Magento\Sales\Model\Download( - $this->filesystemMock, - $this->storageMock, - $this->storageFactoryMock, - $this->httpFileFactoryMock - ); - $this->assertInstanceOf(\Magento\Sales\Model\Download::class, $model); - } - - /** - * @param $realPatchCheck - * @param $isFile - * @param $isReadable - * @expectedException \Magento\Framework\Exception\LocalizedException - * @dataProvider dataProviderForTestDownloadFileException - */ - public function testDownloadFileException($realPatchCheck, $isFile, $isReadable) - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn($realPatchCheck); - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - - $this->storageFactoryMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(false)); - $this->httpFileFactoryMock->expects($this->never())->method('create'); - - $this->model->downloadFile($info); - } - - /** - * @return array - */ - public function dataProviderForTestDownloadFileException() - { - return [ - [1, true, false], - [1, false, true], - [false, true, true], - ]; - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testDownloadFileNoStorage() - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - $isFile = true; - $isReadable = false; - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); - - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - - $this->storageMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(true)); - - $storageDatabaseMock = $this->getMockBuilder(\Magento\MediaStorage\Model\File\Storage\Database::class) - ->disableOriginalConstructor() - ->getMock(); - $storageDatabaseMock->expects($this->at(0)) - ->method('loadByFilename') - ->with($this->equalTo($info['order_path'])) - ->will($this->returnSelf()); - $storageDatabaseMock->expects($this->at(2)) - ->method('loadByFilename') - ->with($this->equalTo($info['quote_path'])) - ->will($this->returnSelf()); - - $storageDatabaseMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue(false)); - - $this->storageFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($storageDatabaseMock)); - $this->httpFileFactoryMock->expects($this->never())->method('create'); - - $this->model->downloadFile($info); - } - - public function testDownloadFile() - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - $isFile = true; - $isReadable = false; - - $writeMock = $this->getMockBuilder(\Magento\Framework\Filesystem\File\Write::class) - ->disableOriginalConstructor() - ->getMock(); - $writeMock->expects($this->any()) - ->method('lock'); - $writeMock->expects($this->any()) - ->method('write'); - $writeMock->expects($this->any()) - ->method('unlock'); - $writeMock->expects($this->any()) - ->method('close'); - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); - - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - $this->writeDirectoryMock->expects($this->any()) - ->method('openFile') - ->will($this->returnValue($writeMock)); - $this->writeDirectoryMock->expects($this->once()) - ->method('getRelativePath') - ->with($info['order_path']) - ->will($this->returnArgument(0)); - - $this->storageMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(true)); - - $storageDatabaseMock = $this->getMockBuilder(\Magento\MediaStorage\Model\File\Storage\Database::class) - ->disableOriginalConstructor() - ->setMethods(['loadByFilename', 'getId', '__wakeup']) - ->getMock(); - $storageDatabaseMock->expects($this->any()) - ->method('loadByFilename') - ->will($this->returnSelf()); - - $storageDatabaseMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue(true)); - - $this->storageFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($storageDatabaseMock)); - - $this->httpFileFactoryMock->expects($this->once()) - ->method('create') - ->with( - $info['title'], - ['value' => $info['order_path'], 'type' => 'filename'], - DirectoryList::MEDIA, - 'application/octet-stream', - null - ); - - $result = $this->model->downloadFile($info); - $this->assertNull($result); - } -} diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index e43a03e72d87c..095e64ddf7620 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -92,7 +92,8 @@ public function execute() $this->_fileResponseFactory->create( $info['title'], ['value' => $info['quote_path'], 'type' => 'filename'], - DirectoryList::ROOT + DirectoryList::ROOT, + $info['type'] ); } } catch (\Exception $e) { diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php deleted file mode 100644 index 6fefe18cf8975..0000000000000 --- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php +++ /dev/null @@ -1,154 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Wishlist\Test\Unit\Controller\Index; - -class DownloadCustomOptionTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Wishlist\Controller\Index\DownloadCustomOption - */ - protected $model; - - /** - * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Framework\App\Response\Http\FileFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fileResponseFactoryMock; - - /** - * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - - /** - * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectManagerMock; - - /** - * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $resultFactoryMock; - - /** - * @var \Magento\Framework\Serialize\Serializer\Json|\PHPUnit_Framework_MockObject_MockObject - */ - protected $jsonMock; - - protected function setUp() - { - $this->fileResponseFactoryMock = $this->getMockBuilder(\Magento\Framework\App\Response\Http\FileFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->jsonMock = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->setMethods(['create', 'get', 'configure']) - ->getMock(); - - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->contextMock = $this->getMockBuilder(\Magento\Framework\App\Action\Context::class) - ->disableOriginalConstructor() - ->getMock(); - $this->contextMock->expects($this->any()) - ->method('getObjectManager') - ->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->any()) - ->method('getRequest') - ->willReturn($this->requestMock); - $this->contextMock->expects($this->any()) - ->method('getResultFactory') - ->willReturn($this->resultFactoryMock); - - $this->model = new \Magento\Wishlist\Controller\Index\DownloadCustomOption( - $this->contextMock, - $this->fileResponseFactoryMock, - $this->jsonMock - ); - } - - public function testExecute() - { - $data = [ - 'number' => 42, - 'string' => 'string_value', - 'boolean' => true, - 'collection' => [1, 2, 3], - 'secret_key' => 999 - ]; - $serialized_data = json_encode($data); - - $optionMock = $this->getMockBuilder(\Magento\Wishlist\Model\Item\Option::class) - ->disableOriginalConstructor() - ->setMethods(['getProductId', 'load', 'getId', 'getValue']) - ->getMock(); - $optionMock->expects($this->any()) - ->method('load') - ->willReturnSelf(); - $optionMock->expects($this->any()) - ->method('getId') - ->willReturn(true); - $optionMock->expects($this->any()) - ->method('getProductId') - ->willReturn('some_value'); - $optionMock->expects($this->any()) - ->method('getValue') - ->willReturn($serialized_data); - - $productOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Option::class) - ->disableOriginalConstructor() - ->setMethods(['getProductId', 'load', 'getId', 'getType']) - ->getMock(); - $productOptionMock->expects($this->any()) - ->method('load') - ->willReturnSelf(); - $productOptionMock->expects($this->any()) - ->method('getId') - ->willReturn(true); - $productOptionMock->expects($this->any()) - ->method('getProductId') - ->willReturn('some_value'); - $productOptionMock->expects($this->any()) - ->method('getType') - ->willReturn('file'); - - $this->objectManagerMock->expects($this->any()) - ->method('create') - ->willReturnMap( - [ - [\Magento\Wishlist\Model\Item\Option::class, [], $optionMock], - [\Magento\Catalog\Model\Product\Option::class, [], $productOptionMock] - ] - ); - - $this->requestMock->expects($this->any()) - ->method('getParam') - ->willReturn(1); - - $this->jsonMock->expects($this->once()) - ->method('unserialize') - ->willReturnCallback(function ($value) { - return json_decode($value, true); - }); - - $this->assertEquals(null, $this->model->execute()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php index e7a2d17586a93..37ef60208861d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php @@ -6,6 +6,8 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +use Magento\Framework\Math\Random; + /** * @magentoDataFixture Magento/Catalog/_files/validate_image.php * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -48,11 +50,18 @@ protected function setUp() $fileSize = $this->objectManager->create(\Magento\Framework\File\Size::class); $this->maxFileSize = $fileSize->getMaxFileSize(); $this->maxFileSizeInMb = $fileSize->getMaxFileSizeInMb(); + $random = $this->getMockBuilder(Random::class) + ->disableOriginalConstructor() + ->getMock(); + $random->expects($this->any()) + ->method('getRandomString') + ->willReturn('RandomString'); $this->model = $this->objectManager->create( - \Magento\Catalog\Model\Product\Option\Type\File\ValidatorFile::class, + ValidatorFile::class, [ - 'httpFactory' => $this->httpFactoryMock + 'httpFactory' => $this->httpFactoryMock, + 'random' => $random, ] ); } @@ -350,8 +359,8 @@ protected function expectedValidate() return [ 'type' => 'image/jpeg', 'title' => 'test.jpg', - 'quote_path' => 'custom_options/quote/t/e/a071b9ffc8fda6df1652c05a4c61bf8a.jpg', - 'order_path' => 'custom_options/order/t/e/a071b9ffc8fda6df1652c05a4c61bf8a.jpg', + 'quote_path' => 'custom_options/quote/t/e/RandomString', + 'order_path' => 'custom_options/order/t/e/RandomString', 'size' => '3046', 'width' => 136, 'height' => 131, From 4279e3e7dcb3192356e4e9a23edf15858f641864 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 10 Oct 2018 17:57:54 +0300 Subject: [PATCH 0470/1415] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Model/Product/Option/Type/File/ValidateFactory.php | 5 +++++ .../Model/Product/Option/Type/File/ValidatorFile.php | 10 ++++++++++ .../Model/Product/Option/Type/File/ValidatorInfo.php | 10 ++++++++++ app/code/Magento/Sales/Model/Download.php | 7 +++++++ .../Wishlist/Controller/Index/DownloadCustomOption.php | 5 +++++ 5 files changed, 37 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php index c0d10c720f6f6..a7add0ad87b89 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php @@ -6,9 +6,14 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +/** + * Class ValidateFactory. Creates Validator with type "ExistingValidate" + */ class ValidateFactory { /** + * Main factory method + * * @return \Zend_Validate */ public function create() diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php index 7449c9ea78883..fef4999a1174a 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php @@ -14,6 +14,8 @@ use Magento\Framework\App\ObjectManager; /** + * Validator class. Represents logic for validation file given from product option + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ValidatorFile extends Validator @@ -70,6 +72,8 @@ class ValidatorFile extends Validator private $random; /** + * Constructor method + * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize @@ -96,6 +100,8 @@ public function __construct( } /** + * Setter method for the product + * * @param Product $product * @return $this */ @@ -106,6 +112,8 @@ public function setProduct(Product $product) } /** + * Validation method + * * @param \Magento\Framework\DataObject $processingParams * @param \Magento\Catalog\Model\Product\Option $option * @return array @@ -253,6 +261,8 @@ protected function initFilesystem() } /** + * Validate contents length method + * * @return bool * @todo need correctly name */ diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php index 31e89d424e3b2..100ad37273cff 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php @@ -37,6 +37,8 @@ class ValidatorInfo extends Validator protected $fileRelativePath; /** + * Construct method + * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize @@ -56,6 +58,8 @@ public function __construct( } /** + * Setter method for property "useQuotePath" + * * @param mixed $useQuotePath * @return $this */ @@ -66,6 +70,8 @@ public function setUseQuotePath($useQuotePath) } /** + * Validate method for the option value depends on an option + * * @param array $optionValue * @param \Magento\Catalog\Model\Product\Option $option * @return bool @@ -112,6 +118,8 @@ public function validate($optionValue, $option) } /** + * Method for creation secret key for the given file + * * @param string $fileRelativePath * @return string */ @@ -121,6 +129,8 @@ protected function buildSecretKey($fileRelativePath) } /** + * Calculates path for the file + * * @param array $optionValue * @return void */ diff --git a/app/code/Magento/Sales/Model/Download.php b/app/code/Magento/Sales/Model/Download.php index 14395bb9afedd..a76b72bfa41dd 100644 --- a/app/code/Magento/Sales/Model/Download.php +++ b/app/code/Magento/Sales/Model/Download.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; +/** + * Class Download. Represents download logic for files + */ class Download { /** @@ -36,6 +39,8 @@ class Download protected $rootDirBasePath; /** + * Constructor method + * * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDatabase * @param \Magento\MediaStorage\Model\File\Storage\DatabaseFactory $storageDatabaseFactory @@ -84,6 +89,8 @@ public function downloadFile($info) } /** + * Method checks, if file can be returned depends on the given filepath + * * @param string $relativePath * @return bool */ diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index 095e64ddf7620..9ffec68780aa1 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -11,6 +11,9 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Serialize\Serializer\Json; +/** + * Class DownloadCustomOption. Represents request-flow logic for option's file download + */ class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex { /** @@ -26,6 +29,8 @@ class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex private $json; /** + * Constructor method + * * @param Action\Context $context * @param \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory * @param Json|null $json From 83426d778a09b995a3ee1d41b6505abfd0ab94d3 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 10 Oct 2018 10:44:23 -0500 Subject: [PATCH 0471/1415] MAGETWO-91057: MFTF Test failure - Add products to wishlist from different stores - add testCaseId --- .../Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml index f8a1707e6c23a..b91f796e6a18f 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml @@ -15,6 +15,7 @@ <description value="All products added to wishlist should be visible on any store. Even if product visibility was set to 'Not Visible Individually' for this store"/> <group value="wishlist"/> <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-95678"/> </annotations> <before> <createData entity="customStoreGroup" stepKey="storeGroup"/> From d2e66ba244ce394c8eaa2abd2992a9d1d8ded558 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 10 Oct 2018 12:19:58 -0500 Subject: [PATCH 0472/1415] MAGETWO-95588: Swatches on category page does not work - Added configuration for listing pages - Added tests --- .../AdminCreateProductAttributeSection.xml | 1 + .../Mftf/Test/AdminCreateImageSwatchTest.xml | 28 +++++++++++++++++++ .../templates/product/listing/renderer.phtml | 3 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index 17778c76da9b9..b3ecf5bcedba9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -72,5 +72,6 @@ <element name="Scope" type="select" selector="#is_global"/> <element name="AddToColumnOptions" type="select" selector="#is_used_in_grid"/> <element name="UseInFilterOptions" type="select" selector="#is_filterable_in_grid"/> + <element name="UseInProductListing" type="select" selector="#used_in_product_listing"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml index a763bda2e494f..dd497cca2c2de 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml @@ -19,6 +19,7 @@ <group value="Swatches"/> </annotations> <before> + <createData entity="ApiCategory" stepKey="createCategory"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> @@ -67,6 +68,11 @@ <click selector="{{AttributePropertiesSection.AdvancedProperties}}" stepKey="expandAdvancedProperties"/> <selectOption selector="{{AttributePropertiesSection.Scope}}" userInput="1" stepKey="selectGlobalScope"/> + <scrollToTopOfPage stepKey="scrollToTabs"/> + <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="clickStorefrontPropertiesTab"/> + <waitForElementVisible selector="{{AdvancedAttributePropertiesSection.UseInProductListing}}" stepKey="waitForTabSwitch"/> + <selectOption selector="{{AdvancedAttributePropertiesSection.UseInProductListing}}" userInput="Yes" stepKey="useInProductListing"/> + <!-- Save the new product attribute --> <click selector="{{AttributePropertiesSection.SaveAndEdit}}" stepKey="clickSaveAndEdit1"/> <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" stepKey="waitForSuccess"/> @@ -97,6 +103,7 @@ <actionGroup ref="fillMainProductForm" stepKey="fillProductForm"> <argument name="product" value="BaseConfigurableProduct"/> </actionGroup> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createCategory.name$$]" stepKey="fillCategory"/> <!-- Create configurations based off the Image Swatch we created earlier --> <click selector="{{AdminProductFormConfigurationsSection.createConfigurations}}" stepKey="clickCreateConfigurations"/> @@ -134,5 +141,26 @@ <expectedResult type="string">adobe-base</expectedResult> <actualResult type="string">{$grabSwatch6}</actualResult> </assertContains> + + <!-- Go to the product listing page and see text swatch options --> + <amOnPage url="$$createCategory.name$$.html" stepKey="goToCategoryPageStorefront"/> + <waitForPageLoad stepKey="waitForProductListingPage"/> + + <!-- Verify the storefront --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('1')}}" userInput="style" stepKey="grabSwatch7"/> + <assertContains stepKey="assertSwatch7"> + <expectedResult type="string">adobe-thumb</expectedResult> + <actualResult type="string">{$grabSwatch7}</actualResult> + </assertContains> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('2')}}" userInput="style" stepKey="grabSwatch8"/> + <assertContains stepKey="assertSwatch8"> + <expectedResult type="string">adobe-small</expectedResult> + <actualResult type="string">{$grabSwatch8}</actualResult> + </assertContains> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('3')}}" userInput="style" stepKey="grabSwatch9"/> + <assertContains stepKey="assertSwatch9"> + <expectedResult type="string">adobe-base</expectedResult> + <actualResult type="string">{$grabSwatch9}</actualResult> + </assertContains> </test> </tests> diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml index e65345b38d9b2..410d4046ae17f 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml @@ -21,7 +21,8 @@ $productId = $block->getProduct()->getId(); "numberToShow": <?= /* @escapeNotVerified */ $block->getNumberSwatchesPerProduct(); ?>, "jsonConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig(); ?>, "jsonSwatchConfig": <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig(); ?>, - "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>" + "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>", + "jsonSwatchImageSizeConfig": <?php /* @noEscape */ echo $block->getJsonSwatchSizeConfig() ?> } } } From 43b3cae9c610984b29c976394ca0ab292d61d0a6 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 10 Oct 2018 13:47:31 -0500 Subject: [PATCH 0473/1415] MAGETWO-95588: Swatches on category page does not work - Fixed static issue --- .../view/frontend/templates/product/listing/renderer.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml index 410d4046ae17f..c30c96fc890f7 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml @@ -22,7 +22,7 @@ $productId = $block->getProduct()->getId(); "jsonConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig(); ?>, "jsonSwatchConfig": <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig(); ?>, "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>", - "jsonSwatchImageSizeConfig": <?php /* @noEscape */ echo $block->getJsonSwatchSizeConfig() ?> + "jsonSwatchImageSizeConfig": <?= /* @noEscape */ $block->getJsonSwatchSizeConfig() ?> } } } From 4c9166f6bbce8949e8ce57b56b2a232134fe3c64 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 10 Oct 2018 14:52:44 -0500 Subject: [PATCH 0474/1415] MC-4323: Cannot Add Slider WYSIWYG Image From Gallery or Link to Image in Gallery After Page Has Been Saved - Fixed editor callback to use the global editor --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js index 760e0785a7893..bd47391e2ed2e 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js @@ -117,7 +117,7 @@ define([ jQuery.when.apply(jQuery, deferreds).done(function () { tinyMCE4.init(settings); this.getPluginButtons().hide(); - this.eventBus.attachEventHandler('open_browser_callback', this.openFileBrowser); + this.eventBus.attachEventHandler('open_browser_callback', tinyMceEditors.get(self.id).openFileBrowser); }.bind(this)); }, From 8cbe1263925df0ac91091f3921f349dcf27efa3c Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 10 Oct 2018 16:48:53 -0500 Subject: [PATCH 0475/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 22 +++++++ .../Test/StorefrontCustomerCheckoutTest.xml | 65 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index eef35abcc978a..41b1e0d811851 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -104,6 +104,28 @@ <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> </actionGroup> + <!-- Logged in user checkout filling shipping section --> + <actionGroup name="LoggedInUserCheckoutAddNewShippingSectionWithoutRegionActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <selectOption selector="{{CheckoutShippingSection.country}}" userInput="{{customerAddressVar.country_id}}" stepKey="enterCountry"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="clickSaveAddress"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + </actionGroup> + <!-- Check product in checkout cart items --> <actionGroup name="CheckProductInCheckoutCartItemsActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index 6ea8d8a167294..2034c99fb4ae9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -193,4 +193,69 @@ <waitForPageLoad stepKey="waitForOrderSuccessPage2"/> <see stepKey="seeSuccessMessage2" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> </test> + <test name="StorefrontCustomerCheckoutTestWithRestrictedCountriesForPayment"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout flow if payment solutions are not available"/> + <title value="Checkout via Customer Checkout with restricted countries for payment"/> + <description value="Should be able to place an order as a Customer with restricted countries for payment."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-42653"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 1" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry GB" /> + <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry ''" /> + </after> + <!-- Login as Customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin"> + <argument name="Customer" value="$$simpleuscustomer$$" /> + </actionGroup> + + <!-- Add product to cart --> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <see selector="{{StorefrontMinicartSection.quantity}}" userInput="1" stepKey="seeCartQuantity"/> + + <!-- Go to checkout page --> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="customerGoToCheckoutFromMinicart" /> + + <!-- Select address --> + <click stepKey="selectAddress" selector="{{CheckoutShippingMethodsSection.firstShippingMethod}}"/> + <waitForElement stepKey="waitNextButton" selector="{{CheckoutShippingMethodsSection.next}}" time="30"/> + <click stepKey="clickNextButton" selector="{{CheckoutShippingMethodsSection.next}}" /> + <waitForPageLoad stepKey="waitBillingForm"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.noQuotes}}" stepKey="waitMessage"/> + <see userInput="No Payment method available." stepKey="checkMessage"/> + + <!-- Fill UK Address and verify that payment available and checkout successful --> + <click selector="{{CheckoutHeaderSection.shippingMethodStep}}" stepKey="goToShipping" /> + <click selector="{{CheckoutShippingSection.newAddressButton}}" stepKey="fillNewAddress" /> + <actionGroup ref="LoggedInUserCheckoutAddNewShippingSectionWithoutRegionActionGroup" stepKey="customerCheckoutFillingShippingSectionUK"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="UK_Not_Default_Address" /> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="customerSelectCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="customerPlaceorder"> + <argument name="orderNumberMessage" value="CONST.successCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + </test> </tests> From 913f88a8a35e2f76339cef8648fdd5e2a7c826f9 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Wed, 10 Oct 2018 17:09:01 -0500 Subject: [PATCH 0476/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel - added functional test to cover the bug fix --- .../AdminCustomerMainActionsSection.xml | 1 + .../Test/AdminResetCustomerPasswordTest.xml | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml index 37ea99d652fb9..3ff880c64e6d6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerMainActionsSection"> <element name="saveButton" type="button" selector="#save" timeout="30"/> + <element name="resetPassword" type="button" selector="#resetPassword" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml new file mode 100644 index 0000000000000..cff605d7c907f --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminResetCustomerPasswordTest"> + <annotations> + <features value="Customer"/> + <stories value="Admin should be able to reset an existing customer's password"/> + <description value="Admin should be able to reset customer password"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-30875"/> + <group value="customer"/> + </annotations> + <before> + <createData entity="Simple_US_Customer" stepKey="customer"/> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + <after> + <deleteData createDataKey="customer" stepKey="deleteCustomer"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + <!--Edit customer info--> + <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> + <argument name="customer" value="$$customer$$"/> + </actionGroup> + <click selector="{{AdminCustomerMainActionsSection.resetPassword}}" stepKey="resetPassword"/> + <see userInput="The customer will receive an email with a link to reset password." stepKey="messageThatLinkToPasswordResetIsSent"/> + </test> +</tests> + + From 848a7c2c209d54bde25e664682b42e4a46e90bd3 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Wed, 10 Oct 2018 19:54:29 +0300 Subject: [PATCH 0477/1415] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index b83bb97301b9c..1ac7675b10289 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -32,6 +32,6 @@ public function __construct(array $blackList = []) */ public function execute(array $attributes): array { - return array_diff($attributes, $this->blackList); + return array_diff_key($attributes, array_flip($this->blackList)); } } From 41cb4685fc24b296de837ddf8c39ab377e7347a9 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Thu, 11 Oct 2018 10:24:11 +0300 Subject: [PATCH 0478/1415] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Add GET interface --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index 9f0dcc6d9c18f..b49635a951e39 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -8,8 +8,9 @@ use Magento\Checkout\Model\Cart\RequestQuantityProcessor; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; -class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface +class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpGetActionInterface, HttpPostActionInterface { /** * @var RequestQuantityProcessor From e210b7044a7bfd503082249a72a95a6c0ae03eb5 Mon Sep 17 00:00:00 2001 From: Joseph Maxwell <joseph@swiftotter.com> Date: Wed, 6 Jun 2018 10:40:48 -0500 Subject: [PATCH 0479/1415] Bundle checkboxes now are checked when item edited from cart --- .../Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php index 5d326e7c01d19..ed6a4d1ad7209 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php @@ -167,7 +167,9 @@ protected function _getSelectedOptions() */ protected function assignSelection(\Magento\Bundle\Model\Option $option, $selectionId) { - if ($selectionId && $option->getSelectionById($selectionId)) { + if (is_array($selectionId)) { + $this->_selectedOptions = $selectionId; + } else if ($selectionId && $option->getSelectionById($selectionId)) { $this->_selectedOptions = $selectionId; } elseif (!$option->getRequired()) { $this->_selectedOptions = 'None'; From 53f59424c0b049e2f275c50bbced1fc9b42a6916 Mon Sep 17 00:00:00 2001 From: Joseph Maxwell <joseph@swiftotter.com> Date: Wed, 6 Jun 2018 10:44:38 -0500 Subject: [PATCH 0480/1415] #4942: bundled products now retain customer selections when editing from cart --- .../Block/Catalog/Product/View/Type/Bundle.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index 62a2fa1c47e1e..cab923da49215 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -193,6 +193,18 @@ public function getJsonConfig() $options[$optionId]['selections'][$configValue]['qty'] = $configQty; } } + + + $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; + $selections = $options[$optionId]['selections']; + array_walk($selections, function(&$selection, $selectionId) use ($preConfiguredQtys) { + if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { + $selection['qty'] = $preConfiguredQtys[$selectionId]; + } else if ((int)$preConfiguredQtys > 0) { + $selection['qty'] = $preConfiguredQtys; + } + }); + $options[$optionId]['selections'] = $selections; } $position++; } From 8050d5014037c9ae845be1fd1338b4f4ce7b8d19 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Tue, 18 Sep 2018 09:05:00 +0000 Subject: [PATCH 0481/1415] magento/magento2#4942: fix code styles in the app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php file --- .../Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index cab923da49215..1cd0c41abb528 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -194,10 +194,9 @@ public function getJsonConfig() } } - $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; $selections = $options[$optionId]['selections']; - array_walk($selections, function(&$selection, $selectionId) use ($preConfiguredQtys) { + array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { $selection['qty'] = $preConfiguredQtys[$selectionId]; } else if ((int)$preConfiguredQtys > 0) { From 1e41ee9f806816d850882e4db2f0b93067ae2592 Mon Sep 17 00:00:00 2001 From: BezV8 <berwyn@v8media.co.uk> Date: Thu, 11 Oct 2018 09:12:58 +0100 Subject: [PATCH 0482/1415] Fix typo on product details causing Validation error. Fixes a typo on the aria-labeleledby attribute on the product page causing a W3C Validation error. --- .../Catalog/view/frontend/templates/product/view/details.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml index b1af46b80552d..038bea86e7d4e 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml @@ -21,7 +21,7 @@ $label = $block->getChildData($alias, 'title'); ?> <div class="data item title" - aria-labeledby="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title" + aria-labelledby="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title" data-role="collapsible" id="tab-label-<?= /* @escapeNotVerified */ $alias ?>"> <a class="data switch" tabindex="-1" From cf3f078e0062504d8837c3013afd0bdbb37ce17e Mon Sep 17 00:00:00 2001 From: David WATTIER <david.wattier@smile.fr> Date: Thu, 16 Mar 2017 19:28:06 +0100 Subject: [PATCH 0483/1415] #8815 * send multiple small purge request instead of one big request to avoid reaching the varnish http_req_hdr_len threshold. --- .../Observer/InvalidateVarnishObserver.php | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php index 3527d4f6cdf4e..acfd321ea0950 100644 --- a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php +++ b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php @@ -21,6 +21,18 @@ class InvalidateVarnishObserver implements ObserverInterface */ protected $purgeCache; + /** + * Batch size of the purge request. + * + * Based on default Varnish 4 http_req_hdr_len size minus a 512 bytes margin for method, + * header name, line feeds etc. + * + * @see http://www.varnish-cache.org/docs/4.0/reference/varnishd.html#http-req-hdr-len + * + * @var int + */ + private $requestSize = 7680; + /** * Invalidation tags resolver * @@ -44,6 +56,8 @@ public function __construct( * If Varnish caching is enabled it collects array of tags * of incoming object and asks to clean cache. * + * For scaling reason the purge request is chopped down to fix batch size. + * * @param \Magento\Framework\Event\Observer $observer * @return void */ @@ -56,10 +70,21 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled()) { $bareTags = $this->getTagResolver()->getTags($object); + $tagsBatchSize = 0; $tags = []; - $pattern = "((^|,)%s(,|$))"; + $pattern = '((^|,)%s(,|$))'; foreach ($bareTags as $tag) { - $tags[] = sprintf($pattern, $tag); + $formattedTag = sprintf($pattern, $tag); + + // Send request if batch size is reached and add the implode with pipe to the computation + if ($tagsBatchSize + strlen($formattedTag) > $this->requestSize - count($tags) - 1) { + $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags))); + $tags = []; + $tagsBatchSize = 0; + } + + $tagsBatchSize += strlen($formattedTag); + $tags[] = $formattedTag; } if (!empty($tags)) { $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags))); From 0bd75c823e506e8099cfa4dbb5877be5662bcebb Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 4 Oct 2018 16:16:01 +0300 Subject: [PATCH 0484/1415] =?UTF-8?q?NGCOM-2997:=20#4942=20and=20bundle=20?= =?UTF-8?q?checkbox=20bug=20#15905.=20Fix=20functional=20and=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Catalog/Product/View/Type/Bundle.php | 43 +++++++++++++------ .../Test/StorefrontEditBundleProductTest.xml | 5 +-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index 1cd0c41abb528..fa488b073f515 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -7,6 +7,7 @@ use Magento\Bundle\Model\Option; use Magento\Catalog\Model\Product; +use Magento\Framework\DataObject; /** * Catalog bundle product info block @@ -170,7 +171,7 @@ public function getJsonConfig() $defaultValues = []; $preConfiguredFlag = $currentProduct->hasPreconfiguredValues(); - /** @var \Magento\Framework\DataObject|null $preConfiguredValues */ + /** @var DataObject|null $preConfiguredValues */ $preConfiguredValues = $preConfiguredFlag ? $currentProduct->getPreconfiguredValues() : null; $position = 0; @@ -193,23 +194,13 @@ public function getJsonConfig() $options[$optionId]['selections'][$configValue]['qty'] = $configQty; } } - - $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; - $selections = $options[$optionId]['selections']; - array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { - if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { - $selection['qty'] = $preConfiguredQtys[$selectionId]; - } else if ((int)$preConfiguredQtys > 0) { - $selection['qty'] = $preConfiguredQtys; - } - }); - $options[$optionId]['selections'] = $selections; + $options = $this->processOptions($optionId, $options, $preConfiguredValues); } $position++; } $config = $this->getConfigData($currentProduct, $options); - $configObj = new \Magento\Framework\DataObject( + $configObj = new DataObject( [ 'config' => $config, ] @@ -414,4 +405,30 @@ private function getConfigData(Product $product, array $options) ]; return $config; } + + /** + * Set preconfigured quantities and selections to options. + * + * @param string $optionId + * @param array $options + * @param DataObject $preConfiguredValues + * @return array + */ + private function processOptions(string $optionId, array $options, DataObject $preConfiguredValues) + { + $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; + $selections = $options[$optionId]['selections']; + array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { + if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { + $selection['qty'] = $preConfiguredQtys[$selectionId]; + } else { + if ((int)$preConfiguredQtys > 0) { + $selection['qty'] = $preConfiguredQtys; + } + } + }); + $options[$optionId]['selections'] = $selections; + + return $options; + } } diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml index f94cd83f4e7d7..4945308c26c4a 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml @@ -94,9 +94,8 @@ <click stepKey="clickEdit" selector="{{CheckoutCartProductSection.nthEditButton('1')}}"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <!-- Choose both of the options on the storefront --> - <click stepKey="selectFirstBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> - <click stepKey="selectSecondBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}"/> + <!-- Check second one option to choose both of the options on the storefront --> + <click selector="{{StorefrontBundledSection.bundleOption('1','2')}}" stepKey="selectSecondBundleOption2"/> <waitForPageLoad stepKey="waitForPriceUpdate3"/> <see stepKey="seeDoublePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="2,460.00"/> From bf5faf8976eea218003b7f62a090e29424b398ca Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Thu, 11 Oct 2018 11:39:02 +0300 Subject: [PATCH 0485/1415] MAGETWO-95491: Product Review "Save and Next" and "Save and Previous" not working --- .../Review/Product/Collection.php | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 145d9e48a8a7b..af4fa9dd3e68d 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Review\Model\ResourceModel\Review\Product; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; @@ -116,7 +117,8 @@ public function __construct( \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, ProductLimitationFactory $productLimitationFactory = null, MetadataPool $metadataPool = null - ) { + ) + { $this->_ratingFactory = $ratingFactory; $this->_voteFactory = $voteFactory; parent::__construct( @@ -403,11 +405,20 @@ public function getAllIds($limit = null, $offset = null) public function getResultingIds() { $idsSelect = clone $this->getSelect(); - $idsSelect->reset(Select::LIMIT_COUNT); - $idsSelect->reset(Select::LIMIT_OFFSET); + $data = $this->getConnection() + ->fetchAll( + $idsSelect + ->reset(Select::LIMIT_COUNT) + ->reset(Select::LIMIT_OFFSET) + ->columns('rt.review_id') + ); - $idsSelect->columns('rt.review_id'); - return $this->getConnection()->fetchCol($idsSelect); + return array_map( + function ($value) { + return $value['review_id']; + }, + $data + ); } /** From 38b91b77bef7604d747780a3cad2d342d05453d3 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 11 Oct 2018 11:52:56 +0300 Subject: [PATCH 0486/1415] ENGCOM-1928: 14294 - Fixes 'back' functionality after switching a store view. #15961. Fix functional tests. --- app/code/Magento/Store/Block/Switcher.php | 20 +++++++++++++++++++ .../frontend/templates/switch/languages.phtml | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php index f15349f11066d..e162a2a0abe16 100644 --- a/app/code/Magento/Store/Block/Switcher.php +++ b/app/code/Magento/Store/Block/Switcher.php @@ -265,4 +265,24 @@ public function getTargetStorePostData(Store $store, $data = []) $data ); } + + /** + * Returns target store redirect url. + * + * @param Store $store + * @return string + */ + public function getTargetStoreRedirectUrl(Store $store) + { + return $this->getUrl( + 'stores/store/redirect', + [ + '___store' => $store->getCode(), + '___from_store' => $this->getCurrentStoreCode(), + ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl( + $store->getCurrentUrl(false) + ), + ] + ); + } } diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 6d041a9e22c5d..411a1ef3c9a32 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?= $block->escapeHtml($_lang->getCode()) ?> switcher-option"> - <a href="<?= $block->escapeUrl($_lang->getCurrentUrl(true)) ?>"> + <a href="<?= $block->escapeUrl($block->getTargetStoreRedirectUrl($_lang)) ?>"> <?= $block->escapeHtml($_lang->getName()) ?> </a> </li> From d42951b0a5a05d5b574aead2df7efd05650904b8 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 11 Oct 2018 12:48:00 +0300 Subject: [PATCH 0487/1415] Make constructor backward compatible --- app/code/Magento/Catalog/Model/ImageUploader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index b2f968553887c..b5ca0895d6d1a 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -93,7 +93,7 @@ public function __construct( $baseTmpPath, $basePath, $allowedExtensions, - $allowedMimeTypes + $allowedMimeTypes = [] ) { $this->coreFileStorageDatabase = $coreFileStorageDatabase; $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); From 097a11ac4f82368af44b8ee85ef0e0338504412c Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Thu, 11 Oct 2018 12:56:33 +0300 Subject: [PATCH 0488/1415] MAGETWO-95491: Product Review "Save and Next" and "Save and Previous" not working --- .../Review/Model/ResourceModel/Review/Product/Collection.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index af4fa9dd3e68d..4e55484e5dd94 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -117,8 +117,7 @@ public function __construct( \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, ProductLimitationFactory $productLimitationFactory = null, MetadataPool $metadataPool = null - ) - { + ) { $this->_ratingFactory = $ratingFactory; $this->_voteFactory = $voteFactory; parent::__construct( From a0085a80984f0d0c26ef6d1bd93eae6bfa03731c Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Thu, 11 Oct 2018 13:58:35 +0400 Subject: [PATCH 0489/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Add automated test --- ...AdminProductFormGroupedProductsSection.xml | 4 + .../AdminSortingAssociatedProductsTest.xml | 207 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index 64dcd9566d890..0739c4e601b62 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,5 +11,9 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> + <element name="nextActionButton" type="button" selector="//button[@class='action-next']"/> + <element name="previousActionButton" type="button" selector="//button[@class='action-previous']"/> + <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> + <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml new file mode 100644 index 0000000000000..ad5fbbb30edeb --- /dev/null +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminSortingAssociatedProductsTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages"/> + <title value="Grouped Products: Sorting Associated Products Between Pages"/> + <description value="Make sure that products in grid were recalculated when sorting associated products between pages"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95085"/> + <group value="GroupedProduct"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <createData entity="_defaultCategory" stepKey="category"/> + <!-- Create 23 products so that grid can have more than one page --> + <createData entity="ApiSimpleProduct" stepKey="product1"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product2"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product3"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product4"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product5"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product6"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product7"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product8"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product9"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product10"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product11"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product12"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product13"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product14"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product15"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product16"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product17"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product18"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product19"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product20"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product21"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product22"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product23"> + <requiredEntity createDataKey="category"/> + </createData> + </before> + <after> + <!--Delete created grouped product--> + <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" + dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFilters"/> + <deleteData createDataKey="product1" stepKey="deleteProduct1"/> + <deleteData createDataKey="product2" stepKey="deleteProduct2"/> + <deleteData createDataKey="product3" stepKey="deleteProduct3"/> + <deleteData createDataKey="product4" stepKey="deleteProduct4"/> + <deleteData createDataKey="product5" stepKey="deleteProduct5"/> + <deleteData createDataKey="product6" stepKey="deleteProduct6"/> + <deleteData createDataKey="product7" stepKey="deleteProduct7"/> + <deleteData createDataKey="product8" stepKey="deleteProduct8"/> + <deleteData createDataKey="product9" stepKey="deleteProduct9"/> + <deleteData createDataKey="product10" stepKey="deleteProduct10"/> + <deleteData createDataKey="product11" stepKey="deleteProduct11"/> + <deleteData createDataKey="product12" stepKey="deleteProduct12"/> + <deleteData createDataKey="product13" stepKey="deleteProduct13"/> + <deleteData createDataKey="product14" stepKey="deleteProduct14"/> + <deleteData createDataKey="product15" stepKey="deleteProduct15"/> + <deleteData createDataKey="product16" stepKey="deleteProduct16"/> + <deleteData createDataKey="product17" stepKey="deleteProduct17"/> + <deleteData createDataKey="product18" stepKey="deleteProduct18"/> + <deleteData createDataKey="product19" stepKey="deleteProduct19"/> + <deleteData createDataKey="product20" stepKey="deleteProduct20"/> + <deleteData createDataKey="product21" stepKey="deleteProduct21"/> + <deleteData createDataKey="product22" stepKey="deleteProduct22"/> + <deleteData createDataKey="product23" stepKey="deleteProduct23"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Create grouped Product--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPage"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGridColumnsInitial"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateProduct"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + <actionGroup ref="fillGroupedProductForm" stepKey="fillProductForm"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + + <scrollTo selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" x="0" y="-100" stepKey="scrollToGroupedSection"/> + <conditionalClick selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" dependentSelector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" visible="false" stepKey="openGroupedProductsSection"/> + <click selector="body" stepKey="clickBodyToCorrectFocusGrouped"/> + <click selector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" stepKey="clickAddProductsToGroup"/> + <waitForElementVisible selector="{{AdminAddProductsToGroupPanel.filters}}" stepKey="waitForGroupedProductModal"/> + <actionGroup ref="filterProductGridBySku2" stepKey="filterGroupedProducts"> + <argument name="sku" value="api-simple-product"/> + </actionGroup> + + <!-- Select all, then start the bulk update attributes flow --> + <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> + <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> + + <click selector="{{AdminAddProductsToGroupPanel.addSelectedProducts}}" stepKey="clickAddSelectedGroupProducts"/> + <waitForPageLoad stepKey="waitForProductsAdded"/> + + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + + <!--Open created Product group--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetFiltersIfExist"/> + <actionGroup ref="searchProductGridByKeyword" stepKey="searchProductGridForm"> + <argument name="keyword" value="GroupedProduct.name"/> + </actionGroup> + <click selector="{{AdminProductGridSection.selectRowBasedOnName(GroupedProduct.name)}}" stepKey="openGroupedProduct"/> + <waitForPageLoad stepKey="waitForProductEditPageLoad"/> + + <scrollTo selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" x="0" y="-100" stepKey="scrollToGroupedSection2"/> + <conditionalClick selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" dependentSelector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" visible="false" stepKey="openGroupedProductsSection2"/> + + <!--Change position value for the Product Position 0--> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('1')}}" stepKey="grabNameProductPosition0"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPositionFirst"/> + <fillField selector="{{AdminProductFormGroupedProductsSection.positionProduct('1')}}" userInput="21" stepKey="fillFieldProductPosition0"/> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.nextActionButton}}" stepKey="clickButton"/> + <waitForAjaxLoad stepKey="waitForAjax1"/> + + <!--Go to next page and verify that Products in grid were recalculated--> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.nextActionButton}}" stepKey="clickNextActionButton"/> + <waitForAjaxLoad stepKey="waitForAjax2"/> + + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPosition21"/> + <assertEquals stepKey="assertProductsRecalculated"> + <actualResult type="string">$grabNameProductPosition0</actualResult> + <expectedResult type="string">$grabNameProductPosition21</expectedResult> + </assertEquals> + + <!--Change position value for the product to 1--> + <fillField selector="{{AdminProductFormGroupedProductsSection.positionProduct('2')}}" userInput="1" stepKey="fillFieldProductPosition1"/> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.previousActionButton}}" stepKey="clickButton2"/> + <waitForAjaxLoad stepKey="waitForAjax3"/> + + <!--Go to previous page and verify that Products in grid were recalculated--> + <click selector="{{AdminProductFormGroupedProductsSection.previousActionButton}}" stepKey="clickPreviousActionButton"/> + <waitForAjaxLoad stepKey="waitForAjax4"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPosition2"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('1')}}" stepKey="grabNameProductPositionZero"/> + <assertEquals stepKey="assertProductsRecalculated2"> + <actualResult type="string">$grabNameProductPosition2</actualResult> + <expectedResult type="string">$grabNameProductPosition0</expectedResult> + </assertEquals> + <assertEquals stepKey="assertProductsRecalculated3"> + <actualResult type="string">$grabNameProductPositionFirst</actualResult> + <expectedResult type="string">$grabNameProductPositionZero</expectedResult> + </assertEquals> + </test> +</tests> From d96db6d0cd9bdab0402ac44f024169197cd8cf86 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Thu, 11 Oct 2018 14:13:51 +0300 Subject: [PATCH 0490/1415] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index 1ac7675b10289..830b974e5edb2 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -27,6 +27,7 @@ public function __construct(array $blackList = []) /** * Delete custom attribute + * * @param array $attributes * @return array */ From c57ffe63ce5c9820dfaa6537511a539ded5dbfb7 Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Thu, 11 Oct 2018 13:38:29 +0200 Subject: [PATCH 0491/1415] Change expected Exception from \Magento\NewRelicReporting\Model\Exception to \Exception to fix docblock --- app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php index ec21e06976b8b..9882a1ce9b0b8 100644 --- a/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php +++ b/app/code/Magento/NewRelicReporting/Model/NewRelicWrapper.php @@ -31,7 +31,7 @@ public function addCustomParameter($param, $value) /** * Wrapper for 'newrelic_notice_error' function * - * @param Exception $exception + * @param \Exception $exception * @return void */ public function reportError($exception) From eec132864eff41b1938cb8bf8a9e82207e018025 Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Thu, 11 Oct 2018 13:40:38 +0200 Subject: [PATCH 0492/1415] Create empty modelData array to avoid undefined var error --- .../Magento/NewRelicReporting/Model/Cron/ReportModulesInfo.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/NewRelicReporting/Model/Cron/ReportModulesInfo.php b/app/code/Magento/NewRelicReporting/Model/Cron/ReportModulesInfo.php index 9cdc90bc46b2a..78c485c5bb6f5 100644 --- a/app/code/Magento/NewRelicReporting/Model/Cron/ReportModulesInfo.php +++ b/app/code/Magento/NewRelicReporting/Model/Cron/ReportModulesInfo.php @@ -64,6 +64,7 @@ public function report() $moduleData = $this->collect->getModuleData(); if (count($moduleData['changes']) > 0) { foreach ($moduleData['changes'] as $change) { + $modelData = []; switch ($change['type']) { case Config::ENABLED: $modelData = [ From c4a24eeecd3fe2f40d91be256c2d85cc0dd35ad3 Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Thu, 11 Oct 2018 13:50:39 +0200 Subject: [PATCH 0493/1415] Removed unused class import for Magento\Framework\App\State --- .../Developer/Console/Command/SourceThemeDeployCommand.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php b/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php index 25519e5c83054..a2db0f43061ea 100644 --- a/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php +++ b/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php @@ -5,7 +5,6 @@ */ namespace Magento\Developer\Console\Command; -use Magento\Framework\App\State; use Magento\Framework\Validator\Locale; use Magento\Framework\View\Asset\Repository; use Symfony\Component\Console\Command\Command; From f03ed7a2e6292f58cc5859422d660e85ec9d5cdb Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 11 Oct 2018 15:00:48 +0300 Subject: [PATCH 0494/1415] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Fix static test --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index b49635a951e39..bfc408d920ad3 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -10,6 +9,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\Action\HttpGetActionInterface; +/** + * Post update shopping cart. + */ class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpGetActionInterface, HttpPostActionInterface { /** From 677356e1014be1d6577c4ea041f9b535fb800c4e Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Thu, 11 Oct 2018 15:29:11 +0300 Subject: [PATCH 0495/1415] MAGETWO-95275: Varnish "Connection reset by peer" error when large catalog is reindexed on schedule --- .../CacheInvalidate/Model/PurgeCache.php | 68 +++++++++++++++++-- .../Observer/InvalidateVarnishObserver.php | 29 +------- 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php index 8acf170d43cfb..57e29d11495a2 100644 --- a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php +++ b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php @@ -26,6 +26,18 @@ class PurgeCache */ private $logger; + /** + * Batch size of the purge request. + * + * Based on default Varnish 4 http_req_hdr_len size minus a 512 bytes margin for method, + * header name, line feeds etc. + * + * @see https://varnish-cache.org/docs/4.1/reference/varnishd.html + * + * @var int + */ + private $requestSize = 7680; + /** * Constructor * @@ -52,10 +64,59 @@ public function __construct( */ public function sendPurgeRequest($tagsPattern) { + $successful = true; $socketAdapter = $this->socketAdapterFactory->create(); $servers = $this->cacheServer->getUris(); - $headers = [self::HEADER_X_MAGENTO_TAGS_PATTERN => $tagsPattern]; $socketAdapter->setOptions(['timeout' => 10]); + + $formattedTagsChunks = $this->splitTags($tagsPattern); + foreach ($formattedTagsChunks as $formattedTagsChunk) { + if (!$this->sendPurgeRequestToServers($socketAdapter, $servers, $formattedTagsChunk)) { + $successful = false; + } + } + + return $successful; + } + + /** + * Split tags by batches + * + * @param string $tagsPattern + * @return \Generator + */ + private function splitTags($tagsPattern) + { + $tagsBatchSize = 0; + $formattedTagsChunk = []; + $formattedTags = explode('|', $tagsPattern); + foreach ($formattedTags as $formattedTag) { + if ($tagsBatchSize + strlen($formattedTag) > $this->requestSize - count($formattedTagsChunk) - 1) { + yield implode('|', array_unique($formattedTagsChunk)); + $formattedTagsChunk = []; + $tagsBatchSize = 0; + } + + $tagsBatchSize += strlen($formattedTag); + $formattedTagsChunk[] = $formattedTag; + } + if (!empty($formattedTagsChunk)) { + yield implode('|', array_unique($formattedTagsChunk)); + } + } + + /** + * Send curl purge request to servers + * to invalidate cache by tags pattern + * + * @param \Zend\Http\Client\Adapter\Socket $socketAdapter + * @param \Zend\Uri\Uri[] $servers + * @param string $formattedTagsChunk + * @return bool Return true if successful; otherwise return false + */ + private function sendPurgeRequestToServers($socketAdapter, $servers, $formattedTagsChunk) + { + $headers = [self::HEADER_X_MAGENTO_TAGS_PATTERN => $formattedTagsChunk]; foreach ($servers as $server) { $headers['Host'] = $server->getHost(); try { @@ -69,12 +130,11 @@ public function sendPurgeRequest($tagsPattern) $socketAdapter->read(); $socketAdapter->close(); } catch (\Exception $e) { - $this->logger->critical($e->getMessage(), compact('server', 'tagsPattern')); + $this->logger->critical($e->getMessage(), compact('server', 'formattedTagsChunk')); return false; } } - - $this->logger->execute(compact('servers', 'tagsPattern')); + $this->logger->execute(compact('servers', 'formattedTagsChunk')); return true; } } diff --git a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php index acfd321ea0950..3527d4f6cdf4e 100644 --- a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php +++ b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php @@ -21,18 +21,6 @@ class InvalidateVarnishObserver implements ObserverInterface */ protected $purgeCache; - /** - * Batch size of the purge request. - * - * Based on default Varnish 4 http_req_hdr_len size minus a 512 bytes margin for method, - * header name, line feeds etc. - * - * @see http://www.varnish-cache.org/docs/4.0/reference/varnishd.html#http-req-hdr-len - * - * @var int - */ - private $requestSize = 7680; - /** * Invalidation tags resolver * @@ -56,8 +44,6 @@ public function __construct( * If Varnish caching is enabled it collects array of tags * of incoming object and asks to clean cache. * - * For scaling reason the purge request is chopped down to fix batch size. - * * @param \Magento\Framework\Event\Observer $observer * @return void */ @@ -70,21 +56,10 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled()) { $bareTags = $this->getTagResolver()->getTags($object); - $tagsBatchSize = 0; $tags = []; - $pattern = '((^|,)%s(,|$))'; + $pattern = "((^|,)%s(,|$))"; foreach ($bareTags as $tag) { - $formattedTag = sprintf($pattern, $tag); - - // Send request if batch size is reached and add the implode with pipe to the computation - if ($tagsBatchSize + strlen($formattedTag) > $this->requestSize - count($tags) - 1) { - $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags))); - $tags = []; - $tagsBatchSize = 0; - } - - $tagsBatchSize += strlen($formattedTag); - $tags[] = $formattedTag; + $tags[] = sprintf($pattern, $tag); } if (!empty($tags)) { $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags))); From d3a62b1c8bcdad89d564b0a41f53a08cc81a4fa0 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 11 Oct 2018 15:32:13 +0300 Subject: [PATCH 0496/1415] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Fix integration test --- .../integration/testsuite/Magento/Catalog/_files/categories.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index 9a1a6f24dffc8..a903274793c34 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -84,7 +84,7 @@ $category = $objectManager->create(\Magento\Catalog\Model\Category::class); $category->isObjectNew(true); $category->setId(6) - ->setName('Category 2.1') + ->setName('Category 2') ->setParentId(2) ->setPath('1/2/6') ->setLevel(2) From 13d360dbac2562b401a9426cf8b982062aab693c Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Thu, 11 Oct 2018 08:12:23 -0500 Subject: [PATCH 0497/1415] MAGETWO-95280: Storefront Images Don't Scale Back To Original Size In Mobile - revert jquery mobile upgrade --- lib/web/jquery/jquery.mobile.custom.js | 1853 +++++++++++------------- 1 file changed, 828 insertions(+), 1025 deletions(-) diff --git a/lib/web/jquery/jquery.mobile.custom.js b/lib/web/jquery/jquery.mobile.custom.js index 3b02f5346484c..f289b97b91d83 100644 --- a/lib/web/jquery/jquery.mobile.custom.js +++ b/lib/web/jquery/jquery.mobile.custom.js @@ -1,141 +1,25 @@ /* -* jQuery Mobile v1.5.0-alpha.1 +* jQuery Mobile v1.4.3 * http://jquerymobile.com * -* Copyright jQuery Foundation, Inc. and other contributors +* Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors * Released under the MIT license. * http://jquery.org/license * */ (function ( root, doc, factory ) { - if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery" ], function ( $ ) { - factory( $, root, doc ); - return $.mobile; - }); - } else { - // Browser globals - factory( root.jQuery, root, doc ); - } -}( this, document, function ( jQuery, window, document, undefined ) {/*! - * jQuery Mobile Scroll Events @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Scroll -//>>group: Events -//>>description: Scroll events including: scrollstart, scrollstop - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'events/scroll',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var scrollEvent = "touchmove scroll"; - -// setup new event shortcuts - $.each( [ "scrollstart", "scrollstop" ], function( i, name ) { - - $.fn[ name ] = function( fn ) { - return fn ? this.bind( name, fn ) : this.trigger( name ); - }; - - // jQuery < 1.8 - if ( $.attrFn ) { - $.attrFn[ name ] = true; - } - } ); - -// also handles scrollstop - $.event.special.scrollstart = { - - enabled: true, - setup: function() { - - var thisObject = this, - $this = $( thisObject ), - scrolling, - timer; - - function trigger( event, state ) { - var originalEventType = event.type; - - scrolling = state; - - event.type = scrolling ? "scrollstart" : "scrollstop"; - $.event.dispatch.call( thisObject, event ); - event.type = originalEventType; - } - - var scrollStartHandler = $.event.special.scrollstart.handler = function ( event ) { - - if ( !$.event.special.scrollstart.enabled ) { - return; - } - - if ( !scrolling ) { - trigger( event, true ); - } - - clearTimeout( timer ); - timer = setTimeout( function() { - trigger( event, false ); - }, 50 ); - }; - - // iPhone triggers scroll after a small delay; use touchmove instead - $this.on( scrollEvent, scrollStartHandler ); - }, - teardown: function() { - $( this ).off( scrollEvent, $.event.special.scrollstart.handler ); - } - }; - - $.each( { - scrollstop: "scrollstart" - }, function( event, sourceEvent ) { - - $.event.special[ event ] = { - setup: function() { - $( this ).bind( sourceEvent, $.noop ); - }, - teardown: function() { - $( this ).unbind( sourceEvent ); - } - }; - } ); - - return $.event.special; - } ); - - /*! - * jQuery Mobile Virtual Mouse @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Virtual Mouse (vmouse) Bindings -//>>group: Core -//>>description: Normalizes touch/mouse events. -//>>docs: http://api.jquerymobile.com/?s=vmouse - -// This plugin is an experiment for abstracting away the touch and mouse + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ "jquery" ], function ( $ ) { + factory( $, root, doc ); + return $.mobile; + }); + } else { + // Browser globals + factory( root.jQuery, root, doc ); + } +}( this, document, function ( jQuery, window, document, undefined ) {// This plugin is an experiment for abstracting away the touch and mouse // events so that developers don't have to worry about which method of input // the device their document is loaded on supports. // @@ -150,912 +34,831 @@ // The current version exposes the following virtual events to jQuery bind methods: // "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'vmouse',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var dataPropertyName = "virtualMouseBindings", - touchTargetPropertyName = "virtualTouchID", - touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), - virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), - generalProps = ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + - "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), - mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], - mouseEventProps = generalProps.concat( mouseHookProps ), - activeDocHandlers = {}, - resetTimerID = 0, - startX = 0, - startY = 0, - didScroll = false, - clickBlockList = [], - blockMouseTriggers = false, - blockTouchTriggers = false, - eventCaptureSupported = "addEventListener" in document, - $document = $( document ), - nextTouchID = 1, - lastTouchID = 0, threshold, - i; - - $.vmouse = { - moveDistanceThreshold: 10, - clickDistanceThreshold: 10, - resetTimerDuration: 1500, - maximumTimeBetweenTouches: 100 - }; - - function getNativeEvent( event ) { - - while ( event && typeof event.originalEvent !== "undefined" ) { - event = event.originalEvent; - } - return event; - } - - function createVirtualEvent( event, eventType ) { - - var t = event.type, - oe, props, ne, prop, ct, touch, i, j, len; - - event = $.Event( event ); - event.type = eventType; - - oe = event.originalEvent; - props = generalProps; - - // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 - // https://github.com/jquery/jquery-mobile/issues/3280 - if ( t.search( /^(mouse|click)/ ) > -1 ) { - props = mouseEventProps; - } - - // copy original event properties over to the new event - // this would happen if we could call $.event.fix instead of $.Event - // but we don't have a way to force an event to be fixed multiple times - if ( oe ) { - for ( i = props.length; i; ) { - prop = props[ --i ]; - event[ prop ] = oe[ prop ]; - } - } - - // make sure that if the mouse and click virtual events are generated - // without a .which one is defined - if ( t.search( /mouse(down|up)|click/ ) > -1 && !event.which ) { - event.which = 1; - } - - if ( t.search( /^touch/ ) !== -1 ) { - ne = getNativeEvent( oe ); - t = ne.touches; - ct = ne.changedTouches; - touch = ( t && t.length ) ? t[ 0 ] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); - - if ( touch ) { - for ( j = 0, len = touchEventProps.length; j < len; j++ ) { - prop = touchEventProps[ j ]; - event[ prop ] = touch[ prop ]; - } - } - } - - return event; - } - - function getVirtualBindingFlags( element ) { - - var flags = {}, - b, k; - - while ( element ) { - - b = $.data( element, dataPropertyName ); - - for ( k in b ) { - if ( b[ k ] ) { - flags[ k ] = flags.hasVirtualBinding = true; - } - } - element = element.parentNode; - } - return flags; - } - - function getClosestElementWithVirtualBinding( element, eventType ) { - var b; - while ( element ) { - - b = $.data( element, dataPropertyName ); - - if ( b && ( !eventType || b[ eventType ] ) ) { - return element; - } - element = element.parentNode; - } - return null; - } - - function enableTouchBindings() { - blockTouchTriggers = false; - } - - function disableTouchBindings() { - blockTouchTriggers = true; - } - - function enableMouseBindings() { - lastTouchID = 0; - clickBlockList.length = 0; - blockMouseTriggers = false; - - // When mouse bindings are enabled, our - // touch bindings are disabled. - disableTouchBindings(); - } - - function disableMouseBindings() { - // When mouse bindings are disabled, our - // touch bindings are enabled. - enableTouchBindings(); - } - - function clearResetTimer() { - if ( resetTimerID ) { - clearTimeout( resetTimerID ); - resetTimerID = 0; - } - } - - function startResetTimer() { - clearResetTimer(); - resetTimerID = setTimeout( function() { - resetTimerID = 0; - enableMouseBindings(); - }, $.vmouse.resetTimerDuration ); - } - - function triggerVirtualEvent( eventType, event, flags ) { - var ve; - - if ( ( flags && flags[ eventType ] ) || - ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { - - ve = createVirtualEvent( event, eventType ); - - $( event.target ).trigger( ve ); - } - - return ve; - } - - function mouseEventCallback( event ) { - var touchID = $.data( event.target, touchTargetPropertyName ), - ve; - - // It is unexpected if a click event is received before a touchend - // or touchmove event, however this is a known behavior in Mobile - // Safari when Mobile VoiceOver (as of iOS 8) is enabled and the user - // double taps to activate a link element. In these cases if a touch - // event is not received within the maximum time between touches, - // re-enable mouse bindings and call the mouse event handler again. - if ( event.type === "click" && $.data( event.target, "lastTouchType" ) === "touchstart" ) { - setTimeout( function() { - if ( $.data( event.target, "lastTouchType" ) === "touchstart" ) { - enableMouseBindings(); - delete $.data( event.target ).lastTouchType; - mouseEventCallback( event ); - } - }, $.vmouse.maximumTimeBetweenTouches ); - } - - if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) { - ve = triggerVirtualEvent( "v" + event.type, event ); - if ( ve ) { - if ( ve.isDefaultPrevented() ) { - event.preventDefault(); - } - if ( ve.isPropagationStopped() ) { - event.stopPropagation(); - } - if ( ve.isImmediatePropagationStopped() ) { - event.stopImmediatePropagation(); - } - } - } - } - - function handleTouchStart( event ) { - - var touches = getNativeEvent( event ).touches, - target, flags, t; - - if ( touches && touches.length === 1 ) { - - target = event.target; - flags = getVirtualBindingFlags( target ); - - $.data( event.target, "lastTouchType", event.type ); - - if ( flags.hasVirtualBinding ) { - - lastTouchID = nextTouchID++; - $.data( target, touchTargetPropertyName, lastTouchID ); - - clearResetTimer(); - - disableMouseBindings(); - didScroll = false; - - t = getNativeEvent( event ).touches[ 0 ]; - startX = t.pageX; - startY = t.pageY; - - triggerVirtualEvent( "vmouseover", event, flags ); - triggerVirtualEvent( "vmousedown", event, flags ); - } - } - } - - function handleScroll( event ) { - if ( blockTouchTriggers ) { - return; - } - - if ( !didScroll ) { - triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); - } - - $.data( event.target, "lastTouchType", event.type ); - - didScroll = true; - startResetTimer(); - } - - function handleTouchMove( event ) { - if ( blockTouchTriggers ) { - return; - } - - var t = getNativeEvent( event ).touches[ 0 ], - didCancel = didScroll, - moveThreshold = $.vmouse.moveDistanceThreshold, - flags = getVirtualBindingFlags( event.target ); - - $.data( event.target, "lastTouchType", event.type ); - - didScroll = didScroll || - ( Math.abs( t.pageX - startX ) > moveThreshold || - Math.abs( t.pageY - startY ) > moveThreshold ); - - if ( didScroll && !didCancel ) { - triggerVirtualEvent( "vmousecancel", event, flags ); - } - - triggerVirtualEvent( "vmousemove", event, flags ); - startResetTimer(); - } - - function handleTouchEnd( event ) { - if ( blockTouchTriggers || $.data( event.target, "lastTouchType" ) === undefined ) { - return; - } - - disableTouchBindings(); - delete $.data( event.target ).lastTouchType; - - var flags = getVirtualBindingFlags( event.target ), - ve, t; - triggerVirtualEvent( "vmouseup", event, flags ); - - if ( !didScroll ) { - ve = triggerVirtualEvent( "vclick", event, flags ); - if ( ve && ve.isDefaultPrevented() ) { - // The target of the mouse events that follow the touchend - // event don't necessarily match the target used during the - // touch. This means we need to rely on coordinates for blocking - // any click that is generated. - t = getNativeEvent( event ).changedTouches[ 0 ]; - clickBlockList.push( { - touchID: lastTouchID, - x: t.clientX, - y: t.clientY - } ); - - // Prevent any mouse events that follow from triggering - // virtual event notifications. - blockMouseTriggers = true; - } - } - triggerVirtualEvent( "vmouseout", event, flags ); - didScroll = false; - - startResetTimer(); - } - - function hasVirtualBindings( ele ) { - var bindings = $.data( ele, dataPropertyName ), - k; - - if ( bindings ) { - for ( k in bindings ) { - if ( bindings[ k ] ) { - return true; - } - } - } - return false; - } - - function dummyMouseHandler() { - } - - function getSpecialEventObject( eventType ) { - var realType = eventType.substr( 1 ); - - return { - setup: function( /* data, namespace */ ) { - // If this is the first virtual mouse binding for this element, - // add a bindings object to its data. - - if ( !hasVirtualBindings( this ) ) { - $.data( this, dataPropertyName, {} ); - } - - // If setup is called, we know it is the first binding for this - // eventType, so initialize the count for the eventType to zero. - var bindings = $.data( this, dataPropertyName ); - bindings[ eventType ] = true; - - // If this is the first virtual mouse event for this type, - // register a global handler on the document. - - activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; - - if ( activeDocHandlers[ eventType ] === 1 ) { - $document.bind( realType, mouseEventCallback ); - } - - // Some browsers, like Opera Mini, won't dispatch mouse/click events - // for elements unless they actually have handlers registered on them. - // To get around this, we register dummy handlers on the elements. - - $( this ).bind( realType, dummyMouseHandler ); - - // For now, if event capture is not supported, we rely on mouse handlers. - if ( eventCaptureSupported ) { - // If this is the first virtual mouse binding for the document, - // register our touchstart handler on the document. - - activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0 ) + 1; - - if ( activeDocHandlers[ "touchstart" ] === 1 ) { - $document.bind( "touchstart", handleTouchStart ) - .bind( "touchend", handleTouchEnd ) - - // On touch platforms, touching the screen and then dragging your finger - // causes the window content to scroll after some distance threshold is - // exceeded. On these platforms, a scroll prevents a click event from being - // dispatched, and on some platforms, even the touchend is suppressed. To - // mimic the suppression of the click event, we need to watch for a scroll - // event. Unfortunately, some platforms like iOS don't dispatch scroll - // events until *AFTER* the user lifts their finger (touchend). This means - // we need to watch both scroll and touchmove events to figure out whether - // or not a scroll happenens before the touchend event is fired. - - .bind( "touchmove", handleTouchMove ) - .bind( "scroll", handleScroll ); - } - } - }, - - teardown: function( /* data, namespace */ ) { - // If this is the last virtual binding for this eventType, - // remove its global handler from the document. - - --activeDocHandlers[eventType]; - - if ( !activeDocHandlers[ eventType ] ) { - $document.unbind( realType, mouseEventCallback ); - } - - if ( eventCaptureSupported ) { - // If this is the last virtual mouse binding in existence, - // remove our document touchstart listener. - - --activeDocHandlers["touchstart"]; - - if ( !activeDocHandlers[ "touchstart" ] ) { - $document.unbind( "touchstart", handleTouchStart ) - .unbind( "touchmove", handleTouchMove ) - .unbind( "touchend", handleTouchEnd ) - .unbind( "scroll", handleScroll ); - } - } - - var $this = $( this ), - bindings = $.data( this, dataPropertyName ); - - // teardown may be called when an element was - // removed from the DOM. If this is the case, - // jQuery core may have already stripped the element - // of any data bindings so we need to check it before - // using it. - if ( bindings ) { - bindings[ eventType ] = false; - } +(function( $, window, document, undefined ) { + +var dataPropertyName = "virtualMouseBindings", + touchTargetPropertyName = "virtualTouchID", + virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), + touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), + mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], + mouseEventProps = $.event.props.concat( mouseHookProps ), + activeDocHandlers = {}, + resetTimerID = 0, + startX = 0, + startY = 0, + didScroll = false, + clickBlockList = [], + blockMouseTriggers = false, + blockTouchTriggers = false, + eventCaptureSupported = "addEventListener" in document, + $document = $( document ), + nextTouchID = 1, + lastTouchID = 0, threshold, + i; + +$.vmouse = { + moveDistanceThreshold: 10, + clickDistanceThreshold: 10, + resetTimerDuration: 1500 +}; + +function getNativeEvent( event ) { + + while ( event && typeof event.originalEvent !== "undefined" ) { + event = event.originalEvent; + } + return event; +} + +function createVirtualEvent( event, eventType ) { + + var t = event.type, + oe, props, ne, prop, ct, touch, i, j, len; + + event = $.Event( event ); + event.type = eventType; + + oe = event.originalEvent; + props = $.event.props; + + // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 + // https://github.com/jquery/jquery-mobile/issues/3280 + if ( t.search( /^(mouse|click)/ ) > -1 ) { + props = mouseEventProps; + } + + // copy original event properties over to the new event + // this would happen if we could call $.event.fix instead of $.Event + // but we don't have a way to force an event to be fixed multiple times + if ( oe ) { + for ( i = props.length, prop; i; ) { + prop = props[ --i ]; + event[ prop ] = oe[ prop ]; + } + } + + // make sure that if the mouse and click virtual events are generated + // without a .which one is defined + if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) { + event.which = 1; + } + + if ( t.search(/^touch/) !== -1 ) { + ne = getNativeEvent( oe ); + t = ne.touches; + ct = ne.changedTouches; + touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); + + if ( touch ) { + for ( j = 0, len = touchEventProps.length; j < len; j++) { + prop = touchEventProps[ j ]; + event[ prop ] = touch[ prop ]; + } + } + } + + return event; +} + +function getVirtualBindingFlags( element ) { + + var flags = {}, + b, k; + + while ( element ) { + + b = $.data( element, dataPropertyName ); + + for ( k in b ) { + if ( b[ k ] ) { + flags[ k ] = flags.hasVirtualBinding = true; + } + } + element = element.parentNode; + } + return flags; +} + +function getClosestElementWithVirtualBinding( element, eventType ) { + var b; + while ( element ) { + + b = $.data( element, dataPropertyName ); + + if ( b && ( !eventType || b[ eventType ] ) ) { + return element; + } + element = element.parentNode; + } + return null; +} + +function enableTouchBindings() { + blockTouchTriggers = false; +} + +function disableTouchBindings() { + blockTouchTriggers = true; +} + +function enableMouseBindings() { + lastTouchID = 0; + clickBlockList.length = 0; + blockMouseTriggers = false; + + // When mouse bindings are enabled, our + // touch bindings are disabled. + disableTouchBindings(); +} + +function disableMouseBindings() { + // When mouse bindings are disabled, our + // touch bindings are enabled. + enableTouchBindings(); +} + +function startResetTimer() { + clearResetTimer(); + resetTimerID = setTimeout( function() { + resetTimerID = 0; + enableMouseBindings(); + }, $.vmouse.resetTimerDuration ); +} + +function clearResetTimer() { + if ( resetTimerID ) { + clearTimeout( resetTimerID ); + resetTimerID = 0; + } +} + +function triggerVirtualEvent( eventType, event, flags ) { + var ve; + + if ( ( flags && flags[ eventType ] ) || + ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { + + ve = createVirtualEvent( event, eventType ); + + $( event.target).trigger( ve ); + } + + return ve; +} + +function mouseEventCallback( event ) { + var touchID = $.data( event.target, touchTargetPropertyName ), + ve; + + if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) { + ve = triggerVirtualEvent( "v" + event.type, event ); + if ( ve ) { + if ( ve.isDefaultPrevented() ) { + event.preventDefault(); + } + if ( ve.isPropagationStopped() ) { + event.stopPropagation(); + } + if ( ve.isImmediatePropagationStopped() ) { + event.stopImmediatePropagation(); + } + } + } +} + +function handleTouchStart( event ) { + + var touches = getNativeEvent( event ).touches, + target, flags, t; + + if ( touches && touches.length === 1 ) { + + target = event.target; + flags = getVirtualBindingFlags( target ); + + if ( flags.hasVirtualBinding ) { + + lastTouchID = nextTouchID++; + $.data( target, touchTargetPropertyName, lastTouchID ); + + clearResetTimer(); + + disableMouseBindings(); + didScroll = false; + + t = getNativeEvent( event ).touches[ 0 ]; + startX = t.pageX; + startY = t.pageY; + + triggerVirtualEvent( "vmouseover", event, flags ); + triggerVirtualEvent( "vmousedown", event, flags ); + } + } +} + +function handleScroll( event ) { + if ( blockTouchTriggers ) { + return; + } + + if ( !didScroll ) { + triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); + } + + didScroll = true; + startResetTimer(); +} + +function handleTouchMove( event ) { + if ( blockTouchTriggers ) { + return; + } + + var t = getNativeEvent( event ).touches[ 0 ], + didCancel = didScroll, + moveThreshold = $.vmouse.moveDistanceThreshold, + flags = getVirtualBindingFlags( event.target ); + + didScroll = didScroll || + ( Math.abs( t.pageX - startX ) > moveThreshold || + Math.abs( t.pageY - startY ) > moveThreshold ); + + if ( didScroll && !didCancel ) { + triggerVirtualEvent( "vmousecancel", event, flags ); + } + + triggerVirtualEvent( "vmousemove", event, flags ); + startResetTimer(); +} + +function handleTouchEnd( event ) { + if ( blockTouchTriggers ) { + return; + } + + disableTouchBindings(); + + var flags = getVirtualBindingFlags( event.target ), + ve, t; + triggerVirtualEvent( "vmouseup", event, flags ); + + if ( !didScroll ) { + ve = triggerVirtualEvent( "vclick", event, flags ); + if ( ve && ve.isDefaultPrevented() ) { + // The target of the mouse events that follow the touchend + // event don't necessarily match the target used during the + // touch. This means we need to rely on coordinates for blocking + // any click that is generated. + t = getNativeEvent( event ).changedTouches[ 0 ]; + clickBlockList.push({ + touchID: lastTouchID, + x: t.clientX, + y: t.clientY + }); + + // Prevent any mouse events that follow from triggering + // virtual event notifications. + blockMouseTriggers = true; + } + } + triggerVirtualEvent( "vmouseout", event, flags); + didScroll = false; + + startResetTimer(); +} + +function hasVirtualBindings( ele ) { + var bindings = $.data( ele, dataPropertyName ), + k; + + if ( bindings ) { + for ( k in bindings ) { + if ( bindings[ k ] ) { + return true; + } + } + } + return false; +} + +function dummyMouseHandler() {} + +function getSpecialEventObject( eventType ) { + var realType = eventType.substr( 1 ); + + return { + setup: function(/* data, namespace */) { + // If this is the first virtual mouse binding for this element, + // add a bindings object to its data. + + if ( !hasVirtualBindings( this ) ) { + $.data( this, dataPropertyName, {} ); + } + + // If setup is called, we know it is the first binding for this + // eventType, so initialize the count for the eventType to zero. + var bindings = $.data( this, dataPropertyName ); + bindings[ eventType ] = true; + + // If this is the first virtual mouse event for this type, + // register a global handler on the document. + + activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; + + if ( activeDocHandlers[ eventType ] === 1 ) { + $document.bind( realType, mouseEventCallback ); + } + + // Some browsers, like Opera Mini, won't dispatch mouse/click events + // for elements unless they actually have handlers registered on them. + // To get around this, we register dummy handlers on the elements. + + $( this ).bind( realType, dummyMouseHandler ); + + // For now, if event capture is not supported, we rely on mouse handlers. + if ( eventCaptureSupported ) { + // If this is the first virtual mouse binding for the document, + // register our touchstart handler on the document. + + activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; + + if ( activeDocHandlers[ "touchstart" ] === 1 ) { + $document.bind( "touchstart", handleTouchStart ) + .bind( "touchend", handleTouchEnd ) + + // On touch platforms, touching the screen and then dragging your finger + // causes the window content to scroll after some distance threshold is + // exceeded. On these platforms, a scroll prevents a click event from being + // dispatched, and on some platforms, even the touchend is suppressed. To + // mimic the suppression of the click event, we need to watch for a scroll + // event. Unfortunately, some platforms like iOS don't dispatch scroll + // events until *AFTER* the user lifts their finger (touchend). This means + // we need to watch both scroll and touchmove events to figure out whether + // or not a scroll happenens before the touchend event is fired. + + .bind( "touchmove", handleTouchMove ) + .bind( "scroll", handleScroll ); + } + } + }, + + teardown: function(/* data, namespace */) { + // If this is the last virtual binding for this eventType, + // remove its global handler from the document. + + --activeDocHandlers[ eventType ]; + + if ( !activeDocHandlers[ eventType ] ) { + $document.unbind( realType, mouseEventCallback ); + } + + if ( eventCaptureSupported ) { + // If this is the last virtual mouse binding in existence, + // remove our document touchstart listener. + + --activeDocHandlers[ "touchstart" ]; + + if ( !activeDocHandlers[ "touchstart" ] ) { + $document.unbind( "touchstart", handleTouchStart ) + .unbind( "touchmove", handleTouchMove ) + .unbind( "touchend", handleTouchEnd ) + .unbind( "scroll", handleScroll ); + } + } + + var $this = $( this ), + bindings = $.data( this, dataPropertyName ); + + // teardown may be called when an element was + // removed from the DOM. If this is the case, + // jQuery core may have already stripped the element + // of any data bindings so we need to check it before + // using it. + if ( bindings ) { + bindings[ eventType ] = false; + } - // Unregister the dummy event handler. + // Unregister the dummy event handler. - $this.unbind( realType, dummyMouseHandler ); + $this.unbind( realType, dummyMouseHandler ); - // If this is the last virtual mouse binding on the - // element, remove the binding data from the element. - - if ( !hasVirtualBindings( this ) ) { - $this.removeData( dataPropertyName ); - } - } - }; - } + // If this is the last virtual mouse binding on the + // element, remove the binding data from the element. + + if ( !hasVirtualBindings( this ) ) { + $this.removeData( dataPropertyName ); + } + } + }; +} // Expose our custom events to the jQuery bind/unbind mechanism. - for ( i = 0; i < virtualEventNames.length; i++ ) { - $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); - } +for ( i = 0; i < virtualEventNames.length; i++ ) { + $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); +} // Add a capture click handler to block clicks. // Note that we require event capture support for this so if the device // doesn't support it, we punt for now and rely solely on mouse events. - if ( eventCaptureSupported ) { - document.addEventListener( "click", function( e ) { - var cnt = clickBlockList.length, - target = e.target, - x, y, ele, i, o, touchID; - - if ( cnt ) { - x = e.clientX; - y = e.clientY; - threshold = $.vmouse.clickDistanceThreshold; - - // The idea here is to run through the clickBlockList to see if - // the current click event is in the proximity of one of our - // vclick events that had preventDefault() called on it. If we find - // one, then we block the click. - // - // Why do we have to rely on proximity? - // - // Because the target of the touch event that triggered the vclick - // can be different from the target of the click event synthesized - // by the browser. The target of a mouse/click event that is synthesized - // from a touch event seems to be implementation specific. For example, - // some browsers will fire mouse/click events for a link that is near - // a touch event, even though the target of the touchstart/touchend event - // says the user touched outside the link. Also, it seems that with most - // browsers, the target of the mouse/click event is not calculated until the - // time it is dispatched, so if you replace an element that you touched - // with another element, the target of the mouse/click will be the new - // element underneath that point. - // - // Aside from proximity, we also check to see if the target and any - // of its ancestors were the ones that blocked a click. This is necessary - // because of the strange mouse/click target calculation done in the - // Android 2.1 browser, where if you click on an element, and there is a - // mouse/click handler on one of its ancestors, the target will be the - // innermost child of the touched element, even if that child is no where - // near the point of touch. - - ele = target; - - while ( ele ) { - for ( i = 0; i < cnt; i++ ) { - o = clickBlockList[ i ]; - touchID = 0; - - if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || - $.data( ele, touchTargetPropertyName ) === o.touchID ) { - // XXX: We may want to consider removing matches from the block list - // instead of waiting for the reset timer to fire. - e.preventDefault(); - e.stopPropagation(); - return; - } - } - ele = ele.parentNode; - } - } - }, true ); - } - } ); - - /*! - * jQuery Mobile Namespace @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Namespace -//>>group: Core -//>>description: The mobile namespace on the jQuery object - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'ns',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - $.mobile = { version: "@VERSION" }; - - return $.mobile; - } ); - - /*! - * jQuery Mobile Touch Support Test @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Touch support test -//>>group: Core -//>>description: Touch feature test - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'support/touch',[ - "jquery", - "../ns" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var support = { - touch: "ontouchend" in document - }; - - $.mobile.support = $.mobile.support || {}; - $.extend( $.support, support ); - $.extend( $.mobile.support, support ); - - return $.support; - } ); - - /*! - * jQuery Mobile Touch Events @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Touch -//>>group: Events -//>>description: Touch events including: touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'events/touch',[ - "jquery", - "../vmouse", - "../support/touch" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - var $document = $( document ), - supportTouch = $.mobile.support.touch, - touchStartEvent = supportTouch ? "touchstart" : "mousedown", - touchStopEvent = supportTouch ? "touchend" : "mouseup", - touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; - -// setup new event shortcuts - $.each( ( "touchstart touchmove touchend " + - "tap taphold " + - "swipe swipeleft swiperight" ).split( " " ), function( i, name ) { - - $.fn[ name ] = function( fn ) { - return fn ? this.bind( name, fn ) : this.trigger( name ); - }; - - // jQuery < 1.8 - if ( $.attrFn ) { - $.attrFn[ name ] = true; - } - } ); - - function triggerCustomEvent( obj, eventType, event, bubble ) { - var originalType = event.type; - event.type = eventType; - if ( bubble ) { - $.event.trigger( event, undefined, obj ); - } else { - $.event.dispatch.call( obj, event ); - } - event.type = originalType; - } - -// also handles taphold - $.event.special.tap = { - tapholdThreshold: 750, - emitTapOnTaphold: true, - setup: function() { - var thisObject = this, - $this = $( thisObject ), - isTaphold = false; - - $this.bind( "vmousedown", function( event ) { - isTaphold = false; - if ( event.which && event.which !== 1 ) { - return true; - } - - var origTarget = event.target, - timer, clickHandler; - - function clearTapTimer() { - if ( timer ) { - $this.bind( "vclick", clickHandler ); - clearTimeout( timer ); - } - } - - function clearTapHandlers() { - clearTapTimer(); - - $this.unbind( "vclick", clickHandler ) - .unbind( "vmouseup", clearTapTimer ); - $document.unbind( "vmousecancel", clearTapHandlers ); - } - - clickHandler = function( event ) { - clearTapHandlers(); - - // ONLY trigger a 'tap' event if the start target is - // the same as the stop target. - if ( !isTaphold && origTarget === event.target ) { - triggerCustomEvent( thisObject, "tap", event ); - } else if ( isTaphold ) { - event.preventDefault(); - } - }; - - $this.bind( "vmouseup", clearTapTimer ); - - $document.bind( "vmousecancel", clearTapHandlers ); - - timer = setTimeout( function() { - if ( !$.event.special.tap.emitTapOnTaphold ) { - isTaphold = true; - } - timer = 0; - triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) ); - }, $.event.special.tap.tapholdThreshold ); - } ); - }, - teardown: function() { - $( this ).unbind( "vmousedown" ).unbind( "vclick" ).unbind( "vmouseup" ); - $document.unbind( "vmousecancel" ); - } - }; - -// Also handles swipeleft, swiperight - $.event.special.swipe = { - - // More than this horizontal displacement, and we will suppress scrolling. - scrollSupressionThreshold: 30, - - // More time than this, and it isn't a swipe. - durationThreshold: 1000, - - // Swipe horizontal displacement must be more than this. - horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, - - // Swipe vertical displacement must be less than this. - verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, - - getLocation: function( event ) { - var winPageX = window.pageXOffset, - winPageY = window.pageYOffset, - x = event.clientX, - y = event.clientY; - - if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || - event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { - - // iOS4 clientX/clientY have the value that should have been - // in pageX/pageY. While pageX/page/ have the value 0 - x = x - winPageX; - y = y - winPageY; - } else if ( y < ( event.pageY - winPageY ) || x < ( event.pageX - winPageX ) ) { - - // Some Android browsers have totally bogus values for clientX/Y - // when scrolling/zooming a page. Detectable since clientX/clientY - // should never be smaller than pageX/pageY minus page scroll - x = event.pageX - winPageX; - y = event.pageY - winPageY; - } - - return { - x: x, - y: y - }; - }, - - start: function( event ) { - var data = event.originalEvent.touches ? - event.originalEvent.touches[ 0 ] : event, - location = $.event.special.swipe.getLocation( data ); - return { - time: ( new Date() ).getTime(), - coords: [ location.x, location.y ], - origin: $( event.target ) - }; - }, - - stop: function( event ) { - var data = event.originalEvent.touches ? - event.originalEvent.touches[ 0 ] : event, - location = $.event.special.swipe.getLocation( data ); - return { - time: ( new Date() ).getTime(), - coords: [ location.x, location.y ] - }; - }, - - handleSwipe: function( start, stop, thisObject, origTarget ) { - if ( stop.time - start.time < $.event.special.swipe.durationThreshold && - Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && - Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { - var direction = start.coords[ 0 ] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; - - triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop } ), true ); - triggerCustomEvent( thisObject, direction, $.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); - return true; - } - return false; - - }, - - // This serves as a flag to ensure that at most one swipe event event is - // in work at any given time - eventInProgress: false, - - setup: function() { - var events, - thisObject = this, - $this = $( thisObject ), - context = {}; - - // Retrieve the events data for this element and add the swipe context - events = $.data( this, "mobile-events" ); - if ( !events ) { - events = { length: 0 }; - $.data( this, "mobile-events", events ); - } - events.length++; - events.swipe = context; - - context.start = function( event ) { - - // Bail if we're already working on a swipe event - if ( $.event.special.swipe.eventInProgress ) { - return; - } - $.event.special.swipe.eventInProgress = true; - - var stop, - start = $.event.special.swipe.start( event ), - origTarget = event.target, - emitted = false; - - context.move = function( event ) { - if ( !start || event.isDefaultPrevented() ) { - return; - } - - stop = $.event.special.swipe.stop( event ); - if ( !emitted ) { - emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); - if ( emitted ) { - - // Reset the context to make way for the next swipe event - $.event.special.swipe.eventInProgress = false; - } - } - // prevent scrolling - if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { - event.preventDefault(); - } - }; - - context.stop = function() { - emitted = true; - - // Reset the context to make way for the next swipe event - $.event.special.swipe.eventInProgress = false; - $document.off( touchMoveEvent, context.move ); - context.move = null; - }; - - $document.on( touchMoveEvent, context.move ) - .one( touchStopEvent, context.stop ); - }; - $this.on( touchStartEvent, context.start ); - }, - - teardown: function() { - var events, context; - - events = $.data( this, "mobile-events" ); - if ( events ) { - context = events.swipe; - delete events.swipe; - events.length--; - if ( events.length === 0 ) { - $.removeData( this, "mobile-events" ); - } - } - - if ( context ) { - if ( context.start ) { - $( this ).off( touchStartEvent, context.start ); - } - if ( context.move ) { - $document.off( touchMoveEvent, context.move ); - } - if ( context.stop ) { - $document.off( touchStopEvent, context.stop ); - } - } - } - }; - $.each( { - taphold: "tap", - swipeleft: "swipe.left", - swiperight: "swipe.right" - }, function( event, sourceEvent ) { - - $.event.special[ event ] = { - setup: function() { - $( this ).bind( sourceEvent, $.noop ); - }, - teardown: function() { - $( this ).unbind( sourceEvent ); - } - }; - } ); - - return $.event.special; - } ); - +if ( eventCaptureSupported ) { + document.addEventListener( "click", function( e ) { + var cnt = clickBlockList.length, + target = e.target, + x, y, ele, i, o, touchID; + + if ( cnt ) { + x = e.clientX; + y = e.clientY; + threshold = $.vmouse.clickDistanceThreshold; + + // The idea here is to run through the clickBlockList to see if + // the current click event is in the proximity of one of our + // vclick events that had preventDefault() called on it. If we find + // one, then we block the click. + // + // Why do we have to rely on proximity? + // + // Because the target of the touch event that triggered the vclick + // can be different from the target of the click event synthesized + // by the browser. The target of a mouse/click event that is synthesized + // from a touch event seems to be implementation specific. For example, + // some browsers will fire mouse/click events for a link that is near + // a touch event, even though the target of the touchstart/touchend event + // says the user touched outside the link. Also, it seems that with most + // browsers, the target of the mouse/click event is not calculated until the + // time it is dispatched, so if you replace an element that you touched + // with another element, the target of the mouse/click will be the new + // element underneath that point. + // + // Aside from proximity, we also check to see if the target and any + // of its ancestors were the ones that blocked a click. This is necessary + // because of the strange mouse/click target calculation done in the + // Android 2.1 browser, where if you click on an element, and there is a + // mouse/click handler on one of its ancestors, the target will be the + // innermost child of the touched element, even if that child is no where + // near the point of touch. + + ele = target; + + while ( ele ) { + for ( i = 0; i < cnt; i++ ) { + o = clickBlockList[ i ]; + touchID = 0; + + if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || + $.data( ele, touchTargetPropertyName ) === o.touchID ) { + // XXX: We may want to consider removing matches from the block list + // instead of waiting for the reset timer to fire. + e.preventDefault(); + e.stopPropagation(); + return; + } + } + ele = ele.parentNode; + } + } + }, true); +} +})( jQuery, window, document ); + +(function( $ ) { + $.mobile = {}; +}( jQuery )); + + (function( $, undefined ) { + var support = { + touch: "ontouchend" in document + }; + + $.mobile.support = $.mobile.support || {}; + $.extend( $.support, support ); + $.extend( $.mobile.support, support ); + }( jQuery )); + + +(function( $, window, undefined ) { + var $document = $( document ), + supportTouch = $.mobile.support.touch, + scrollEvent = "touchmove scroll", + touchStartEvent = supportTouch ? "touchstart" : "mousedown", + touchStopEvent = supportTouch ? "touchend" : "mouseup", + touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; + + // setup new event shortcuts + $.each( ( "touchstart touchmove touchend " + + "tap taphold " + + "swipe swipeleft swiperight " + + "scrollstart scrollstop" ).split( " " ), function( i, name ) { + + $.fn[ name ] = function( fn ) { + return fn ? this.bind( name, fn ) : this.trigger( name ); + }; + + // jQuery < 1.8 + if ( $.attrFn ) { + $.attrFn[ name ] = true; + } + }); + + function triggerCustomEvent( obj, eventType, event, bubble ) { + var originalType = event.type; + event.type = eventType; + if ( bubble ) { + $.event.trigger( event, undefined, obj ); + } else { + $.event.dispatch.call( obj, event ); + } + event.type = originalType; + } + + // also handles scrollstop + $.event.special.scrollstart = { + + enabled: true, + setup: function() { + + var thisObject = this, + $this = $( thisObject ), + scrolling, + timer; + + function trigger( event, state ) { + scrolling = state; + triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); + } + + // iPhone triggers scroll after a small delay; use touchmove instead + $this.bind( scrollEvent, function( event ) { + + if ( !$.event.special.scrollstart.enabled ) { + return; + } + + if ( !scrolling ) { + trigger( event, true ); + } + + clearTimeout( timer ); + timer = setTimeout( function() { + trigger( event, false ); + }, 50 ); + }); + }, + teardown: function() { + $( this ).unbind( scrollEvent ); + } + }; + + // also handles taphold + $.event.special.tap = { + tapholdThreshold: 750, + emitTapOnTaphold: true, + setup: function() { + var thisObject = this, + $this = $( thisObject ), + isTaphold = false; + + $this.bind( "vmousedown", function( event ) { + isTaphold = false; + if ( event.which && event.which !== 1 ) { + return false; + } + + var origTarget = event.target, + timer; + + function clearTapTimer() { + clearTimeout( timer ); + } + + function clearTapHandlers() { + clearTapTimer(); + + $this.unbind( "vclick", clickHandler ) + .unbind( "vmouseup", clearTapTimer ); + $document.unbind( "vmousecancel", clearTapHandlers ); + } + + function clickHandler( event ) { + clearTapHandlers(); + + // ONLY trigger a 'tap' event if the start target is + // the same as the stop target. + if ( !isTaphold && origTarget === event.target ) { + triggerCustomEvent( thisObject, "tap", event ); + } else if ( isTaphold ) { + event.preventDefault(); + } + } + + $this.bind( "vmouseup", clearTapTimer ) + .bind( "vclick", clickHandler ); + $document.bind( "vmousecancel", clearTapHandlers ); + + timer = setTimeout( function() { + if ( !$.event.special.tap.emitTapOnTaphold ) { + isTaphold = true; + } + triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) ); + }, $.event.special.tap.tapholdThreshold ); + }); + }, + teardown: function() { + $( this ).unbind( "vmousedown" ).unbind( "vclick" ).unbind( "vmouseup" ); + $document.unbind( "vmousecancel" ); + } + }; + + // Also handles swipeleft, swiperight + $.event.special.swipe = { + + // More than this horizontal displacement, and we will suppress scrolling. + scrollSupressionThreshold: 30, + + // More time than this, and it isn't a swipe. + durationThreshold: 1000, + + // Swipe horizontal displacement must be more than this. + horizontalDistanceThreshold: 30, + + // Swipe vertical displacement must be less than this. + verticalDistanceThreshold: 30, + + getLocation: function ( event ) { + var winPageX = window.pageXOffset, + winPageY = window.pageYOffset, + x = event.clientX, + y = event.clientY; + + if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || + event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { + + // iOS4 clientX/clientY have the value that should have been + // in pageX/pageY. While pageX/page/ have the value 0 + x = x - winPageX; + y = y - winPageY; + } else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) { + + // Some Android browsers have totally bogus values for clientX/Y + // when scrolling/zooming a page. Detectable since clientX/clientY + // should never be smaller than pageX/pageY minus page scroll + x = event.pageX - winPageX; + y = event.pageY - winPageY; + } + + return { + x: x, + y: y + }; + }, + + start: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ], + origin: $( event.target ) + }; + }, + + stop: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ] + }; + }, + + handleSwipe: function( start, stop, thisObject, origTarget ) { + if ( stop.time - start.time < $.event.special.swipe.durationThreshold && + Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && + Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { + var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; + + triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true ); + triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); + return true; + } + return false; + + }, + + // This serves as a flag to ensure that at most one swipe event event is + // in work at any given time + eventInProgress: false, + + setup: function() { + var events, + thisObject = this, + $this = $( thisObject ), + context = {}; + + // Retrieve the events data for this element and add the swipe context + events = $.data( this, "mobile-events" ); + if ( !events ) { + events = { length: 0 }; + $.data( this, "mobile-events", events ); + } + events.length++; + events.swipe = context; + + context.start = function( event ) { + + // Bail if we're already working on a swipe event + if ( $.event.special.swipe.eventInProgress ) { + return; + } + $.event.special.swipe.eventInProgress = true; + + var stop, + start = $.event.special.swipe.start( event ), + origTarget = event.target, + emitted = false; + + context.move = function( event ) { + if ( !start ) { + return; + } + + stop = $.event.special.swipe.stop( event ); + if ( !emitted ) { + emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); + if ( emitted ) { + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + } + } + // prevent scrolling + if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { + event.preventDefault(); + } + }; + + context.stop = function() { + emitted = true; + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + $document.off( touchMoveEvent, context.move ); + context.move = null; + }; + + $document.on( touchMoveEvent, context.move ) + .one( touchStopEvent, context.stop ); + }; + $this.on( touchStartEvent, context.start ); + }, + + teardown: function() { + var events, context; + + events = $.data( this, "mobile-events" ); + if ( events ) { + context = events.swipe; + delete events.swipe; + events.length--; + if ( events.length === 0 ) { + $.removeData( this, "mobile-events" ); + } + } + + if ( context ) { + if ( context.start ) { + $( this ).off( touchStartEvent, context.start ); + } + if ( context.move ) { + $document.off( touchMoveEvent, context.move ); + } + if ( context.stop ) { + $document.off( touchStopEvent, context.stop ); + } + } + } + }; + $.each({ + scrollstop: "scrollstart", + taphold: "tap", + swipeleft: "swipe.left", + swiperight: "swipe.right" + }, function( event, sourceEvent ) { + + $.event.special[ event ] = { + setup: function() { + $( this ).bind( sourceEvent, $.noop ); + }, + teardown: function() { + $( this ).unbind( sourceEvent ); + } + }; + }); + +})( jQuery, this ); })); From ef60a4e44a6ea66d60d076734d0a86b85876664e Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Thu, 11 Oct 2018 08:28:13 -0500 Subject: [PATCH 0498/1415] MAGETWO-94438: AdminAddImageToWYSIWYGProductTest is unstable --- .../Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml index 37c0eb6ea1253..d8f6bc3e4a749 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -16,6 +16,9 @@ <description value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84375"/> + <skip> + <issueId value="MAGETWO-94438"/> + </skip> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> From 6e20e2e642bdb8a5fee6b5a0979591ff0b4f71e1 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Thu, 11 Oct 2018 16:39:20 +0300 Subject: [PATCH 0499/1415] MAGETWO-95539: [2.3] Moving Category generate duplicate url_rewrite when 4th level category exist and is translated - Fixed url rewrites regeneration after category moving --- .../Model/Category/Plugin/Category/Move.php | 57 +++++++++++++++++-- .../Model/CategoryUrlRewriteGenerator.php | 8 +++ .../Category/Plugin/Category/MoveTest.php | 33 ++++++++--- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php index 17d12ba563ebd..8a70af213c612 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php @@ -6,9 +6,14 @@ namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Category; use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\CategoryFactory; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; +use Magento\Store\Model\Store; +/** + * Perform url updating for children categories. + */ class Move { /** @@ -21,16 +26,24 @@ class Move */ private $childrenCategoriesProvider; + /** + * @var CategoryFactory + */ + private $categoryFactory; + /** * @param CategoryUrlPathGenerator $categoryUrlPathGenerator * @param ChildrenCategoriesProvider $childrenCategoriesProvider + * @param CategoryFactory $categoryFactory */ public function __construct( CategoryUrlPathGenerator $categoryUrlPathGenerator, - ChildrenCategoriesProvider $childrenCategoriesProvider + ChildrenCategoriesProvider $childrenCategoriesProvider, + CategoryFactory $categoryFactory ) { $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; $this->childrenCategoriesProvider = $childrenCategoriesProvider; + $this->categoryFactory = $categoryFactory; } /** @@ -51,20 +64,54 @@ public function afterChangeParent( Category $newParent, $afterCategoryId ) { - $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); - $category->getResource()->saveAttribute($category, 'url_path'); - $this->updateUrlPathForChildren($category); + foreach ($category->getStoreIds() as $storeId) { + $category->setStoreId($storeId); + if (!$this->isGlobalScope($storeId)) { + $this->updateCategoryUrlKeyForStore($category); + $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); + $category->getResource()->saveAttribute($category, 'url_path'); + $this->updateUrlPathForChildren($category); + } + } return $result; } /** + * Set category url_key according to current category store id. + * + * @param Category $category + * @return void + */ + private function updateCategoryUrlKeyForStore(Category $category) + { + $item = $this->categoryFactory->create(); + $item->setStoreId($category->getStoreId()); + $item->load($category->getId()); + $category->setUrlKey($item->getUrlKey()); + } + + /** + * Check is global scope. + * + * @param int|null $storeId + * @return bool + */ + private function isGlobalScope($storeId) + { + return null === $storeId || $storeId == Store::DEFAULT_STORE_ID; + } + + /** + * Updates url_path for child categories. + * * @param Category $category * @return void */ - protected function updateUrlPathForChildren($category) + private function updateUrlPathForChildren($category) { foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) { + $childCategory->setStoreId($category->getStoreId()); $childCategory->unsUrlPath(); $childCategory->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($childCategory)); $childCategory->getResource()->saveAttribute($childCategory, 'url_path'); diff --git a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php index b2da0ab39f31f..a86604672e2b4 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGenerator.php @@ -15,6 +15,9 @@ use Magento\Framework\App\ObjectManager; use Magento\UrlRewrite\Model\MergeDataProviderFactory; +/** + * Generate list of urls. + */ class CategoryUrlRewriteGenerator { /** Entity type code */ @@ -84,6 +87,8 @@ public function __construct( } /** + * Generate list of urls. + * * @param \Magento\Catalog\Model\Category $category * @param bool $overrideStoreUrls * @param int|null $rootCategoryId @@ -119,6 +124,7 @@ protected function generateForGlobalScope( $mergeDataProvider = clone $this->mergeDataProviderPrototype; $categoryId = $category->getId(); foreach ($category->getStoreIds() as $storeId) { + $category->setStoreId($storeId); if (!$this->isGlobalScope($storeId) && $this->isOverrideUrlsForStore($storeId, $categoryId, $overrideStoreUrls) ) { @@ -131,6 +137,8 @@ protected function generateForGlobalScope( } /** + * Checks if urls should be overridden for store. + * * @param int $storeId * @param int $categoryId * @param bool $overrideStoreUrls diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php index f91a55c11b974..b69aabe76c35e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php @@ -5,6 +5,7 @@ */ namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Category; +use Magento\Catalog\Model\CategoryFactory; use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move as CategoryMovePlugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; @@ -39,6 +40,11 @@ class MoveTest extends \PHPUnit\Framework\TestCase */ private $categoryMock; + /** + * @var CategoryFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryFactory; + /** * @var CategoryMovePlugin */ @@ -55,28 +61,44 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['getChildren']) ->getMock(); + $this->categoryFactory = $this->getMockBuilder(CategoryFactory::class) + ->disableOriginalConstructor() + ->getMock(); $this->subjectMock = $this->getMockBuilder(CategoryResourceModel::class) ->disableOriginalConstructor() ->getMock(); $this->categoryMock = $this->getMockBuilder(Category::class) ->disableOriginalConstructor() - ->setMethods(['getResource', 'setUrlPath']) + ->setMethods(['getResource', 'setUrlPath', 'getStoreIds']) ->getMock(); $this->plugin = $this->objectManager->getObject( CategoryMovePlugin::class, [ 'categoryUrlPathGenerator' => $this->categoryUrlPathGeneratorMock, - 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock + 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock, + 'categoryFactory' => $this->categoryFactory ] ); } + /** + * Tests url updating for children categories. + */ public function testAfterChangeParent() { $urlPath = 'test/path'; - $this->categoryMock->expects($this->once()) - ->method('getResource') + $storeIds = [1]; + $originalCategory = $this->getMockBuilder(Category::class) + ->disableOriginalConstructor() + ->getMock(); + $this->categoryFactory->method('create') + ->willReturn($originalCategory); + + $this->categoryMock->method('getResource') ->willReturn($this->subjectMock); + $this->categoryMock->expects($this->once()) + ->method('getStoreIds') + ->willReturn($storeIds); $this->childrenCategoriesProviderMock->expects($this->once()) ->method('getChildren') ->with($this->categoryMock, true) @@ -85,9 +107,6 @@ public function testAfterChangeParent() ->method('getUrlPath') ->with($this->categoryMock) ->willReturn($urlPath); - $this->categoryMock->expects($this->once()) - ->method('getResource') - ->willReturn($this->subjectMock); $this->categoryMock->expects($this->once()) ->method('setUrlPath') ->with($urlPath); From 5bd5e4d9c53e4883e31be4d062a665fac2d9d2ba Mon Sep 17 00:00:00 2001 From: BezV8 <berwyn@v8media.co.uk> Date: Thu, 11 Oct 2018 15:18:14 +0100 Subject: [PATCH 0500/1415] Fix validation errors on cart page. --- .../Magento/Checkout/view/frontend/templates/cart/form.phtml | 2 +- .../Checkout/view/frontend/templates/cart/item/default.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml index 71b1392d5391f..e762a89dc1580 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml @@ -26,7 +26,7 @@ class="cart items data table" data-mage-init='{"shoppingCart":{"emptyCartButton": "action.clear", "updateCartActionContainer": "#update_cart_action_container"}}'> - <caption role="heading" aria-level="2" class="table-caption"><?= /* @escapeNotVerified */ __('Shopping Cart Items') ?></caption> + <caption class="table-caption"><?= /* @escapeNotVerified */ __('Shopping Cart Items') ?></caption> <thead> <tr> <th class="col item" scope="col"><span><?= /* @escapeNotVerified */ __('Item') ?></span></th> diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml index 0567c61f0db60..c96df9cdd3195 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml @@ -111,7 +111,7 @@ $canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinima </td> </tr> <tr class="item-actions"> - <td colspan="100"> + <td colspan="4"> <div class="actions-toolbar"> <?= /* @escapeNotVerified */ $block->getActions($_item) ?> </div> From 66198844e9a8653b3f53b63588d7b071daf65589 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 11 Oct 2018 17:20:25 +0300 Subject: [PATCH 0501/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 8 ++++---- app/code/Magento/Backend/Block/Media/Uploader.php | 12 ++++++------ ...{ImageUploadConfig.php => UploadResizeConfig.php} | 2 +- ...Interface.php => UploadResizeConfigInterface.php} | 4 ++-- app/code/Magento/Backend/etc/adminhtml/di.xml | 2 +- app/code/Magento/Backend/etc/adminhtml/system.xml | 4 ++-- .../Backend/view/adminhtml/web/js/media-uploader.js | 8 +++----- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- .../Magento/Framework/Image/Adapter/Config.php | 4 ++-- .../Image/Adapter/UploadConfigInterface.php | 4 ++-- 10 files changed, 24 insertions(+), 26 deletions(-) rename app/code/Magento/Backend/Model/Image/{ImageUploadConfig.php => UploadResizeConfig.php} (96%) rename app/code/Magento/Backend/Model/Image/{ImageUploadConfigInterface.php => UploadResizeConfigInterface.php} (89%) diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php index 6ec40cfa0b2d4..9c17b0e5538f4 100644 --- a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -8,7 +8,7 @@ namespace Magento\Backend\Block\DataProviders; use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Backend\Model\Image\ImageUploadConfigInterface; +use Magento\Backend\Model\Image\UploadResizeConfigInterface; /** * Provides additional data for image uploader @@ -16,14 +16,14 @@ class ImageUploadConfig implements ArgumentInterface { /** - * @var ImageUploadConfigInterface + * @var UploadResizeConfigInterface */ private $imageUploadConfig; /** - * @param ImageUploadConfigInterface $imageUploadConfig + * @param UploadResizeConfigInterface $imageUploadConfig */ - public function __construct(ImageUploadConfigInterface $imageUploadConfig) + public function __construct(UploadResizeConfigInterface $imageUploadConfig) { $this->imageUploadConfig = $imageUploadConfig; } diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 941d6f37737fe..84fa487281ac8 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -10,7 +10,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Image\Adapter\UploadConfigInterface; -use Magento\Backend\Model\Image\ImageUploadConfigInterface; +use Magento\Backend\Model\Image\UploadResizeConfigInterface; /** * Adminhtml media library uploader @@ -40,14 +40,14 @@ class Uploader extends \Magento\Backend\Block\Widget private $jsonEncoder; /** - * @var ImageUploadConfigInterface + * @var UploadResizeConfigInterface */ private $imageUploadConfig; /** * @var UploadConfigInterface * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface */ private $imageConfig; @@ -57,7 +57,7 @@ class Uploader extends \Magento\Backend\Block\Widget * @param array $data * @param Json $jsonEncoder * @param UploadConfigInterface $imageConfig - * @param ImageUploadConfigInterface $imageUploadConfig + * @param UploadResizeConfigInterface $imageUploadConfig */ public function __construct( \Magento\Backend\Block\Template\Context $context, @@ -65,14 +65,14 @@ public function __construct( array $data = [], Json $jsonEncoder = null, UploadConfigInterface $imageConfig = null, - ImageUploadConfigInterface $imageUploadConfig = null + UploadResizeConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); $this->imageConfig = $imageConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); $this->imageUploadConfig = $imageUploadConfig - ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); + ?: ObjectManager::getInstance()->get(UploadResizeConfigInterface::class); parent::__construct($context, $data); } diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php b/app/code/Magento/Backend/Model/Image/UploadResizeConfig.php similarity index 96% rename from app/code/Magento/Backend/Model/Image/ImageUploadConfig.php rename to app/code/Magento/Backend/Model/Image/UploadResizeConfig.php index b7e13b1e8274c..8155aa5e2fe2d 100644 --- a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Model/Image/UploadResizeConfig.php @@ -10,7 +10,7 @@ /** * Image uploader config provider. */ -class ImageUploadConfig implements ImageUploadConfigInterface +class UploadResizeConfig implements UploadResizeConfigInterface { /** * Config path for the maximal image width value diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php b/app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php similarity index 89% rename from app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php rename to app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php index 254a13407b2c1..50582dfafbcd1 100644 --- a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php +++ b/app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php @@ -8,11 +8,11 @@ namespace Magento\Backend\Model\Image; /** - * Interface ImageUploadConfigInterface + * Interface UploadResizeConfigInterface * * Used to retrieve configuration for frontend image uploader */ -interface ImageUploadConfigInterface +interface UploadResizeConfigInterface { /** * Get maximal width value for resized image diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index dcfc99cfed310..4abea272c5495 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -168,5 +168,5 @@ </arguments> </type> <preference for="CsrfRequestValidator" type="Magento\Backend\App\Request\BackendValidator" /> - <preference for="Magento\Backend\Model\Image\ImageUploadConfigInterface" type="Magento\Backend\Model\Image\ImageUploadConfig" /> + <preference for="Magento\Backend\Model\Image\UploadResizeConfigInterface" type="Magento\Backend\Model\Image\UploadResizeConfig" /> </config> diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 3a0d3e50acc5a..2915d8d671a01 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -339,9 +339,9 @@ <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Images Upload Configuration</label> <field id="enable_resize" translate="label" type="select" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> - <label>Enable Front-end Resize</label> + <label>Enable Frontend Resize</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> - <comment>Resize performed by javascript during file upload.</comment> + <comment>Resize performed via javascript before file upload.</comment> </field> <field id="max_width" translate="label comment" type="text" sortOrder="300" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Width</label> diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index e1d5a0a9debe5..119e7a35747cb 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -33,8 +33,7 @@ define([ * @private */ _create: function () { - var - self = this, + var self = this, progressTmpl = mageTemplate('[data-template="uploader"]'), isResizeEnabled = this.options.isResizeEnabled, resizeConfiguration = { @@ -43,7 +42,7 @@ define([ maxHeight: this.options.maxHeight }; - if (isResizeEnabled === 0) { + if (!isResizeEnabled) { resizeConfiguration = { action: 'resize' }; @@ -64,8 +63,7 @@ define([ * @param {Object} data */ add: function (e, data) { - var - fileSize, + var fileSize, tmpl; $.each(data.files, function (index, file) { diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 2d872fc06b416..74661acb8f136 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -207,7 +207,7 @@ <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> - <comment>Jpeg quality for images 1-100%.</comment> + <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> </section> diff --git a/lib/internal/Magento/Framework/Image/Adapter/Config.php b/lib/internal/Magento/Framework/Image/Adapter/Config.php index 84b6b6dcfbdd1..636bbcdcbdb41 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Config.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Config.php @@ -66,7 +66,7 @@ public function getAdapters() * * @return int * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface::getMaxHeight() */ public function getMaxWidth(): int { @@ -78,7 +78,7 @@ public function getMaxWidth(): int * * @return int * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface::getMaxHeight() */ public function getMaxHeight(): int { diff --git a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php index 990062b83ef6f..0a2dbefff8ee0 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php @@ -9,8 +9,8 @@ /** * Interface UploadConfigInterface - * @deprecated because new interface was introduced - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface; + * @deprecated moved to proper namespace and extended + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface; */ interface UploadConfigInterface { From 09fcc07642fdc8a1b63b00b2150b986a94206d50 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 10 Oct 2018 13:51:46 -0500 Subject: [PATCH 0502/1415] MAGETWO-95363: Update Magento\Ui\Controller\Adminhtml\Index\Render\Handle controller --- .../Adminhtml/Index/Render/Handle.php | 30 ++++++++- .../Adminhtml/Index/Render/HandleTest.php | 63 ++++++++++++++++--- .../Adminhtml/Index/Renderer/HandleTest.php | 52 +++++++++++++++ .../Magento/Ui/Model/AuthorizationMock.php | 27 ++++++++ 4 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Ui/Controller/Adminhtml/Index/Renderer/HandleTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ui/Model/AuthorizationMock.php diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php index d1254790cb8eb..3b2a81fdac729 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php @@ -23,14 +23,18 @@ class Handle extends AbstractAction implements HttpGetActionInterface */ public function execute() { + $response = ''; $handle = $this->_request->getParam('handle'); $namespace = $this->_request->getParam('namespace'); $buttons = $this->_request->getParam('buttons', false); - $this->_view->loadLayout(['default', $handle], true, true, false); + $component = $this->factory->create($namespace); + if ($this->validateAclResource($component->getContext()->getDataProvider()->getConfigData())) { + $this->_view->loadLayout(['default', $handle], true, true, false); - $uiComponent = $this->_view->getLayout()->getBlock($namespace); - $response = $uiComponent instanceof UiComponent ? $uiComponent->toHtml() : ''; + $uiComponent = $this->_view->getLayout()->getBlock($namespace); + $response = $uiComponent instanceof UiComponent ? $uiComponent->toHtml() : ''; + } if ($buttons) { $actionsToolbar = $this->_view->getLayout()->getBlock(ActionPool::ACTIONS_PAGE_TOOLBAR); @@ -39,4 +43,24 @@ public function execute() $this->_response->appendBody($response); } + + /** + * Optionally validate ACL resource of components with a DataSource/DataProvider + * + * @param mixed $dataProviderConfigData + * @return bool + */ + private function validateAclResource($dataProviderConfigData) + { + if (isset($dataProviderConfigData['aclResource']) + && !$this->_authorization->isAllowed($dataProviderConfigData['aclResource']) + ) { + if (!$this->_request->isAjax()) { + $this->_redirect('admin/denied'); + } + return false; + } + + return true; + } } diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php index 31d5b421013f6..e7752678f0c86 100644 --- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php +++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php @@ -6,6 +6,7 @@ namespace Magento\Ui\Test\Unit\Controller\Adminhtml\Index\Render; use Magento\Ui\Controller\Adminhtml\Index\Render\Handle; +use Magento\Framework\View\Element\UiComponent\ContextInterface; class HandleTest extends \PHPUnit\Framework\TestCase { @@ -27,22 +28,42 @@ class HandleTest extends \PHPUnit\Framework\TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $componentFactoryMock; + protected $viewMock; + + /** + * @var Handle + */ + protected $controller; + + /** + * @var \Magento\Framework\AuthorizationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $authorizationMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $viewMock; + private $uiComponentContextMock; /** - * @var Handle + * @var \Magento\Framework\View\Element\UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $controller; + private $uiComponentMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $uiFactoryMock; + + /** + * @var \Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface| + * \PHPUnit_Framework_MockObject_MockObject + */ + private $dataProviderMock; public function setUp() { $this->contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class); - $this->componentFactoryMock = $this->createMock(\Magento\Framework\View\Element\UiComponentFactory::class); $this->requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class); $this->contextMock->expects($this->atLeastOnce())->method('getRequest')->willReturn($this->requestMock); @@ -52,8 +73,36 @@ public function setUp() $this->viewMock = $this->createMock(\Magento\Framework\App\ViewInterface::class); $this->contextMock->expects($this->atLeastOnce())->method('getView')->willReturn($this->viewMock); - - $this->controller = new Handle($this->contextMock, $this->componentFactoryMock); + $this->authorizationMock = $this->getMockBuilder(\Magento\Framework\AuthorizationInterface::class) + ->getMockForAbstractClass(); + $this->authorizationMock->expects($this->any()) + ->method('isAllowed') + ->willReturn(true); + $this->uiComponentContextMock = $this->getMockForAbstractClass( + ContextInterface::class + ); + $this->uiComponentMock = $this->getMockForAbstractClass( + \Magento\Framework\View\Element\UiComponentInterface::class + ); + $this->dataProviderMock = $this->getMockForAbstractClass( + \Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface::class + ); + $this->uiComponentContextMock->expects($this->once()) + ->method('getDataProvider') + ->willReturn($this->dataProviderMock); + $this->uiFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Element\UiComponentFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->uiComponentMock->expects($this->any()) + ->method('getContext') + ->willReturn($this->uiComponentContextMock); + $this->uiFactoryMock->expects($this->any()) + ->method('create') + ->willReturn($this->uiComponentMock); + $this->dataProviderMock->expects($this->once()) + ->method('getConfigData') + ->willReturn([]); + $this->controller = new Handle($this->contextMock, $this->uiFactoryMock); } public function testExecuteNoButtons() diff --git a/dev/tests/integration/testsuite/Magento/Ui/Controller/Adminhtml/Index/Renderer/HandleTest.php b/dev/tests/integration/testsuite/Magento/Ui/Controller/Adminhtml/Index/Renderer/HandleTest.php new file mode 100644 index 0000000000000..dbe721a76e2c6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ui/Controller/Adminhtml/Index/Renderer/HandleTest.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Ui\Controller\Adminhtml\Index\Renderer; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\AuthorizationInterface; + +/** + * @magentoAppArea adminhtml + */ +class HandleTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testExecuteWhenUserDoesNotHavePermission() + { + Bootstrap::getObjectManager()->configure([ + 'preferences' => [ + AuthorizationInterface::class => \Magento\Ui\Model\AuthorizationMock::class + ] + ]); + $this->getRequest()->setParam('handle', 'customer_index_index'); + $this->getRequest()->setParam('namespace', 'customer_listing'); + $this->getRequest()->setParam('sorting%5Bfield%5D', 'entity_id'); + $this->getRequest()->setParam('paging%5BpageSize%5D', 20); + $this->getRequest()->setParam('isAjax', 1); + $this->dispatch('backend/mui/index/render_handle'); + $output = $this->getResponse()->getBody(); + $this->assertEmpty($output, 'The acl restriction wasn\'t applied properly'); + } + + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testExecuteWhenUserHasPermission() + { + $this->getRequest()->setParam('handle', 'customer_index_index'); + $this->getRequest()->setParam('namespace', 'customer_listing'); + $this->getRequest()->setParam('sorting%5Bfield%5D', 'entity_id'); + $this->getRequest()->setParam('paging%5BpageSize%5D', 20); + $this->getRequest()->setParam('isAjax', 1); + $this->dispatch('backend/mui/index/render_handle'); + $output = $this->getResponse()->getBody(); + $this->assertNotEmpty($output, 'The acl restriction wasn\'t applied properly'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Ui/Model/AuthorizationMock.php b/dev/tests/integration/testsuite/Magento/Ui/Model/AuthorizationMock.php new file mode 100644 index 0000000000000..76f472f30eb1f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ui/Model/AuthorizationMock.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Ui\Model; + +/** + * Class AuthorizationMock + */ +class AuthorizationMock extends \Magento\Framework\Authorization +{ + /** + * Check current user permission on resource and privilege + * + * @param string $resource + * @param string $privilege + * @return boolean + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function isAllowed($resource, $privilege = null) + { + return $resource !== 'Magento_Customer::manage'; + } +} From ad0934a8aaab00bd612206e63d99d4ac2c555131 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 11 Oct 2018 09:43:53 -0500 Subject: [PATCH 0503/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel - updated test after CR comments --- .../Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml index cff605d7c907f..0ca1d72a3ae1d 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -23,7 +23,7 @@ </before> <after> <deleteData createDataKey="customer" stepKey="deleteCustomer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!--Edit customer info--> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> From 2cb6a021a85045167c1affc365ce66670a8aaea7 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Thu, 11 Oct 2018 17:53:55 +0300 Subject: [PATCH 0504/1415] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- .../Model/FilterProductCustomAttribute.php | 2 +- app/code/Magento/Catalog/Model/Product.php | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index 830b974e5edb2..497ed2fd49953 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -28,7 +28,7 @@ public function __construct(array $blackList = []) /** * Delete custom attribute * - * @param array $attributes + * @param array $attributes set objects attributes @example ['attribute_code'=>'attribute_object'] * @return array */ public function execute(array $attributes): array diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index b29eee9a47f8b..5a00f8bfbee8a 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -506,13 +506,16 @@ protected function _getResource() protected function getCustomAttributesCodes() { if ($this->customAttributesCodes === null) { - $this->customAttributesCodes = array_keys($this->eavConfig->getEntityAttributes( - self::ENTITY, - $this - )); - - $this->customAttributesCodes = $this->filterCustomAttribute->execute($this->customAttributesCodes); - $this->customAttributesCodes = array_diff($this->customAttributesCodes, ProductInterface::ATTRIBUTES); + $this->customAttributesCodes = array_diff( + array_keys( + $this->filterCustomAttribute->execute( + $this->eavConfig->getEntityAttributes( + self::ENTITY, + $this + ) + ) + ), ProductInterface::ATTRIBUTES + ); } return $this->customAttributesCodes; From 2eb844f239c68591a6998d279103246609ef4a3d Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 11 Oct 2018 18:19:10 +0300 Subject: [PATCH 0505/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Model/Product/Image.php | 6 +++--- .../view/adminhtml/templates/browser/content/uploader.phtml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index adde1263e1bf9..a0be36c5a327c 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -45,7 +45,7 @@ class Image extends \Magento\Framework\Model\AbstractModel * Default quality value (for JPEG images only). * * @var int - * @deprecated + * @deprecated use config setting with path self::XML_PATH_JPEG_QUALITY */ protected $_quality = null; @@ -220,7 +220,7 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param SerializerInterface $serializer * @param ParamsBuilder $paramsBuilder * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.UnusedLocalVariable)1 + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function __construct( \Magento\Framework\Model\Context $context, @@ -305,7 +305,7 @@ public function getHeight() * * @param int $quality * @return $this - * @deprecated + * @deprecated use config setting with path self::XML_PATH_JPEG_QUALITY */ public function setQuality($quality) { diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 54f42bb4ecc1f..df0a74c48ac23 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,7 +17,7 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } -$resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) +$resizeConfig = $block->getImageUploadConfigData()->getIsResizeEnabled() ? "{action: 'resize', maxWidth: " . $block->getImageUploadMaxWidth() . ", maxHeight: " From 0eec64f51cd9ea437fb75dbf66adccffb5bccac1 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 11 Oct 2018 18:33:15 +0300 Subject: [PATCH 0506/1415] MAGETWO-94438: AdminAddImageToWYSIWYGProductTest is unstable - Stabilize test --- .../Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml index 37c0eb6ea1253..03f3e93bb30ec 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -47,9 +47,9 @@ <conditionalClick selector="{{ProductDescriptionWYSIWYGToolbarSection.WysiwygArrow}}" dependentSelector="{{ProductDescriptionWYSIWYGToolbarSection.checkIfWysiwygArrowExpand}}" stepKey="clickWysiwygArrowIfClosed" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder1" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder1" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading4" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading4" timeout="45"/> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage1"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" timeout="30"/> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage1" /> <seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.imageSelected(ImageUpload1.value)}}" stepKey="seeImageSelected1" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn1"/> @@ -60,7 +60,7 @@ <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="dontSeeImage1" /> <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn2" /> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage2"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" timeout="45"/> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage2" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn1" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.ImageDescription}}" stepKey="waitForImageDescriptionButton1" /> @@ -72,10 +72,12 @@ <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse2" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.CancelBtn}}" stepKey="waitForCancelButton2"/> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn2" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading13" timeout="30"/> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn2" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading14" timeout="40"/> <dontSeeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn3" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage3"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" timeout="45"/> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage3" /> <waitForElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="waitForDeletebtn" /> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn2"/> @@ -84,7 +86,7 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete2" /> <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn4" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage4"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" timeout="45"/> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading11" /> From fc5c571ab6e635a17ea7c5a4d4a0209c56ec9366 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Thu, 11 Oct 2018 10:47:21 -0500 Subject: [PATCH 0507/1415] MAGETWO-95111: Added MFTF test added for this bug fix --- .../Mftf/Section/AdminStoresGridSection.xml | 1 + .../Test/AdminCreateStoreViewCodeTest.xml | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml index 04cbeb5bc596e..6b2c38502923a 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml @@ -12,6 +12,7 @@ <element name="createWebsite" type="button" selector="#add"/> </section> <section name="AdminStoresGridSection"> + <element name="loadingMask" type="text" selector=".admin__data-grid-loading-mask[data-component*='notification_area.notification_area.columns']"/> <element name="storeGrpFilterTextField" type="input" selector="#storeGrid_filter_group_title"/> <element name="websiteFilterTextField" type="input" selector="#storeGrid_filter_website_title"/> <element name="storeFilterTextField" type="input" selector="#storeGrid_filter_store_title"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml new file mode 100644 index 0000000000000..473b0c1663033 --- /dev/null +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateStoreViewCodeTest"> + <annotations> + <features value="Store"/> + <stories value="Create a store view new in admin"/> + <title value="Admin should be able to create a store view new"/> + <description value="Admin should be able to create a store view new"/> + <group value="storeViewGroup"/> + <severity value="AVERAGE"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + </before> + <amOnPage url="{{AdminSystemStoreViewPage.url}}" stepKey="navigateToNewStoreView"/> + <waitForPageLoad stepKey="waitForPageLoad1" /> + <!--Create Store View and and check for loading-mask!--> + <fillField selector="{{AdminNewStoreSection.storeNameTextField}}" userInput="{{customStore.name}}" stepKey="enterStoreViewName" /> + <fillField selector="{{AdminNewStoreSection.storeCodeTextField}}" userInput="{{customStore.code}}" stepKey="enterStoreViewCode" /> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad time="60" stepKey="wait1"/> + <waitForElementNotVisible selector="{{AdminStoresGridSection.loadingMask}}" stepKey="waitForLoadingMaskToLoad"/> + <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> + <waitForPageLoad time="60" stepKey="wait2"/> + <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + </test> +</tests> From 87dce54dc6d75dd203af95a5fe87a1baad236957 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 11:02:38 -0500 Subject: [PATCH 0508/1415] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Removed all shipping addresses in reset plugin to avoid logical errors --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index 3791b28917e97..a63072f5a3de7 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -27,6 +27,11 @@ public function afterRemoveItem(Quote $quote, Quote $result, $itemId): Quote if (empty($result->getAllVisibleItems())) { foreach ($result->getAllAddresses() as $address) { $result->removeAddress($address->getId()); + + $extensionAttributes = $result->getExtensionAttributes(); + if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $extensionAttributes->setShippingAssignments([]); + } } } From 0ec20f5a77fd11fc61d6a0d297bbd6ab09296a78 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 11:16:23 -0500 Subject: [PATCH 0509/1415] MAGETWO-95588: Swatches on category page does not work - CR feedback --- .../Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml index dd497cca2c2de..0e294153e881e 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml @@ -23,7 +23,8 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!-- Begin creating a new product attribute of type "Image Swatch" --> From a19990e4dd46b264d376b485bb28cdfedc2e3e20 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Oct 2018 11:17:50 -0500 Subject: [PATCH 0510/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index 5ed6ba0f79f65..1ef7403e94ce1 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -199,7 +199,7 @@ <stories value="Checkout flow if payment solutions are not available"/> <title value="Checkout via Customer Checkout with restricted countries for payment"/> <description value="Should be able to place an order as a Customer with restricted countries for payment."/> - <severity value="CRITICAL"/> + <severity value="MAJOR"/> <testCaseId value="MAGETWO-42653"/> <group value="checkout"/> </annotations> @@ -213,7 +213,7 @@ <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> From 6cf27d0cfe0df6a108ec182da292eb110951c27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Corr=C3=AAa=20Gomes?= <rafaelcg_stz@hotmail.com> Date: Fri, 5 Oct 2018 10:40:07 -0400 Subject: [PATCH 0511/1415] Admin > Footer > Aligning Proportionally --- .../backend/Magento_Backend/web/css/source/module/_footer.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less index 2958708e51deb..0244775fad0b6 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/_footer.less @@ -25,7 +25,7 @@ border-top: @footer__border-width solid @footer__border-color; color: @footer__color; margin-top: auto; - padding: 2.6rem 2rem 6rem 3rem; + padding: 2.6rem 3rem 6rem; a { .lib-link( From de9603e744996a3bd2de090ddb1613e597edec0e Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Thu, 11 Oct 2018 13:27:58 -0500 Subject: [PATCH 0512/1415] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT --- .../Test/Mftf/Section/AdminCartPriceRulesFormSection.xml | 2 ++ .../SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml | 1 + .../Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml | 1 + .../Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml | 1 + .../Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml | 1 + .../Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml | 1 + .../Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml | 1 + .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml | 1 + .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml | 1 + 12 files changed, 13 insertions(+) diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index d8253505c42e4..54f7aa97053cb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -21,6 +21,8 @@ <element name="coupon" type="select" selector="select[name='coupon_type']"/> <element name="couponCode" type="input" selector="input[name='coupon_code']"/> <element name="useAutoGeneration" type="checkbox" selector="input[name='use_auto_generation']"/> + <element name="fromDate" type="input" selector="input[name='from_date']"/> + <element name="toDate" type="input" selector="input[name='to_date']"/> <element name="userPerCoupon" type="input" selector="//input[@name='uses_per_coupon']"/> <element name="userPerCustomer" type="input" selector="//input[@name='uses_per_customer']"/> <element name="priority" type="input" selector="//*[@name='sort_order']"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml index c69fa97efc034..51062da6f2efe 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Buy X get Y free (discount amount is Y)" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="1" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 49233cb4b42f5..44145f9290457 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -42,6 +42,7 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index c1aeebfca520e..a9083cb320ccb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -42,6 +42,7 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <checkOption selector="{{AdminCartPriceRulesFormSection.useAutoGeneration}}" stepKey="tickAutoGeneration"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml index 30aa26b26ed39..9d95b01b2f81d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml index 7ac69f82f79da..1adf2d22be4db 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="19.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml index eb04ce04f0718..42d84f13b9acf 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="50" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index ca897bffe8b79..e8b8c6cd9e683 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index 83854c4a767ca..ae7d0eed739ff 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml index 60a19074317fc..c43aaf8d3c97c 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index f98f7b408436f..4e1944bed9b42 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml index 6567beba198eb..8fb27a9dd1ef3 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> From 778be5815ab0a55825cb25d246b61e79ea581dab Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Thu, 11 Oct 2018 14:06:43 -0500 Subject: [PATCH 0513/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted - Deprecated all classes/interfaces in Magento\Framework\Search\Adapter\Mysql and added missing descriptions to avoid static tests failures. - Deprecated MySQL search related unit tests (for easier removal in the future) - Removed deprecation of Magento\CatalogSearch\Model\ResourceModel\FulltextCollection (it should be kept and refactored) --- .../Model/ResourceModel/Fulltext/Collection.php | 6 +++--- .../Data/MySQLSearchDeprecationNotification.php | 6 ++++++ .../DataProvider/QueryBuilderTest.php | 2 ++ .../Mysql/Aggregation/DataProviderTest.php | 3 +++ .../Adapter/Mysql/Dynamic/DataProviderTest.php | 3 ++- .../Model/Adapter/Mysql/Field/ResolverTest.php | 3 +++ .../Adapter/Mysql/Filter/AliasResolverTest.php | 4 ++++ .../Adapter/Mysql/Filter/PreprocessorTest.php | 2 ++ .../ResourceModel/Advanced/CollectionTest.php | 2 ++ .../Unit/Model/ResourceModel/BaseCollection.php | 3 +++ .../BaseSelectStrategy/StrategyMapperTest.php | 4 ++++ .../FilterMapper/ExclusionStrategyTest.php | 2 ++ .../Search/FilterMapper/FilterContextTest.php | 4 ++++ .../FilterMapper/TermDropdownStrategyTest.php | 3 +++ .../Test/Unit/Model/Search/IndexBuilderTest.php | 2 ++ .../Test/Unit/Model/Search/TableMapperTest.php | 3 +++ .../Test/Unit/Plugin/EnableEavIndexerTest.php | 4 ++++ .../Framework/Search/Adapter/Mysql/Adapter.php | 4 ++++ .../Search/Adapter/Mysql/Aggregation/Builder.php | 14 +++++++++++--- .../Aggregation/Builder/BucketInterface.php | 6 +++++- .../Mysql/Aggregation/Builder/Container.php | 8 ++++++++ .../Mysql/Aggregation/Builder/Dynamic.php | 8 +++++++- .../Mysql/Aggregation/Builder/Metrics.php | 6 ++++++ .../Adapter/Mysql/Aggregation/Builder/Range.php | 10 +++++++++- .../Adapter/Mysql/Aggregation/Builder/Term.php | 8 +++++++- .../Mysql/Aggregation/DataProviderContainer.php | 6 ++++++ .../Mysql/Aggregation/DataProviderInterface.php | 4 +++- .../Adapter/Mysql/Aggregation/Interval.php | 14 +++++++++++--- .../Search/Adapter/Mysql/AggregationFactory.php | 3 +++ .../Search/Adapter/Mysql/ConditionManager.php | 10 ++++++++++ .../Search/Adapter/Mysql/DocumentFactory.php | 3 +++ .../Search/Adapter/Mysql/Field/Field.php | 11 +++++++++++ .../Search/Adapter/Mysql/Field/FieldFactory.php | 4 ++++ .../Adapter/Mysql/Field/FieldInterface.php | 13 +++++++++---- .../Search/Adapter/Mysql/Field/Resolver.php | 5 ++++- .../Adapter/Mysql/Field/ResolverInterface.php | 6 ++++-- .../Search/Adapter/Mysql/Filter/Builder.php | 11 ++++++++++- .../Mysql/Filter/Builder/FilterInterface.php | 6 +++++- .../Adapter/Mysql/Filter/Builder/Range.php | 16 +++++++++++++++- .../Search/Adapter/Mysql/Filter/Builder/Term.php | 10 +++++++++- .../Adapter/Mysql/Filter/Builder/Wildcard.php | 8 +++++++- .../Adapter/Mysql/Filter/BuilderInterface.php | 6 +++++- .../Search/Adapter/Mysql/Filter/Preprocessor.php | 5 ++++- .../Mysql/Filter/PreprocessorInterface.php | 6 +++++- .../Adapter/Mysql/IndexBuilderInterface.php | 3 +++ .../Framework/Search/Adapter/Mysql/Mapper.php | 11 +++++++++++ .../Search/Adapter/Mysql/Query/Builder/Match.php | 8 +++++++- .../Mysql/Query/Builder/QueryInterface.php | 6 +++++- .../Adapter/Mysql/Query/MatchContainer.php | 10 ++++++++++ .../Mysql/Query/MatchContainerFactory.php | 3 +++ .../Adapter/Mysql/Query/QueryContainer.php | 10 ++++++++++ .../Mysql/Query/QueryContainerFactory.php | 3 +++ .../Search/Adapter/Mysql/ResponseFactory.php | 3 +++ .../Search/Adapter/Mysql/ScoreBuilder.php | 2 ++ .../Search/Adapter/Mysql/ScoreBuilderFactory.php | 3 +++ .../Search/Adapter/Mysql/TemporaryStorage.php | 10 ++++++++++ .../Adapter/Mysql/TemporaryStorageFactory.php | 2 ++ 57 files changed, 309 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 916bfdd602029..79d03b6fad2ca 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -20,12 +20,12 @@ /** * Fulltext Collection - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * This collection should be refactored to not have dependencies on MySQL-specific implementation. * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php b/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php index a58ee2bcb184d..d3c5aa5aaa6f5 100644 --- a/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php +++ b/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php @@ -7,6 +7,12 @@ namespace Magento\CatalogSearch\Setup\Patch\Data; +/** + * Implementation of the notification about MySQL search being deprecated. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class MySQLSearchDeprecationNotification implements \Magento\Framework\Setup\Patch\DataPatchInterface { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php index 72379c3819dea..949554506d5b0 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php @@ -20,6 +20,8 @@ * Test for Magento\CatalogSearch\Model\Adapter\Mysql\Aggregation\DataProvider\QueryBuilder. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class QueryBuilderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php index 8eeceba8209bf..85b1b136e78d2 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php @@ -23,6 +23,9 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @deprecated + * @see \Magento\ElasticSearch */ class DataProviderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php index 1186dd6936cc6..b064eec3338e9 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php @@ -19,8 +19,9 @@ use Magento\Store\Model\StoreManager; /** - * Class DataProviderTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class DataProviderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php index ca19e5e995c81..1e609cdeac28f 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php @@ -9,6 +9,9 @@ /** * Unit tests for Magento\CatalogSearch\Model\Adapter\Mysql\Field\Resolver class. + * + * @deprecated + * @see \Magento\ElasticSearch */ class ResolverTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php index 697fab6507934..1690d9f39360f 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php @@ -9,6 +9,10 @@ use Magento\CatalogSearch\Model\Search\RequestGenerator; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class AliasResolverTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php index 01108358da2e0..7e3de7534e8c4 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php @@ -15,6 +15,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class PreprocessorTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php index 21d67bdf53c56..b65a0d6ca47a0 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php @@ -13,6 +13,8 @@ * Tests Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class CollectionTest extends BaseCollection { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php index e99d75c25f5cd..9ea103e23d2a7 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php @@ -9,6 +9,9 @@ * Base class for Collection tests. * * Contains helper methods to get commonly used mocks used for collection tests. + * + * @deprecated + * @see \Magento\ElasticSearch **/ class BaseCollection extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php index 5fa5b0333c6ba..b168e72811760 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php @@ -11,6 +11,10 @@ use \Magento\CatalogSearch\Model\Search\BaseSelectStrategy\StrategyMapper; use \Magento\CatalogSearch\Model\Search\SelectContainer\SelectContainer; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class StrategyMapperTest extends \PHPUnit\Framework\TestCase { /** @var BaseSelectAttributesSearchStrategy|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php index 09591532f9f06..e693807760ea5 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php @@ -17,6 +17,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class ExclusionStrategyTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php index e16f23ca09d2c..12ce0d63ac685 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php @@ -16,6 +16,10 @@ use Magento\Framework\Search\Request\FilterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class FilterContextTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php index 8771c92039f4d..e064f46655d91 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php @@ -18,6 +18,9 @@ /** * Class TermDropdownStrategyTest. * Unit test for \Magento\CatalogSearch\Model\Search\FilterMapper\TermDropdownStrategy. + * + * @deprecated + * @see \Magento\ElasticSearch */ class TermDropdownStrategyTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php index da7cfa1ea9821..b066c118ef783 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php @@ -27,6 +27,8 @@ * Test for \Magento\CatalogSearch\Model\Search\IndexBuilder * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class IndexBuilderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php index cfddc07bceecc..db46755261534 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -18,7 +18,10 @@ /** * Test for \Magento\CatalogSearch\Model\Search\TableMapper + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class TableMapperTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php index 0eac2e3309aec..b20fdde7c5216 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php @@ -9,6 +9,10 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class EnableEavIndexerTest extends \PHPUnit\Framework\TestCase { /** diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php index 11bd746eb71e5..897b67d8d46ec 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php @@ -14,6 +14,8 @@ /** * MySQL Search Adapter * + * @deprecated + * @see \Magento\ElasticSearch * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Adapter implements AdapterInterface @@ -104,6 +106,8 @@ private function getDocuments(Table $table) } /** + * Get connection. + * * @return false|\Magento\Framework\DB\Adapter\AdapterInterface */ private function getConnection() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php index 47d991274b9e0..4a5802dd44e04 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php @@ -15,6 +15,10 @@ use Magento\Framework\Search\RequestInterface; /** + * MySQL search aggregation builder. + * + * @deprecated + * @see \Magento\ElasticSearch * @api */ class Builder @@ -66,6 +70,8 @@ public function __construct( } /** + * Build aggregations. + * * @param RequestInterface $request * @param Table $documentsTable * @param array $documents @@ -77,6 +83,8 @@ public function build(RequestInterface $request, Table $documentsTable, array $d } /** + * Process aggregations. + * * @param RequestInterface $request * @param Table $documentsTable * @param array $documents @@ -102,7 +110,7 @@ private function processAggregations(RequestInterface $request, Table $documents } /** - * Extract document ids + * Extract document ids. * * @param array $documents * @return array @@ -113,7 +121,7 @@ private function extractDocumentIds(array $documents) } /** - * Get document ids + * Get document ids. * * @param Table $documentsTable * @return array @@ -128,7 +136,7 @@ private function getDocumentIds(Table $documentsTable) } /** - * Get Connection + * Get Connection. * * @return AdapterInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php index 90220676e0068..4fa2474d2258e 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php @@ -11,12 +11,16 @@ use Magento\Framework\Search\Request\Dimension; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder\BucketInterface + * MySQL search aggregation bucket builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface BucketInterface { /** + * Build bucket. + * * @param DataProviderInterface $dataProvider * @param Dimension[] $dimensions * @param RequestBucketInterface $bucket diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php index cba29ad6287d3..844cfc9f8741d 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php @@ -5,6 +5,12 @@ */ namespace Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder; +/** + * MySQL search aggregation container builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Container { /** @@ -21,6 +27,8 @@ public function __construct(array $buckets) } /** + * Get bucket by type. + * * @param string $bucketType * @return BucketInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php index 481b2252dbf69..46828ab7a8c73 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php @@ -12,6 +12,12 @@ use Magento\Framework\Search\Request\Aggregation\DynamicBucket; use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search dynamic aggregation builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Dynamic implements BucketInterface { /** @@ -37,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php index 840f94622183a..e4cdb04052ef2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php @@ -7,6 +7,12 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search aggregation metrics builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Metrics { /** diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php index 29fc6806b50e7..aced57c100130 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php @@ -14,6 +14,12 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; use Magento\Framework\Translate\AdapterInterface; +/** + * MySQL search aggregation range builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Range implements BucketInterface { const GREATER_THAN = '>='; @@ -46,7 +52,7 @@ public function __construct(Metrics $metricsBuilder, ResourceConnection $resourc } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, @@ -70,6 +76,8 @@ public function build( } /** + * Generate case. + * * @param Select $select * @param AggregationRange[] $ranges * @return Select diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php index 78ff7b04fd39c..547526be43ccd 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php @@ -9,6 +9,12 @@ use Magento\Framework\Search\Adapter\Mysql\Aggregation\DataProviderInterface; use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search aggregation term builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Term implements BucketInterface { /** @@ -25,7 +31,7 @@ public function __construct(Metrics $metricsBuilder) } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php index 6a817bcbddf82..565b5eeef3351 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php @@ -6,6 +6,10 @@ namespace Magento\Framework\Search\Adapter\Mysql\Aggregation; /** + * MySQL search data provider container. + * + * @deprecated + * @see \Magento\ElasticSearch * @api */ class DataProviderContainer @@ -24,6 +28,8 @@ public function __construct(array $dataProviders) } /** + * Get data provider by index name. + * * @param string $indexName * @return DataProviderInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php index b18269335bc6f..c251265c694d2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php @@ -11,8 +11,10 @@ use Magento\Framework\Search\Request\Dimension; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Aggregation\DataProviderInterface + * MySQL search data provider. * + * @deprecated + * @see \Magento\ElasticSearch */ interface DataProviderInterface { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php index ed5640d42274f..ba41a535f45c9 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php @@ -8,6 +8,12 @@ use Magento\Framework\DB\Select; use Magento\Framework\Search\Dynamic\IntervalInterface; +/** + * MySQL search aggregation interval. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Interval implements IntervalInterface { /** @@ -41,7 +47,7 @@ private function getValueFiled() } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function load($limit, $offset = null, $lower = null, $upper = null) @@ -64,7 +70,7 @@ public function load($limit, $offset = null, $lower = null, $upper = null) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function loadPrevious($data, $index, $lower = null) @@ -86,7 +92,7 @@ public function loadPrevious($data, $index, $lower = null) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function loadNext($data, $rightIndex, $upper = null) @@ -124,6 +130,8 @@ public function loadNext($data, $rightIndex, $upper = null) } /** + * Convert array values to float. + * * @param array $prices * @return array */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php index 4d255705bf7df..756d9edc6fbe1 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php @@ -7,6 +7,9 @@ /** * Aggregation Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class AggregationFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php index 41d6b14b6a477..413af71814198 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php @@ -9,7 +9,11 @@ use Magento\Framework\DB\Adapter\AdapterInterface; /** + * MySQL search condition manager + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class ConditionManager { @@ -30,6 +34,8 @@ public function __construct(ResourceConnection $resource) } /** + * Wrap query with parentheces. + * * @param string $query * @return string */ @@ -41,6 +47,8 @@ public function wrapBrackets($query) } /** + * Combine multiple queries. + * * @param string[] $queries * @param string $unionOperator * @return string @@ -54,6 +62,8 @@ public function combineQueries(array $queries, $unionOperator) } /** + * Generate query condition. + * * @param string $field * @param string $operator * @param mixed $value diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php index 3ca0e94852a5e..4e8854fad353a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php @@ -13,7 +13,10 @@ /** * Document Factory + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class DocumentFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php index 72495e68a26ff..0a340e7f76dc0 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php @@ -6,6 +6,11 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; +/** + * @inheritdoc + * @deprecated + * @see \Magento\ElasticSearch + */ class Field implements FieldInterface { /** @@ -36,6 +41,8 @@ public function __construct($column, $attributeId = null, $type = self::TYPE_FUL } /** + * Get column. + * * @return string */ public function getColumn() @@ -44,6 +51,8 @@ public function getColumn() } /** + * Get attribute ID. + * * @return int|null */ public function getAttributeId() @@ -52,6 +61,8 @@ public function getAttributeId() } /** + * Get type. + * * @return int */ public function getType() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php index 9a3c55965740e..066d1832aefbf 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php @@ -7,7 +7,11 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** + * MySQL search field factory. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class FieldFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php index 5f4e0027a8508..7dc74f39709f9 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php @@ -7,8 +7,10 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Field\FieldInterface + * MySQL search field. * + * @deprecated + * @see \Magento\ElasticSearch */ interface FieldInterface { @@ -16,19 +18,22 @@ interface FieldInterface const TYPE_FULLTEXT = 2; /** - * Get type of index + * Get type of index. + * * @return int */ public function getType(); /** - * Get ID of attribute + * Get ID of attribute. + * * @return int */ public function getAttributeId(); /** - * Get field name + * Get field nam. + * * @return string */ public function getColumn(); diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php index 5146177783ae2..908d6ccc50746 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Search\Adapter\Mysql\Field; +/** + * @inheritdoc + */ class Resolver implements ResolverInterface { /** @@ -21,7 +24,7 @@ public function __construct(FieldFactory $fieldFactory) } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve(array $fields) { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php index f275c4f1b1c14..5455b91d73020 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php @@ -6,13 +6,15 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface + * MySQL search field resolver. * + * @deprecated + * @see \Magento\ElasticSearch */ interface ResolverInterface { /** - * Resolve field + * Resolve field. * * @param array $fields * @return FieldInterface[] diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php index 80074ffc5e2b9..ce02bef244fbb 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php @@ -15,6 +15,7 @@ use Magento\Framework\Search\Request\Query\BoolExpression; /** + * @inheritdoc * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Builder implements BuilderInterface @@ -58,7 +59,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build(RequestFilterInterface $filter, $conditionType) { @@ -66,6 +67,8 @@ public function build(RequestFilterInterface $filter, $conditionType) } /** + * Process filter. + * * @param RequestFilterInterface $filter * @param bool $isNegation * @return string @@ -87,6 +90,8 @@ private function processFilter(RequestFilterInterface $filter, $isNegation) } /** + * Process boolean filter. + * * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Bool $filter * @param bool $isNegation * @return string @@ -111,6 +116,8 @@ private function processBoolFilter(RequestFilterInterface $filter, $isNegation) } /** + * Build filters. + * * @param \Magento\Framework\Search\Request\FilterInterface[] $filters * @param string $unionOperator * @param bool $isNegation @@ -127,6 +134,8 @@ private function buildFilters(array $filters, $unionOperator, $isNegation) } /** + * Check if condition type is 'negative'. + * * @param string $conditionType * @return bool */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php index 787866a2bca38..6f8b63955a0c1 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\Builder\FilterInterface + * MySQL search filter builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface FilterInterface { /** + * Build filter. + * * @param RequestFilterInterface $filter * @param bool $isNegation * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php index d4ee9542c5934..d14bfdcb548d3 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php @@ -9,6 +9,12 @@ use Magento\Framework\Search\Request\Filter\Range as RangeFilterRequest; use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; +/** + * Range filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Range implements FilterInterface { const CONDITION_PART_GREATER_THAN = '>='; @@ -31,7 +37,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( RequestFilterInterface $filter, @@ -48,6 +54,8 @@ public function buildFilter( } /** + * Get left condition filter part. + * * @param RequestFilterInterface|RangeFilterRequest $filter * @param bool $isNegation * @return string @@ -62,6 +70,8 @@ private function getLeftConditionPart(RequestFilterInterface $filter, $isNegatio } /** + * Get right condition filter part. + * * @param RequestFilterInterface|RangeFilterRequest $filter * @param bool $isNegation * @return string @@ -76,6 +86,8 @@ private function getRightConditionPart(RequestFilterInterface $filter, $isNegati } /** + * Get filter part. + * * @param string $field * @param string $operator * @param string $value @@ -89,6 +101,8 @@ private function getPart($field, $operator, $value) } /** + * Get condition union operator. + * * @param bool $isNegation * @return string */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php index 3ac755de2b8a3..c89ef50f3cb35 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php @@ -8,6 +8,12 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; +/** + * Term filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Term implements FilterInterface { const CONDITION_OPERATOR_EQUALS = '='; @@ -30,7 +36,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( RequestFilterInterface $filter, @@ -46,6 +52,8 @@ public function buildFilter( } /** + * Get condition operator. + * * @param string|array $value * @param bool $isNegation * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php index 308d1d564301d..9a2776ac20b2c 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php @@ -7,6 +7,12 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; +/** + * Wildcard filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Wildcard implements FilterInterface { const CONDITION_LIKE = 'LIKE'; @@ -27,7 +33,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( \Magento\Framework\Search\Request\FilterInterface $filter, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php index ec3b88ad24507..3da989333d668 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\BuilderInterface + * MySQL search filter builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface BuilderInterface { /** + * Buil filter. + * * @param RequestFilterInterface $filter * @param string $conditionType * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php index a8bb8e255f2cb..32d134cfe8d6d 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php @@ -8,6 +8,9 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Request\FilterInterface; +/** + * @inheritdoc + */ class Preprocessor implements PreprocessorInterface { /** @@ -24,7 +27,7 @@ public function __construct(ConditionManager $conditionManager) } /** - * {@inheritdoc} + * @inheritdoc */ public function process(FilterInterface $filter, $isNegation, $query) { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php index 430b775337b7f..eb0bbc6f3b563 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface + * MySQL search filter pre-processor. * + * @deprecated + * @see \Magento\ElasticSearch */ interface PreprocessorInterface { /** + * Process filter. + * * @param FilterInterface $filter * @param bool $isNegation * @param string $query diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php index 73c20406f35df..fbd35455c2294 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php @@ -10,6 +10,9 @@ /** * Build base Query for Index + * + * @deprecated + * @see \Magento\ElasticSearch */ interface IndexBuilderInterface { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php index fb4ff5d298c12..e97a6690dbcc2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php @@ -22,8 +22,11 @@ /** * Mapper class. Maps library request to specific adapter dependent query + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * @deprecated + * @see \Magento\ElasticSearch */ class Mapper { @@ -344,6 +347,8 @@ private function processFilterQuery( } /** + * Add match queries to select. + * * @param RequestInterface $request * @param QueryContainer $queryContainer * @param ScoreBuilder $scoreBuilder @@ -380,6 +385,8 @@ private function addDerivedQueries( } /** + * Get connection. + * * @return false|\Magento\Framework\DB\Adapter\AdapterInterface */ private function getConnection() @@ -388,6 +395,8 @@ private function getConnection() } /** + * Add match queries to select. + * * @param RequestInterface $request * @param Select $select * @param IndexBuilderInterface $indexBuilder @@ -424,6 +433,8 @@ private function addMatchQueries( } /** + * Join previous result to select. + * * @param Select $query * @param Table $previousResultTable * @param ScoreBuilder $scoreBuilder diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php index 8e3758817adf0..fb44e4037bcf7 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php @@ -15,7 +15,11 @@ use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; /** + * MySQL search query match. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class Match implements QueryInterface { @@ -69,7 +73,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( ScoreBuilder $scoreBuilder, @@ -113,6 +117,8 @@ public function build( } /** + * Prepare query. + * * @param string $queryValue * @param string $conditionType * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php index a2446264d48d7..6796a1f995e4f 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Adapter\Mysql\ScoreBuilder; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Query\Builder\QueryInterface + * MySQL search query builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface QueryInterface { /** + * Build query. + * * @param \Magento\Framework\Search\Adapter\Mysql\ScoreBuilder $scoreBuilder * @param \Magento\Framework\DB\Select $select * @param \Magento\Framework\Search\Request\QueryInterface $query diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php index b694cd48a07af..6ed3338c040e2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php @@ -10,6 +10,12 @@ // @codeCoverageIgnore +/** + * MySQL search query match container. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class MatchContainer { /** @@ -34,6 +40,8 @@ public function __construct(QueryInterface $request, $conditionType) } /** + * Get request. + * * @return QueryInterface */ public function getRequest() @@ -42,6 +50,8 @@ public function getRequest() } /** + * Get condition type. + * * @return string */ public function getConditionType() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php index ba103e060ae7c..cb10de7bdcbbc 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php @@ -7,6 +7,9 @@ /** * MatchContainer Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class MatchContainerFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php index be8507838e44f..9161a30f9bc51 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php @@ -9,6 +9,12 @@ use Magento\Framework\DB\Select; use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; +/** + * MySQL search query container. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class QueryContainer { const DERIVED_QUERY_PREFIX = 'derived_'; @@ -32,6 +38,8 @@ public function __construct(MatchContainerFactory $matchContainerFactory) } /** + * Add query to select. + * * @param Select $select * @param RequestQueryInterface $query * @param string $conditionType @@ -54,6 +62,8 @@ public function addMatchQuery( } /** + * Get queries. + * * @return MatchContainer[] */ public function getMatchQueries() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php index 70fefec13dd88..59ee4bb045b2a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php @@ -7,6 +7,9 @@ /** * MatchContainer Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class QueryContainerFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php index 8a269d8d95bc2..776dab93c2dcd 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php @@ -7,6 +7,9 @@ /** * Response Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class ResponseFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php index 190d3a04ed210..1cc417f891c19 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php @@ -9,6 +9,8 @@ * Class for generating sql condition for calculating store manager * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class ScoreBuilder { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php index 4a7612fcc3042..70aa749fd859f 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php @@ -7,6 +7,9 @@ /** * ScoreBuilder Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class ScoreBuilderFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php index dcb977bfa2ae8..60ee2d5706067 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php @@ -13,7 +13,11 @@ use Magento\Framework\DB\Select; /** + * MySQL search temporary storage. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryStorage { @@ -100,6 +104,8 @@ private function populateTemporaryTable(Table $table, $data) } /** + * Store select results in temporary table. + * * @param Select $select * @return Table * @throws \Zend_Db_Exception @@ -112,6 +118,8 @@ public function storeDocumentsFromSelect(Select $select) } /** + * Get connection. + * * @return false|AdapterInterface */ private function getConnection() @@ -120,6 +128,8 @@ private function getConnection() } /** + * Create temporary table for search select results. + * * @return Table * @throws \Zend_Db_Exception */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php index 4a282faf317ce..208f6b39b9eb4 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php @@ -12,6 +12,8 @@ * * @codeCoverageIgnore * @api + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryStorageFactory { From 0fc837e33067e6337893d9478669c657f4d42e42 Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Thu, 11 Oct 2018 21:09:35 +0200 Subject: [PATCH 0514/1415] Fixed typo from heght to height for image validation rule --- app/code/Magento/Customer/Model/Metadata/Form/Image.php | 2 +- .../Customer/Test/Unit/Model/Metadata/Form/ImageTest.php | 2 +- app/code/Magento/Eav/Model/Attribute/Data/Image.php | 6 +++--- .../Eav/Test/Unit/Model/Attribute/Data/ImageTest.php | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Image.php b/app/code/Magento/Customer/Model/Metadata/Form/Image.php index 2104f941a6bc2..692d08aae8d78 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Image.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Image.php @@ -133,7 +133,7 @@ protected function _validateByRules($value) $maxImageHeight = ArrayObjectSearch::getArrayElementByName( $rules, - 'max_image_heght' + 'max_image_height' ); if ($maxImageHeight !== null) { if ($maxImageHeight < $imageProp[1]) { diff --git a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/ImageTest.php b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/ImageTest.php index 0278e2b2d791d..31d2a31ceae4c 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/ImageTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/ImageTest.php @@ -259,7 +259,7 @@ public function testValidateMaxImageHeight() )->getMockForAbstractClass(); $validationRuleMock->expects($this->any()) ->method('getName') - ->willReturn('max_image_heght'); + ->willReturn('max_image_height'); $validationRuleMock->expects($this->any()) ->method('getValue') ->willReturn($maxImageHeight); diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Image.php b/app/code/Magento/Eav/Model/Attribute/Data/Image.php index d04b7e9b940cf..0020256dfb148 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Image.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Image.php @@ -54,9 +54,9 @@ protected function _validateByRules($value) $errors[] = __('"%1" width exceeds allowed value of %2 px.', $label, $r); } } - if (!empty($rules['max_image_heght'])) { - if ($rules['max_image_heght'] < $imageProp[1]) { - $r = $rules['max_image_heght']; + if (!empty($rules['max_image_height'])) { + if ($rules['max_image_height'] < $imageProp[1]) { + $r = $rules['max_image_height']; $errors[] = __('"%1" height exceeds allowed value of %2 px.', $label, $r); } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/ImageTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/ImageTest.php index c89f581daac82..2df87c39868a1 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/ImageTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/ImageTest.php @@ -143,7 +143,7 @@ public function validateValueDataProvider() 'originalValue' => 'value', 'isRequired' => true, 'isAjaxRequest' => false, - 'rules' => ['max_image_heght' => 2], + 'rules' => ['max_image_height' => 2], 'expectedResult' => ['"Label" height exceeds allowed value of 2 px.'] ], [ @@ -151,7 +151,7 @@ public function validateValueDataProvider() 'originalValue' => 'value', 'isRequired' => true, 'isAjaxRequest' => false, - 'rules' => ['max_image_heght' => 2000], + 'rules' => ['max_image_height' => 2000], 'expectedResult' => true ], [ @@ -159,7 +159,7 @@ public function validateValueDataProvider() 'originalValue' => 'value', 'isRequired' => true, 'isAjaxRequest' => false, - 'rules' => ['max_image_heght' => 2, 'max_image_width' => 2], + 'rules' => ['max_image_height' => 2, 'max_image_width' => 2], 'expectedResult' => [ '"Label" width exceeds allowed value of 2 px.', '"Label" height exceeds allowed value of 2 px.', From 58c13d6ffab80a2fcca35b151d60f2ca6577c80a Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 14:43:45 -0500 Subject: [PATCH 0515/1415] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Added test assertion for bugfix --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 9 ++++----- .../Plugin/Model/Quote/ResetQuoteAddressesTest.php | 6 ++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index a63072f5a3de7..4f05279350a7c 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -27,11 +27,10 @@ public function afterRemoveItem(Quote $quote, Quote $result, $itemId): Quote if (empty($result->getAllVisibleItems())) { foreach ($result->getAllAddresses() as $address) { $result->removeAddress($address->getId()); - - $extensionAttributes = $result->getExtensionAttributes(); - if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { - $extensionAttributes->setShippingAssignments([]); - } + } + $extensionAttributes = $result->getExtensionAttributes(); + if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $extensionAttributes->setShippingAssignments([]); } } diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php index e533dbfa0c879..994076badddae 100644 --- a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php +++ b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php @@ -52,9 +52,15 @@ public function testAfterRemoveItem(): void $cart = Bootstrap::getObjectManager()->create(Cart::class); $activeQuote = $cart->getQuote(); + // Dummy data is still persisted here. This is sufficient to check that it is removed + $activeQuote->getExtensionAttributes()->setShippingAssignments(['test']); + $cart->removeItem($activeQuote->getAllVisibleItems()[0]->getId()); $cart->save(); + // Check that the shipping assignments were also unset + $this->assertEmpty($activeQuote->getExtensionAttributes()->getShippingAssignments()); + /** @var Quote $quote */ $quote = Bootstrap::getObjectManager()->create(Quote::class); $quote->load('test_order_with_virtual_product', 'reserved_order_id'); From c19c00b1385176502ff4961503f6d8fb480f6907 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 11 Oct 2018 15:17:28 -0500 Subject: [PATCH 0516/1415] MAGETWO-95234: Change regular expression --- app/code/Magento/Sales/Helper/Admin.php | 19 ++++++++-- lib/internal/Magento/Framework/Escaper.php | 42 ++++++++++++++++++---- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Helper/Admin.php b/app/code/Magento/Sales/Helper/Admin.php index 45a6dd1252ba3..6b38f0046a983 100644 --- a/app/code/Magento/Sales/Helper/Admin.php +++ b/app/code/Magento/Sales/Helper/Admin.php @@ -3,8 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Helper; +/** + * Sales admin helper. + */ class Admin extends \Magento\Framework\App\Helper\AbstractHelper { /** @@ -148,11 +153,19 @@ public function escapeHtmlWithLinks($data, $allowedTags = null) $links = []; $i = 1; $data = str_replace('%', '%%', $data); - $regexp = "/<a\s[^>]*href\s*?=\s*?([\"\']??)([^\" >]*?)\\1[^>]*>(.*)<\/a>/siU"; + $regexp = "#(?J)<a" + ."(?:(?:\s+(?:(?:href\s*=\s*(['\"])(?<link>.*?)\\1\s*)|(?:\S+\s*=\s*(['\"])(.*?)\\3)\s*)*)|>)" + .">?(?:(?:(?<text>.*?)(?:<\/a\s*>?|(?=<\w))|(?<text>.*)))#si"; while (preg_match($regexp, $data, $matches)) { + $text = ''; + $url = ''; //Revert the sprintf escaping - $url = str_replace('%%', '%', $matches[2]); - $text = str_replace('%%', '%', $matches[3]); + if (!empty($matches['link'])) { + $url = str_replace('%%', '%', $matches['link']); + } + if (!empty($matches['text'])) { + $text = str_replace('%%', '%', $matches['text']); + } //Check for an valid url if ($url) { $urlScheme = strtolower(parse_url($url, PHP_URL_SCHEME)); diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fec64378189eb..d0181c2651868 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework; /** @@ -32,13 +33,23 @@ class Escaper */ private $allowedAttributes = ['id', 'class', 'href', 'target', 'title', 'style']; + /** + * @var string + */ + private static $xssFiltrationPattern = + '/((javascript(\\\\x3a|:|%3A))|(data(\\\\x3a|:|%3A))|(vbscript:))|' + . '((\\\\x6A\\\\x61\\\\x76\\\\x61\\\\x73\\\\x63\\\\x72\\\\x69\\\\x70\\\\x74(\\\\x3a|:|%3A))|' + . '(\\\\x64\\\\x61\\\\x74\\\\x61(\\\\x3a|:|%3A)))/i'; + /** * @var string[] */ private $escapeAsUrlAttributes = ['href']; /** - * Escape string for HTML context. allowedTags will not be escaped, except the following: script, img, embed, + * Escape string for HTML context. + * + * AllowedTags will not be escaped, except the following: script, img, embed, * iframe, video, source, object, audio * * @param string|array $data @@ -285,7 +296,6 @@ public function escapeJsQuote($data, $quote = '\'') /** * Escape xss in urls - * Remove `javascript:`, `vbscript:`, `data:` words from url * * @param string $data * @return string @@ -293,15 +303,33 @@ public function escapeJsQuote($data, $quote = '\'') */ public function escapeXssInUrl($data) { - $pattern = '/((javascript(\\\\x3a|:|%3A))|(data(\\\\x3a|:|%3A))|(vbscript:))|' - . '((\\\\x6A\\\\x61\\\\x76\\\\x61\\\\x73\\\\x63\\\\x72\\\\x69\\\\x70\\\\x74(\\\\x3a|:|%3A))|' - . '(\\\\x64\\\\x61\\\\x74\\\\x61(\\\\x3a|:|%3A)))/i'; - $result = preg_replace($pattern, ':', $data); - return htmlspecialchars($result, ENT_COMPAT | ENT_HTML5 | ENT_HTML401, 'UTF-8', false); + return htmlspecialchars( + $this->escapeScriptIdentifiers($data), + ENT_COMPAT | ENT_HTML5 | ENT_HTML401, + 'UTF-8', + false + ); + } + + /** + * Remove `javascript:`, `vbscript:`, `data:` words from the string. + * + * @param string $data + * @return string + */ + private function escapeScriptIdentifiers(string $data): string + { + $filteredData = preg_replace(self::$xssFiltrationPattern, ':', $data) ?: ''; + if (preg_match(self::$xssFiltrationPattern, $filteredData)) { + $filteredData = $this->escapeScriptIdentifiers($filteredData); + } + + return $filteredData; } /** * Escape quotes inside html attributes + * * Use $addSlashes = false for escaping js that inside html attribute (onClick, onSubmit etc) * * @param string $data From 8574dac6e8eaef7cb0b0da7f0aca347d3e82fe02 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Thu, 11 Oct 2018 15:23:32 -0500 Subject: [PATCH 0517/1415] MQE-1303: AdminCreateCustomerTestCest test sequence failure --- .../Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml index 9dd2127fa28b2..6bde63d900c17 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml @@ -27,17 +27,17 @@ <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomers"/> <waitForPageLoad stepKey="waitForLoad1"/> <click selector="{{AdminCustomerGridMainActionsSection.addNewCustomer}}" stepKey="clickCreateCustomer"/> - <waitForElement selector="{{AdminCustomerAccountInformationSection.firstName}}" stepKey="wait1"/> <fillField userInput="{{CustomerEntityOne.firstname}}" selector="{{AdminCustomerAccountInformationSection.firstName}}" stepKey="fillFirstName"/> <fillField userInput="{{CustomerEntityOne.lastname}}" selector="{{AdminCustomerAccountInformationSection.lastName}}" stepKey="fillLastName"/> <fillField userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerAccountInformationSection.email}}" stepKey="fillEmail"/> <click selector="{{AdminCustomerMainActionsSection.saveButton}}" stepKey="saveCustomer"/> - <waitForElementNotVisible selector="div [data-role='spinner']" time="10" stepKey="waitForSpinner1"/> <seeElement selector="{{AdminCustomerMessagesSection.successMessage}}" stepKey="assertSuccessMessage"/> + <magentoCLI stepKey="reindex" command="indexer:reindex"/> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForLoad2"/> <click selector="{{AdminCustomerFiltersSection.filtersButton}}" stepKey="openFilter"/> <fillField userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerFiltersSection.emailInput}}" stepKey="filterEmail"/> <click selector="{{AdminCustomerFiltersSection.apply}}" stepKey="applyFilter"/> - <waitForElementNotVisible selector="div [data-role='spinner']" time="10" stepKey="waitForSpinner2"/> <see userInput="{{CustomerEntityOne.firstname}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertFirstName"/> <see userInput="{{CustomerEntityOne.lastname}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertLastName"/> <see userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertEmail"/> From 8ee82302d4ee9964abb8c867c5f72ca4c3969356 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Thu, 11 Oct 2018 16:01:35 -0500 Subject: [PATCH 0518/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel - fix static test failure --- .../Customer/Controller/Adminhtml/Index/ResetPassword.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 69af6f4fb1b27..3e6046b0d117f 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -9,6 +9,11 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\SecurityViolationException; +/** + * Reset password controller + * + * @package Magento\Customer\Controller\Adminhtml\Index + */ class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** From a3d1e71a08cb64ed8e33be13bf1d90d3100ba7e6 Mon Sep 17 00:00:00 2001 From: Andreas von Studnitz <avs@integer-net.de> Date: Thu, 20 Sep 2018 12:08:26 +0200 Subject: [PATCH 0519/1415] Fix type hint of @message declaration as the "setWidgetParameters" method allows arrays too --- app/code/Magento/Widget/Model/Widget/Instance.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Widget/Model/Widget/Instance.php b/app/code/Magento/Widget/Model/Widget/Instance.php index afe7ef3766f7c..1ccb75ad6611a 100644 --- a/app/code/Magento/Widget/Model/Widget/Instance.php +++ b/app/code/Magento/Widget/Model/Widget/Instance.php @@ -15,7 +15,7 @@ * @method string getTitle() * @method \Magento\Widget\Model\Widget\Instance setTitle(string $value) * @method \Magento\Widget\Model\Widget\Instance setStoreIds(string $value) - * @method \Magento\Widget\Model\Widget\Instance setWidgetParameters(string $value) + * @method \Magento\Widget\Model\Widget\Instance setWidgetParameters(string|array $value) * @method int getSortOrder() * @method \Magento\Widget\Model\Widget\Instance setSortOrder(int $value) * @method \Magento\Widget\Model\Widget\Instance setThemeId(int $value) From ce340abe9e9cfe3734f49deb97f7bd3f957fdc76 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Fri, 12 Oct 2018 09:19:00 +0300 Subject: [PATCH 0520/1415] Add unit test for ModuleService --- .../Unit/Service/V1/ModuleServiceTest.php | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php diff --git a/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php new file mode 100644 index 0000000000000..db103c0de05d5 --- /dev/null +++ b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Test\Unit\Model; + +use Magento\Backend\Service\V1\ModuleService; +use Magento\Framework\Module\ModuleListInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Module List Service Test + * + * Covers \Magento\Sales\Model\ValidatorResultMerger + */ +class ValidatorResultMergerTest extends \PHPUnit\Framework\TestCase +{ + /** + * Testable Object + * + * @var ModuleService + */ + private $moduleService; + + /** + * @var ModuleListInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $moduleListMock; + + /** + * Object Manager + * + * @var ObjectManager + */ + private $objectManager; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->moduleListMock = $this->createMock(ModuleListInterface::class); + $this->objectManager = new ObjectManager($this); + $this->moduleService = $this->objectManager->getObject( + ModuleService::class, + [ + 'moduleList' => $this->moduleListMock, + ] + ); + } + + /** + * Test getModules method + * + * @return void + */ + public function testGetModules() + { + $moduleNames = ['Magento_Backend', 'Magento_Catalog', 'Magento_Customer']; + $this->moduleListMock->expects($this->once())->method('getNames')->willReturn($moduleNames); + + $expected = $moduleNames; + $actual = $this->moduleService->getModules(); + $this->assertEquals($expected, $actual); + } +} From be0e463bff4d0fcf82a923cd14ffccd70620e86b Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Fri, 12 Oct 2018 09:20:10 +0300 Subject: [PATCH 0521/1415] Fix the class name --- .../Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php index db103c0de05d5..f86747aac1259 100644 --- a/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php +++ b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php @@ -16,7 +16,7 @@ * * Covers \Magento\Sales\Model\ValidatorResultMerger */ -class ValidatorResultMergerTest extends \PHPUnit\Framework\TestCase +class ModuleServiceTest extends \PHPUnit\Framework\TestCase { /** * Testable Object From df29676e93e1345c933927d81dbb7b80d4b25788 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Fri, 12 Oct 2018 11:34:44 +0300 Subject: [PATCH 0522/1415] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/Product.php | 66 +++++++++++++++------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 5a00f8bfbee8a..a488e306473b2 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -498,8 +498,9 @@ protected function _getResource() } /** - * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for - * product will return all product attribute codes + * Get a list of custom attribute codes that belongs to product attribute set. + * + * If attribute set not specified fors product will return all product attribute codes * * @return string[] */ @@ -514,7 +515,8 @@ protected function getCustomAttributesCodes() $this ) ) - ), ProductInterface::ATTRIBUTES + ), + ProductInterface::ATTRIBUTES ); } @@ -587,8 +589,9 @@ public function getPrice() } /** - * @codeCoverageIgnoreStart * Get visibility status + * + * @codeCoverageIgnoreStart * @see \Magento\Catalog\Model\Product\Visibility * * @return int @@ -665,6 +668,7 @@ public function getStatus() /** * Retrieve type instance of the product. + * * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType @@ -825,9 +829,10 @@ public function getStoreIds() /** * Retrieve product attributes - * if $groupId is null - retrieve all product attributes * - * @param int $groupId Retrieve attributes of the specified group + * If $groupId is null - retrieve all product attributes + * + * @param int $groupId Retrieve attributes of the specified group * @param bool $skipSuper Not used * @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -919,6 +924,7 @@ public function beforeSave() /** * Check/set if options can be affected when saving product + * * If value specified, it will be set. * * @param bool $value @@ -1039,9 +1045,11 @@ public function reindex() /** * Clear cache related with product and protect delete from not admin + * * Register indexing event before delete product * * @return \Magento\Catalog\Model\Product + * @throws \Magento\Framework\Exception\LocalizedException */ public function beforeDelete() { @@ -1548,12 +1556,12 @@ public function hasGalleryAttribute() /** * Add image to media gallery * - * @param string $file file path of image in file system - * @param string|array $mediaAttribute code of attribute with type 'media_image', - * leave blank if image should be only in gallery - * @param boolean $move if true, it will move source file - * @param boolean $exclude mark image as disabled in product page view + * @param string $file file path of image in file system + * @param string|array $mediaAttribute code of type 'media_image', leave blank if image should be only in gallery + * @param boolean $move if true, it will move source file + * @param boolean $exclude mark image as disabled in product page view * @return \Magento\Catalog\Model\Product + * @throws \Magento\Framework\Exception\LocalizedException */ public function addImageToMediaGallery($file, $mediaAttribute = null, $move = false, $exclude = true) { @@ -1714,7 +1722,6 @@ public function getIsSalable() /** * Check is a virtual product - * Data helper wrapper * * @return bool */ @@ -1807,8 +1814,8 @@ public function formatUrlKey($str) * Save current attribute with code $code and assign new value * * @param string $code Attribute code - * @param mixed $value New attribute value - * @param int $store Store ID + * @param mixed $value New attribute value + * @param int $store Store ID * @return void */ public function addAttributeUpdate($code, $value, $store) @@ -1878,6 +1885,7 @@ public function getRequestPath() /** * Custom function for other modules + * * @return string */ public function getGiftMessageAvailable() @@ -1996,6 +2004,8 @@ public function getOptions() } /** + * Set options for product + * * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options * @return $this */ @@ -2019,10 +2029,10 @@ public function getIsVirtual() /** * Add custom option information to product * - * @param string $code Option code - * @param mixed $value Value of the option - * @param int|Product $product Product ID - * @return $this + * @param string $code Option code + * @param mixed $value Value of the option + * @param int|Product $product Product ID + * @return $this */ public function addCustomOption($code, $value, $product = null) { @@ -2216,6 +2226,7 @@ public function getPreconfiguredValues() /** * Prepare product custom options. + * * To be sure that all product custom options does not has ID and has product instance * * @return \Magento\Catalog\Model\Product @@ -2550,9 +2561,9 @@ public function setTypeId($typeId) } /** - * {@inheritdoc} + * Retrieve existing extension attributes object or create a new one. * - * @return \Magento\Catalog\Api\Data\ProductExtensionInterface + * @return \Magento\Framework\Api\ExtensionAttributesInterface */ public function getExtensionAttributes() { @@ -2560,7 +2571,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * Set an extension attributes object. * * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes * @return $this @@ -2573,8 +2584,11 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensio //@codeCoverageIgnoreEnd /** + * Convert to media gallery interface + * * @param array $mediaGallery * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] + * @throws \Magento\Framework\Exception\LocalizedException */ protected function convertToMediaGalleryInterface(array $mediaGallery) { @@ -2590,7 +2604,10 @@ protected function convertToMediaGalleryInterface(array $mediaGallery) } /** + * Get media gallery entries + * * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null + * @throws \Magento\Framework\Exception\LocalizedException */ public function getMediaGalleryEntries() { @@ -2604,8 +2621,11 @@ public function getMediaGalleryEntries() } /** + * Set media gallery entries + * * @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function setMediaGalleryEntries(array $mediaGalleryEntries = null) { @@ -2646,6 +2666,8 @@ public function setId($value) } /** + * Get link repository + * * @return ProductLinkRepositoryInterface */ private function getLinkRepository() @@ -2658,6 +2680,8 @@ private function getLinkRepository() } /** + * Get media gallery processor + * * @return Product\Gallery\Processor */ private function getMediaGalleryProcessor() From 596ffb10ba2dc95f012cc39693ff513a2b41889c Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 19 Sep 2018 09:10:37 +0300 Subject: [PATCH 0523/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch --- .../CategoryFieldsProvider.php | 43 +- .../Adapter/DataMapper/ProductDataMapper.php | 53 ++- .../FieldProvider/FieldIndex/Converter.php | 36 ++ .../FieldIndex/IndexResolver.php | 86 ++++ .../FieldProvider/FieldType/Converter.php | 45 +++ .../FieldType/Resolver/CompositeResolver.php | 45 +++ .../FieldType/Resolver/IntegerType.php | 52 +++ .../FieldType/Resolver/KeywordType.php | 44 ++ .../FieldMapper/ProductFieldMapper.php | 186 +++------ .../Model/Adapter/FieldType.php | 12 + .../CategoryFieldsProvider.php | 43 +- .../BatchDataMapper/PriceFieldsProvider.php | 38 +- .../Model/Adapter/Elasticsearch.php | 25 +- .../FieldMapper/Product/AttributeAdapter.php | 177 +++++++++ .../AttributeAdapter/DummyAttribute.php | 14 + .../FieldMapper/Product/AttributeProvider.php | 77 ++++ .../Product/CompositeFieldProvider.php | 39 ++ .../FieldName/Resolver/NotEavAttribute.php | 45 --- .../Product/FieldName/Resolver/Price.php | 49 --- .../Product/FieldName/Resolver/Resolver.php | 54 --- .../FieldName/Resolver/SpecialAttribute.php | 27 -- .../Product/FieldName/ResolverInterface.php | 39 -- .../Product/FieldProvider/DynamicField.php | 134 +++++++ .../FieldProvider/FieldIndex/Converter.php | 34 ++ .../FieldIndex/ConverterInterface.php | 26 ++ .../FieldIndex/IndexResolver.php | 43 ++ .../FieldIndex/ResolverInterface.php | 23 ++ .../FieldName/Resolver/CategoryName.php | 30 +- .../FieldName/Resolver/CompositeResolver.php | 45 +++ .../FieldName/Resolver/DefaultResolver.php | 62 +-- .../FieldName/Resolver/NotEavAttribute.php | 28 ++ .../FieldName/Resolver/Position.php | 28 +- .../FieldName/Resolver/Price.php | 57 +++ .../FieldName/Resolver/SpecialAttribute.php | 28 ++ .../FieldName/ResolverInterface.php | 24 ++ .../FieldProvider/FieldType/Converter.php | 42 ++ .../FieldType/ConverterInterface.php | 31 ++ .../FieldType/Resolver/CompositeResolver.php | 45 +++ .../FieldType/Resolver/DateTimeType.php | 42 ++ .../FieldType/Resolver/DefaultResolver.php | 38 ++ .../FieldType/Resolver/FloatType.php | 42 ++ .../FieldType/Resolver/IntegerType.php | 44 ++ .../FieldType/ResolverInterface.php | 23 ++ .../Product/FieldProvider/StaticField.php | 112 ++++++ .../Product/FieldProviderInterface.php | 21 + .../FieldMapper/ProductFieldMapper.php | 40 -- .../Elasticsearch/Model/Adapter/FieldType.php | 13 +- .../FieldIndex/IndexResolverTest.php | 161 ++++++++ .../FieldType/Resolver/IntegerTypeTest.php | 99 +++++ .../FieldType/Resolver/KeywordTypeTest.php | 99 +++++ .../FieldMapper/ProductFieldMapperTest.php | 296 -------------- .../Model/Adapter/FieldTypeTest.php | 107 ----- .../Product/AttributeAdapterTest.php | 375 ++++++++++++++++++ .../FieldProvider/DynamicFieldTest.php | 327 +++++++++++++++ .../FieldIndex/IndexResolverTest.php | 95 +++++ .../FieldName/Resolver/CategoryNameTest.php | 119 ++++++ .../Resolver/DefaultResolverTest.php | 113 ++++++ .../Resolver/NotEavAttributeTest.php | 74 ++++ .../FieldName/Resolver/PositionTest.php | 119 ++++++ .../FieldName/Resolver/PriceTest.php | 107 +++++ .../Resolver/SpecialAttributeTest.php | 68 ++++ .../FieldProvider/FieldType/ConverterTest.php | 70 ++++ .../FieldType/Resolver/DateTimeTypeTest.php | 83 ++++ .../Resolver/DefaultResolverTest.php | 77 ++++ .../FieldType/Resolver/FloatTypeTest.php | 83 ++++ .../FieldType/Resolver/IntegerTypeTest.php | 99 +++++ .../Product/FieldProvider/StaticFieldTest.php | 245 ++++++++++++ .../FieldMapper/ProductFieldMapperTest.php | 298 -------------- app/code/Magento/Elasticsearch/etc/di.xml | 137 ++++++- 69 files changed, 4344 insertions(+), 1191 deletions(-) create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/CategoryName.php (60%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/DefaultResolver.php (54%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/Position.php (62%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 3e6164208b422..7892e18b9ee4c 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for categories fields @@ -20,18 +24,30 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $resourceIndex; /** - * @var FieldMapperInterface + * @var AttributeProvider */ - private $fieldMapper; + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; /** * @param Index $resourceIndex - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ - public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) - { + public function __construct( + Index $resourceIndex, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null + ) { $this->resourceIndex = $resourceIndex; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -55,6 +71,7 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { @@ -66,9 +83,17 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => $categoryIds]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index bcf0d0bfe26cd..de72485ddb84f 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; @@ -14,6 +15,10 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\Adapter\DataMapperInterface; use Magento\Elasticsearch\Model\Adapter\FieldType\Date as DateFieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * @deprecated 100.2.0 @@ -78,6 +83,16 @@ class ProductDataMapper implements DataMapperInterface */ protected $mediaGalleryRoles; + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + /** * Construction for DocumentDataMapper * @@ -87,6 +102,8 @@ class ProductDataMapper implements DataMapperInterface * @param FieldMapperInterface $fieldMapper * @param StoreManagerInterface $storeManager * @param DateFieldType $dateFieldType + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ public function __construct( Builder $builder, @@ -94,7 +111,9 @@ public function __construct( Index $resourceIndex, FieldMapperInterface $fieldMapper, StoreManagerInterface $storeManager, - DateFieldType $dateFieldType + DateFieldType $dateFieldType, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null ) { $this->builder = $builder; $this->attributeContainer = $attributeContainer; @@ -102,6 +121,10 @@ public function __construct( $this->fieldMapper = $fieldMapper; $this->storeManager = $storeManager; $this->dateFieldType = $dateFieldType; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); $this->mediaGalleryRoles = [ self::MEDIA_ROLE_IMAGE, @@ -232,14 +255,14 @@ protected function getProductTierPriceData($data) if (!empty($data)) { $i = 0; foreach ($data as $tierPrice) { - $result['tier_price_id_'.$i] = $tierPrice['price_id']; - $result['tier_website_id_'.$i] = $tierPrice['website_id']; - $result['tier_all_groups_'.$i] = $tierPrice['all_groups']; - $result['tier_cust_group_'.$i] = $tierPrice['cust_group'] == GroupInterface::CUST_GROUP_ALL + $result['tier_price_id_' . $i] = $tierPrice['price_id']; + $result['tier_website_id_' . $i] = $tierPrice['website_id']; + $result['tier_all_groups_' . $i] = $tierPrice['all_groups']; + $result['tier_cust_group_' . $i] = $tierPrice['cust_group'] == GroupInterface::CUST_GROUP_ALL ? '' : $tierPrice['cust_group']; - $result['tier_price_qty_'.$i] = $tierPrice['price_qty']; - $result['tier_website_price_'.$i] = $tierPrice['website_price']; - $result['tier_price_'.$i] = $tierPrice['price']; + $result['tier_price_qty_' . $i] = $tierPrice['price_qty']; + $result['tier_website_price_' . $i] = $tierPrice['website_price']; + $result['tier_price_' . $i] = $tierPrice['price']; $i++; } } @@ -395,13 +418,21 @@ protected function getProductCategoryData($productId, array $categoryIndexData) if (array_key_exists($productId, $categoryIndexData)) { $indexData = $categoryIndexData[$productId]; foreach ($indexData as $categoryData) { - $categoryIds[] = (int) $categoryData['id']; + $categoryIds[] = (int)$categoryData['id']; } if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php new file mode 100644 index 0000000000000..b68d5e6f62d14 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; + +/** + * Field type converter from internal index type to elastic service. + */ +class Converter implements ConverterInterface +{ + /** + * Text flags for Elasticsearch index value + */ + private const ES_NO_INDEX = false; + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + 'no_index' => self::ES_NO_INDEX, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType) + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php new file mode 100644 index 0000000000000..21429bc564374 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; + +/** + * Field index resolver that provide index type for attribute in mapping. + * For example we need to set 'no'/false in case when attribute must be present in index data, + * but stay as not indexable. + */ +class IndexResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @param ConverterInterface $converter + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param FieldTypeResolver $fieldTypeResolver + */ + public function __construct( + ConverterInterface $converter, + FieldTypeConverterInterface $fieldTypeConverter, + FieldTypeResolver $fieldTypeResolver + ) { + $this->converter = $converter; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->fieldTypeResolver = $fieldTypeResolver; + } + + /** + * {@inheritdoc} + */ + public function getFieldIndex(AttributeAdapter $attribute) + { + $index = null; + if (!$attribute->isSearchable() + && !$attribute->isAlwaysIndexable() + && ($this->isStringServiceFieldType($attribute) || $attribute->isComplexType()) + && !(($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined()) + && !$attribute->isFloatType() + ) { + $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); + } + + return $index; + } + + /** + * Check if service field type for field set as 'string' + * + * @param AttributeAdapter $attribute + * @return bool + */ + private function isStringServiceFieldType(AttributeAdapter $attribute): bool + { + $serviceFieldType = $this->fieldTypeResolver->getFieldType($attribute); + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); + + return $serviceFieldType === $stringTypeKey; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php new file mode 100644 index 0000000000000..9cb773adf914d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; + +/** + * Field type converter from internal data types to elastic service. + */ +class Converter implements ConverterInterface +{ + /**#@+ + * Text flags for Elasticsearch field types + */ + private const ES_DATA_TYPE_TEXT = 'text'; + private const ES_DATA_TYPE_KEYWORD = 'keyword'; + private const ES_DATA_TYPE_FLOAT = 'float'; + private const ES_DATA_TYPE_INT = 'integer'; + private const ES_DATA_TYPE_DATE = 'date'; + /**#@-*/ + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + self::INTERNAL_DATA_TYPE_STRING => self::ES_DATA_TYPE_TEXT, + self::INTERNAL_DATA_TYPE_KEYWORD => self::ES_DATA_TYPE_KEYWORD, + self::INTERNAL_DATA_TYPE_FLOAT => self::ES_DATA_TYPE_FLOAT, + self::INTERNAL_DATA_TYPE_INT => self::ES_DATA_TYPE_INT, + self::INTERNAL_DATA_TYPE_DATE => self::ES_DATA_TYPE_DATE, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType): string + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..719af357263d6 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Composite resolver for resolving field type. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param ResolverInterface[] $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldType($attribute); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php new file mode 100644 index 0000000000000..b777eb7e96ba5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Integer type resolver. + */ +class IntegerType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var array + */ + private $integerTypeAttributes; + + /** + * @param ConverterInterface $fieldTypeConverter + * @param array $integerTypeAttributes + */ + public function __construct(ConverterInterface $fieldTypeConverter, $integerTypeAttributes = ['category_ids']) + { + $this->fieldTypeConverter = $fieldTypeConverter; + $this->integerTypeAttributes = $integerTypeAttributes; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if (in_array($attribute->getAttributeCode(), $this->integerTypeAttributes, true) + || (($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined()) + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_INT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php new file mode 100644 index 0000000000000..77ef77aaf8740 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Keyword type resolver. + */ +class KeywordType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isComplexType() + || (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable() && $attribute->isFilterable()) + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_KEYWORD); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 87112032e1e27..e34e62a774925 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -3,16 +3,20 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper; -use Magento\Catalog\Api\CategoryListInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; +use Magento\Framework\App\ObjectManager; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use \Magento\Customer\Model\Session as CustomerSession; /** * Class ProductFieldMapper @@ -20,60 +24,81 @@ class ProductFieldMapper implements FieldMapperInterface { /** + * @deprecated * @var Config */ protected $eavConfig; /** + * @deprecated * @var FieldType */ protected $fieldType; /** - * Category list. - * - * @var CategoryListInterface + * @deprecated + * @var CustomerSession */ - private $categoryList; + protected $customerSession; /** - * Customer group repository. - * - * @var GroupRepositoryInterface + * @deprecated + * @var StoreManager */ - private $groupRepository; + protected $storeManager; /** - * Search criteria builder. - * - * @var SearchCriteriaBuilder + * @deprecated + * @var Registry + */ + protected $coreRegistry; + + /** + * @var AttributeProvider */ - private $searchCriteriaBuilder; + private $attributeAdapterProvider; /** - * @var ResolverInterface + * @var FieldNameResolver */ private $fieldNameResolver; + /** + * @var FieldProviderInterface + */ + private $fieldProvider; + /** * @param Config $eavConfig * @param FieldType $fieldType - * @param GroupRepositoryInterface $groupRepository - * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param ResolverInterface $fieldNameResolver + * @param CustomerSession $customerSession + * @param StoreManager $storeManager + * @param Registry $coreRegistry + * @param FieldNameResolver|null $fieldNameResolver + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldProviderInterface|null $fieldProvider */ public function __construct( Config $eavConfig, FieldType $fieldType, - GroupRepositoryInterface $groupRepository, - SearchCriteriaBuilder $searchCriteriaBuilder, - ResolverInterface $fieldNameResolver + CustomerSession $customerSession, + StoreManager $storeManager, + Registry $coreRegistry, + FieldNameResolver $fieldNameResolver = null, + AttributeProvider $attributeAdapterProvider = null, + FieldProviderInterface $fieldProvider = null ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; - $this->groupRepository = $groupRepository; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->fieldNameResolver = $fieldNameResolver; + $this->customerSession = $customerSession; + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldProvider = $fieldProvider ?: ObjectManager::getInstance() + ->get(FieldProviderInterface::class); } /** @@ -82,10 +107,12 @@ public function __construct( * @param string $attributeCode * @param array $context * @return string + * @throws \Magento\Framework\Exception\LocalizedException */ public function getFieldName($attributeCode, $context = []) { - return $this->fieldNameResolver->getFieldName($attributeCode, $context); + $attributeAdapter = $this->attributeAdapterProvider->getByAttributeCode($attributeCode); + return $this->fieldNameResolver->getFieldName($attributeAdapter, $context); } /** @@ -96,107 +123,6 @@ public function getFieldName($attributeCode, $context = []) */ public function getAllAttributesTypes($context = []) { - return array_merge( - $this->getAllStaticAttributesTypes(), - $this->getAllDynamicAttributesTypes() - ); - } - - /** - * @param Object $attribute - * @return bool - */ - protected function isAttributeUsedInAdvancedSearch($attribute) - { - return $attribute->getIsVisibleInAdvancedSearch() - || $attribute->getIsFilterable() - || $attribute->getIsFilterableInSearch(); - } - - /** - * Prepare mapping data for static attributes. - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @return array - */ - private function getAllStaticAttributesTypes() - { - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); - $allAttributes = []; - // List of attributes which are required to be indexable - $alwaysIndexableAttributes = [ - 'category_ids', - 'visibility', - ]; - - foreach ($attributeCodes as $attributeCode) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - - $allAttributes[$attributeCode] = [ - 'type' => $this->fieldType->getFieldType($attribute), - ]; - - if (!$attribute->getIsSearchable() && !$this->isAttributeUsedInAdvancedSearch($attribute) - && !in_array($attributeCode, $alwaysIndexableAttributes, true) - ) { - if ($attribute->getIsFilterable() || $attribute->getIsFilterableInSearch()) { - $allAttributes[$attributeCode]['type'] = FieldType::ES_DATA_TYPE_KEYWORD; - } else if ($allAttributes[$attributeCode]['type'] === FieldType::ES_DATA_TYPE_TEXT) { - $allAttributes[$attributeCode]['index'] = false; - } - } else if ($attributeCode == "category_ids") { - $allAttributes[$attributeCode] = [ - 'type' => FieldType::ES_DATA_TYPE_INT, - ]; - } - - if ($attribute->usesSource() - || $attribute->getFrontendInput() === 'select' - || $attribute->getFrontendInput() === 'multiselect' - ) { - $allAttributes[$attributeCode]['type'] = FieldType::ES_DATA_TYPE_KEYWORD; - - $allAttributes[$attributeCode . '_value'] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - ]; - } - } - - return $allAttributes; - } - - /** - * Prepare mapping data for dynamic attributes. - * - * @return array - */ - private function getAllDynamicAttributesTypes() - { - $allAttributes = []; - $searchCriteria = $this->searchCriteriaBuilder->create(); - $categories = $this->categoryList->getList($searchCriteria)->getItems(); - foreach ($categories as $category) { - $categoryPositionKey = $this->getFieldName('position', ['categoryId' => $category->getId()]); - $categoryNameKey = $this->getFieldName('category_name', ['categoryId' => $category->getId()]); - $allAttributes[$categoryPositionKey] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - 'index' => false - ]; - $allAttributes[$categoryNameKey] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - 'index' => false - ]; - } - - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - foreach ($groups as $group) { - $groupPriceKey = $this->getFieldName('price', ['customerGroupId' => $group->getId()]); - $allAttributes[$groupPriceKey] = [ - 'type' => FieldType::ES_DATA_TYPE_FLOAT, - 'store' => true - ]; - } - - return $allAttributes; + return $this->fieldProvider->getFields($context); } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index d11603295453d..002a787fd031a 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -6,15 +6,23 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; /** * Class FieldType + * * @api * @since 100.1.0 + * + * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @see ResolverInterface */ class FieldType { /**#@+ + * @deprecated + * @see \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + * * Text flags for Elasticsearch field types */ const ES_DATA_TYPE_TEXT = 'text'; @@ -28,12 +36,16 @@ class FieldType /**#@-*/ /** + * @deprecated + * @see ResolverInterface::getFieldType + * * @param AbstractAttribute $attribute * @return string * @since 100.1.0 */ public function getFieldType($attribute) { + trigger_error('Class is deprecated', E_USER_DEPRECATED); $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 7d2af3b31d9ac..8feb8eb6088cc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for categories fields @@ -20,18 +24,30 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $resourceIndex; /** - * @var FieldMapperInterface + * @var AttributeProvider */ - private $fieldMapper; + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; /** * @param Index $resourceIndex - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ - public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) - { + public function __construct( + Index $resourceIndex, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null + ) { $this->resourceIndex = $resourceIndex; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -55,6 +71,7 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { @@ -66,9 +83,17 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index f97cc89c5c875..1b749fd7039e5 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -3,13 +3,17 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\Store\Model\StoreManagerInterface; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for price fields @@ -32,26 +36,36 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface private $storeManager; /** - * @var FieldMapperInterface + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver */ - private $fieldMapper; + private $fieldNameResolver; /** * @param Index $resourceIndex * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, StoreManagerInterface $storeManager, - FieldMapperInterface $fieldMapper + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; $this->storeManager = $storeManager; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -65,7 +79,7 @@ public function getFields(array $productIds, $storeId) $fields = []; foreach ($productIds as $productId) { - $fields[$productId] = $this->getProductPriceData($productId, $priceData); + $fields[$productId] = $this->getProductPriceData($productId, $storeId, $priceData); } return $fields; @@ -75,18 +89,20 @@ public function getFields(array $productIds, $storeId) * Prepare price index for product * * @param int $productId + * @param int $websiteId * @param array $priceIndexData * @return array */ - private function getProductPriceData($productId, array $priceIndexData) + private function getProductPriceData($productId, $websiteId, array $priceIndexData) { $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = $this->fieldMapper->getFieldName( - 'price', - ['customerGroupId' => $customerGroupId] + $fieldName = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $customerGroupId, 'websiteId' => $websiteId] ); $result[$fieldName] = sprintf('%F', $price); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index fdf23332fff04..8e69001272b27 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -23,6 +23,11 @@ class Elasticsearch const BULK_ACTION_UPDATE = 'update'; /**#@-*/ + /** + * Buffer for total fields limit in mapping. + */ + private const MAPPING_TOTAL_FIELDS_BUFFER_LIMIT = 1000; + /**#@-*/ protected $connectionManager; @@ -348,8 +353,13 @@ protected function prepareIndex($storeId, $indexName, $mappedIndexerId) { $this->indexBuilder->setStoreId($storeId); $settings = $this->indexBuilder->build(); - $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]); - $settings['index']['mapping']['total_fields']['limit'] = count($allAttributeTypes); + $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes([ + 'entityType' => $mappedIndexerId, + // Use store id instead of website id from context for save existing fields mapping. + // In future websiteId will be eliminated due to index stored per store + 'websiteId' => $storeId + ]); + $settings['index']['mapping']['total_fields']['limit'] = $this->getMappingTotalFieldsLimit($allAttributeTypes); $this->client->createIndex($indexName, ['settings' => $settings]); $this->client->addFieldsMapping( $allAttributeTypes, @@ -359,4 +369,15 @@ protected function prepareIndex($storeId, $indexName, $mappedIndexerId) $this->preparedIndex[$storeId] = $indexName; return $this; } + + /** + * Get total fields limit for mapping. + * + * @param array $allAttributeTypes + * @return int + */ + private function getMappingTotalFieldsLimit(array $allAttributeTypes): int + { + return count($allAttributeTypes) + self::MAPPING_TOTAL_FIELDS_BUFFER_LIMIT; + } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php new file mode 100644 index 0000000000000..0661e86edceb7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -0,0 +1,177 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Framework\Model\AbstractExtensibleModel; + +/** + * Product attribute adapter for elasticsearch context. + */ +class AttributeAdapter +{ + /** + * @var AbstractExtensibleModel + */ + private $attribute; + + /** + * @var string + */ + private $attributeCode; + + /** + * @param AbstractExtensibleModel $attribute + * @param string $attributeCode + */ + public function __construct( + AbstractExtensibleModel $attribute, + string $attributeCode + ) { + $this->attribute = $attribute; + $this->attributeCode = $attributeCode; + } + + /** + * Check if attribute is filterable. + * + * @return bool + */ + public function isFilterable(): bool + { + return $this->getAttribute()->getIsFilterable() || $this->getAttribute()->getIsFilterableInSearch(); + } + + /** + * Check if attribute is searchable. + * + * @return bool + */ + public function isSearchable(): bool + { + return $this->getAttribute()->getIsSearchable() + || ($this->getAttribute()->getIsVisibleInAdvancedSearch() + || $this->isFilterable()); + } + + /** + * Check if attribute is need to index always. + * + * @return bool + */ + public function isAlwaysIndexable(): bool + { + // List of attributes which are required to be indexable + $alwaysIndexableAttributes = [ + 'category_ids', + 'visibility', + ]; + + return in_array($this->getAttributeCode(), $alwaysIndexableAttributes, true); + } + + /** + * Check if attribute has date/time type. + * + * @return bool + */ + public function isDateTimeType(): bool + { + return in_array($this->getAttribute()->getBackendType(), ['timestamp', 'datetime'], true); + } + + /** + * Check if attribute has float type. + * + * @return bool + */ + public function isFloatType(): bool + { + return $this->getAttribute()->getBackendType() === 'decimal'; + } + + /** + * Check if attribute has integer type. + * + * @return bool + */ + public function isIntegerType(): bool + { + return in_array($this->getAttribute()->getBackendType(), ['int', 'smallint'], true); + } + + /** + * Check if attribute has boolean type. + * + * @return bool + */ + public function isBooleanType(): bool + { + return in_array($this->getAttribute()->getFrontendInput(), ['select', 'boolean'], true) + && $this->getAttribute()->getBackendType() !== 'varchar'; + } + + /** + * Check if attribute has boolean type. + * + * @return bool + */ + public function isComplexType(): bool + { + return in_array($this->getAttribute()->getFrontendInput(), ['select', 'multiselect'], true) + || $this->getAttribute()->usesSource(); + } + + /** + * Check if product attribute is EAV. + * + * @return bool + */ + public function isEavAttribute(): bool + { + return $this->getAttribute() instanceof \Magento\Eav\Api\Data\AttributeInterface; + } + + /** + * Get attribute code. + * + * @return string + */ + public function getAttributeCode(): string + { + return $this->attributeCode; + } + + /** + * Check if attribute is defined by user. + * + * @return string + */ + public function isUserDefined(): string + { + return $this->getAttribute()->getIsUserDefined(); + } + + /** + * Frontend HTML for input element. + * + * @return string + */ + public function getFrontendInput() + { + return $this->getAttribute()->getFrontendInput(); + } + + /** + * Get product attribute instance. + * + * @return AbstractExtensibleModel|\Magento\Eav\Api\Data\AttributeInterface + */ + private function getAttribute(): AbstractExtensibleModel + { + return $this->attribute; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php new file mode 100644 index 0000000000000..de824e4aeedb2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Dummy class for Not EAV attribute. + */ +class DummyAttribute extends \Magento\Framework\Model\AbstractExtensibleModel +{ + // +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php new file mode 100644 index 0000000000000..8ae100f177494 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -0,0 +1,77 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Eav\Model\Config; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; + +/** + * Provide attribute adapter. + */ +class AttributeProvider +{ + /** + * Object Manager instance + * + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager = null; + + /** + * Instance name to create + * + * @var string + */ + private $instanceName = null; + + /** + * @var Config + */ + private $eavConfig; + + /** + * @var array + */ + private $cachedPool = []; + + /** + * Factory constructor + * + * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @param Config $eavConfig + * @param string $instanceName + */ + public function __construct( + \Magento\Framework\ObjectManagerInterface $objectManager, + Config $eavConfig, + $instanceName = 'Magento\\Elasticsearch\\Model\\Adapter\\FieldMapper\\Product\\AttributeAdapter' + ) { + $this->objectManager = $objectManager; + $this->instanceName = $instanceName; + $this->eavConfig = $eavConfig; + } + + /** + * Create class instance with specified parameters + * + * @param string $attributeCode + * @return AttributeAdapter + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getByAttributeCode(string $attributeCode): AttributeAdapter + { + if (!isset($this->cachedPool[$attributeCode])) { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (null === $attribute) { + $attribute = $this->objectManager->create(DummyAttribute::class); + } + $this->cachedPool[$attributeCode] = $this->objectManager->create( + $this->instanceName, + ['attribute' => $attribute, 'attributeCode' => $attributeCode] + ); + } + + return $this->cachedPool[$attributeCode]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php new file mode 100644 index 0000000000000..7d0d5fccbcf6c --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -0,0 +1,39 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +/** + * Provide fields for product. + */ +class CompositeFieldProvider implements FieldProviderInterface +{ + /** + * @var FieldProviderInterface[] + */ + private $providers; + + /** + * @param array $providers + */ + public function __construct(array $providers) + { + $this->providers = $providers; + } + + /** + * Get fields. + * + * @param array $context + * @return array + */ + public function getFields(array $context = []): array + { + $allAttributes = []; + + foreach ($this->providers as $provider) { + $allAttributes = array_merge($allAttributes, $provider->getFields($context)); + } + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php deleted file mode 100644 index 8c8b58943a5b3..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; - -/** - * Resolver field name for not EAV attribute. - */ -class NotEavAttribute extends Resolver implements ResolverInterface -{ - /** - * @var Config - */ - private $eavConfig; - - /** - * @param ResolverInterface $resolver - * @param Config $eavConfig - */ - public function __construct(ResolverInterface $resolver, Config $eavConfig) - { - parent::__construct($resolver); - $this->eavConfig = $eavConfig; - } - - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute) { - return $attributeCode; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php deleted file mode 100644 index ea64972868d0a..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Customer\Model\Session as CustomerSession; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Resolver field name for price attribute. - */ -class Price extends Resolver implements ResolverInterface -{ - /** - * @var CustomerSession - */ - private $customerSession; - - /** - * @param ResolverInterface $resolver - * @param CustomerSession $customerSession - */ - public function __construct( - ResolverInterface $resolver, - CustomerSession $customerSession - ) { - parent::__construct($resolver); - $this->customerSession = $customerSession; - } - - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - if ($attributeCode === 'price') { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); - - return 'price_' . $customerGroupId; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php deleted file mode 100644 index 492fc70848530..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; -use Magento\Framework\Exception\NotFoundException; - -/** - * Abstract class for resolving field name. - */ -abstract class Resolver implements ResolverInterface -{ - /** - * @var ResolverInterface - */ - private $next; - - /** - * @param ResolverInterface $resolver - */ - public function __construct(ResolverInterface $resolver) - { - $this->next = $resolver; - } - - /** - * {@inheritdoc} - */ - public abstract function getFieldName($attributeCode, $context = []): string; - - /** - * {@inheritdoc} - */ - public function getNext(): ResolverInterface - { - if (!$this->hasNext()) { - throw new NotFoundException(__('Next resolver not found.')); - } - - return $this->next; - } - - /** - * {@inheritdoc} - */ - public function hasNext(): bool - { - return null !== $this->next; - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php deleted file mode 100644 index 518cd548536b2..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Resolver field name for not special attribute. - */ -class SpecialAttribute extends Resolver implements ResolverInterface -{ - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php deleted file mode 100644 index 0b7bc187ecd68..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; - -use Magento\Framework\Exception\NotFoundException; - -/** - * Field name resolver interface. - */ -interface ResolverInterface -{ - /** - * Get field name. - * - * @param $attributeCode - * @param array $context - * @return string - */ - public function getFieldName($attributeCode, $context = []): string; - - /** - * Get next resolver. - * - * @return ResolverInterface - * @throws NotFoundException - */ - public function getNext(): ResolverInterface; - - /** - * Check if next resolver present. - * - * @return bool - */ - public function hasNext(): bool; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php new file mode 100644 index 0000000000000..a7773f0afda7e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -0,0 +1,134 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Catalog\Api\CategoryListInterface; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; +use Magento\Framework\Api\SearchCriteriaBuilder; + +/** + * Provide dynamic fields for product. + */ +class DynamicField implements FieldProviderInterface +{ + /** + * Category list. + * + * @var CategoryListInterface + */ + private $categoryList; + + /** + * Customer group repository. + * + * @var GroupRepositoryInterface + */ + private $groupRepository; + + /** + * Search criteria builder. + * + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + + /** + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param IndexTypeConverterInterface $indexTypeConverter + * @param GroupRepositoryInterface $groupRepository + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param CategoryListInterface $categoryList + * @param FieldNameResolver $fieldNameResolver + * @param AttributeProvider $attributeAdapterProvider + */ + public function __construct( + FieldTypeConverterInterface $fieldTypeConverter, + IndexTypeConverterInterface $indexTypeConverter, + GroupRepositoryInterface $groupRepository, + SearchCriteriaBuilder $searchCriteriaBuilder, + CategoryListInterface $categoryList, + FieldNameResolver $fieldNameResolver, + AttributeProvider $attributeAdapterProvider + ) { + $this->groupRepository = $groupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->indexTypeConverter = $indexTypeConverter; + $this->categoryList = $categoryList; + $this->fieldNameResolver = $fieldNameResolver; + $this->attributeAdapterProvider = $attributeAdapterProvider; + } + + /** + * {@inheritdoc} + */ + public function getFields(array $context = []): array + { + $allAttributes = []; + $searchCriteria = $this->searchCriteriaBuilder->create(); + $categories = $this->categoryList->getList($searchCriteria)->getItems(); + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); + foreach ($categories as $category) { + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $category->getId()] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $category->getId()] + ); + $allAttributes[$categoryPositionKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE) + ]; + $allAttributes[$categoryNameKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE) + ]; + } + + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; + } + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php new file mode 100644 index 0000000000000..bd24fe6fa82a3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +/** + * Field type converter from internal index type to elastic service. + */ +class Converter implements ConverterInterface +{ + /** + * Text flags for Elasticsearch index value + */ + private const ES_NO_INDEX = 'no'; + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + 'no_index' => self::ES_NO_INDEX, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType) + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php new file mode 100644 index 0000000000000..8199639fb8045 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +/** + * Field type converter from internal index value to elastic service. + */ +interface ConverterInterface +{ + /**#@+ + * Text flags for internal no index value. + */ + public const INTERNAL_NO_INDEX_VALUE = 'no_index'; + public const INTERNAL_INDEX_VALUE = 'index'; + + /** + * Get service field type. + * + * @param string $internalType + * @return string|boolean + */ + public function convert(string $internalType); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php new file mode 100644 index 0000000000000..5a7203bf30bf6 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field index resolver that provide index type for attribute in mapping. + * For example we need to set 'no'/false in case when attribute must be present in index data, + * but stay as not indexable. + */ +class IndexResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @param ConverterInterface $converter + */ + public function __construct(ConverterInterface $converter) + { + $this->converter = $converter; + } + + /** + * {@inheritdoc} + */ + public function getFieldIndex(AttributeAdapter $attribute) + { + $index = null; + if (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable()) { + $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); + } + + return $index; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php new file mode 100644 index 0000000000000..fb87e0756d621 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field index type resolver interface. + */ +interface ResolverInterface +{ + /** + * Get field index. + * + * @param AttributeAdapter $attribute + * @return string|boolean + */ + public function getFieldIndex(AttributeAdapter $attribute); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php similarity index 60% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index 9e012c1427218..1ad42a55cbbd4 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -4,16 +4,18 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Framework\App\ObjectManager; /** * Resolver field name for Category name attribute. */ -class CategoryName extends Resolver implements ResolverInterface +class CategoryName implements ResolverInterface { /** * @var StoreManager @@ -26,30 +28,29 @@ class CategoryName extends Resolver implements ResolverInterface private $coreRegistry; /** - * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - ResolverInterface $resolver, - StoreManager $storeManager, - Registry $coreRegistry + StoreManager $storeManager = null, + Registry $coreRegistry = null ) { - parent::__construct($resolver); - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() + ->get(Registry::class); } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - if ($attributeCode === 'category_name') { + if ($attribute->getAttributeCode() === 'category_name') { return 'name_category_' . $this->resolveCategoryId($context); } - return $this->getNext()->getFieldName($attributeCode, $context); + return null; } /** @@ -57,8 +58,9 @@ public function getFieldName($attributeCode, $context = []): string * * @param array $context * @return int + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - private function resolveCategoryId($context) + private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..81ce3bf030806 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Composite class for resolving field name. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param array $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldName($attribute, $context); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php similarity index 54% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index afc0b6a0c6f99..ab5486f3af292 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -4,58 +4,57 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; -use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; /** * Default name resolver. */ -class DefaultResolver extends Resolver implements ResolverInterface +class DefaultResolver implements ResolverInterface { /** - * @var Config + * @var FieldTypeResolver */ - private $eavConfig; + private $fieldTypeResolver; /** - * @var FieldType + * @var FieldTypeConverterInterface */ - private $fieldType; + private $fieldTypeConverter; /** - * @param ResolverInterface $resolver - * @param Config $eavConfig - * @param FieldType $fieldType + * @param FieldTypeResolver $fieldTypeResolver + * @param FieldTypeConverterInterface $fieldTypeConverter */ public function __construct( - ResolverInterface $resolver, - Config $eavConfig, - FieldType $fieldType + FieldTypeResolver $fieldTypeResolver, + FieldTypeConverterInterface $fieldTypeConverter ) { - parent::__construct($resolver); - $this->eavConfig = $eavConfig; - $this->fieldType = $fieldType; + $this->fieldTypeResolver = $fieldTypeResolver; + $this->fieldTypeConverter = $fieldTypeConverter; } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - $fieldType = $this->fieldType->getFieldType($attribute); + $fieldType = $this->fieldTypeResolver->getFieldType($attribute); + $attributeCode = $attribute->getAttributeCode(); $frontendInput = $attribute->getFrontendInput(); if (empty($context['type'])) { $fieldName = $attributeCode; } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if (in_array($fieldType, ['string', FieldType::ES_DATA_TYPE_TEXT], true)) { + if ($this->isStringServiceFieldType($fieldType)) { return $this->getFieldName( - $attributeCode, + $attribute, array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) ); } @@ -69,6 +68,19 @@ public function getFieldName($attributeCode, $context = []): string return $fieldName; } + /** + * Check if service field type for field set as 'string' + * + * @param string $serviceFieldType + * @return bool + */ + private function isStringServiceFieldType(string $serviceFieldType): bool + { + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); + + return $serviceFieldType === $stringTypeKey; + } + /** * @param string $frontendInput * @param string $fieldType @@ -95,7 +107,7 @@ private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) { switch ($frontendInput) { case 'select': - return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; + return in_array($fieldType, ['text', 'integer'], true) ? $attributeCode . '_value' : $attributeCode; case 'boolean': return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; default: diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php new file mode 100644 index 0000000000000..094148aa3e632 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for not EAV attribute. + */ +class NotEavAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if (!$attribute->isEavAttribute()) { + return $attribute->getAttributeCode(); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php similarity index 62% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index d4839012f0b8c..beb1a675e89da 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -4,16 +4,18 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Framework\App\ObjectManager; /** * Resolver field name for position attribute. */ -class Position extends Resolver implements ResolverInterface +class Position implements ResolverInterface { /** * @var StoreManager @@ -26,30 +28,29 @@ class Position extends Resolver implements ResolverInterface private $coreRegistry; /** - * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - ResolverInterface $resolver, - StoreManager $storeManager, - Registry $coreRegistry + StoreManager $storeManager = null, + Registry $coreRegistry = null ) { - parent::__construct($resolver); - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() + ->get(Registry::class); } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - if ($attributeCode === 'position') { + if ($attribute->getAttributeCode() === 'position') { return 'position_category_' . $this->resolveCategoryId($context); } - return $this->getNext()->getFieldName($attributeCode, $context); + return null; } /** @@ -57,6 +58,7 @@ public function getFieldName($attributeCode, $context = []): string * * @param array $context * @return int + * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php new file mode 100644 index 0000000000000..4449ec57523b9 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for price attribute. + */ +class Price implements ResolverInterface +{ + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @param CustomerSession $customerSession + * @param StoreManager $storeManager + */ + public function __construct(CustomerSession $customerSession, StoreManager $storeManager) + { + $this->customerSession = $customerSession; + $this->storeManager = $storeManager; + } + + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if ($attribute->getAttributeCode() === 'price') { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); + + return 'price_' . $customerGroupId . '_' . $websiteId; + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php new file mode 100644 index 0000000000000..14906fa5cee82 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for not special attribute. + */ +class SpecialAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if (in_array($attribute->getAttributeCode(), ['id', 'sku', 'store_id', 'visibility'], true)) { + return $attribute->getAttributeCode(); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php new file mode 100644 index 0000000000000..ecc46d2607cf8 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field name resolver for preparing field key for elasticsearch mapping by attribute. + */ +interface ResolverInterface +{ + /** + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php new file mode 100644 index 0000000000000..be8ef76e666fe --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +/** + * Field type converter from internal data types to elastic service. + */ +class Converter implements ConverterInterface +{ + /**#@+ + * Text flags for Elasticsearch field types + */ + private const ES_DATA_TYPE_STRING = 'string'; + private const ES_DATA_TYPE_FLOAT = 'float'; + private const ES_DATA_TYPE_INT = 'integer'; + private const ES_DATA_TYPE_DATE = 'date'; + /**#@-*/ + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + self::INTERNAL_DATA_TYPE_STRING => self::ES_DATA_TYPE_STRING, + self::INTERNAL_DATA_TYPE_KEYWORD => self::ES_DATA_TYPE_STRING, + self::INTERNAL_DATA_TYPE_FLOAT => self::ES_DATA_TYPE_FLOAT, + self::INTERNAL_DATA_TYPE_INT => self::ES_DATA_TYPE_INT, + self::INTERNAL_DATA_TYPE_DATE => self::ES_DATA_TYPE_DATE, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType): string + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php new file mode 100644 index 0000000000000..e5ec1ce445ab2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +/** + * @api + * Field type converter from internal data types to elastic service. + */ +interface ConverterInterface +{ + /**#@+ + * Text flags for internal field types + */ + public const INTERNAL_DATA_TYPE_STRING = 'string'; + public const INTERNAL_DATA_TYPE_FLOAT = 'float'; + public const INTERNAL_DATA_TYPE_INT = 'integer'; + public const INTERNAL_DATA_TYPE_DATE = 'date'; + public const INTERNAL_DATA_TYPE_KEYWORD = 'keyword'; + /**#@-*/ + + /** + * Get service field type. + * + * @param string $internalType + * @return string + */ + public function convert(string $internalType): string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..7a4c06c56d095 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Composite resolver for resolving field type. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param ResolverInterface[] $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldType($attribute); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php new file mode 100644 index 0000000000000..ff029ff8610f5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Date/Time type resolver. + */ +class DateTimeType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isDateTimeType()) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_DATE); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php new file mode 100644 index 0000000000000..8e754cddd3e92 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Default field type resolver. + */ +class DefaultResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_STRING); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php new file mode 100644 index 0000000000000..9fe03d4cbab49 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Float type resolver. + */ +class FloatType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isFloatType()) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_FLOAT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php new file mode 100644 index 0000000000000..c4280505f1190 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Integer type resolver. + */ +class IntegerType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if (($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined() + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_INT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php new file mode 100644 index 0000000000000..118a440cddef2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field type resolver interface. + */ +interface ResolverInterface +{ + /** + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string + */ + public function getFieldType(AttributeAdapter $attribute): ?string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php new file mode 100644 index 0000000000000..89748d6428e4d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -0,0 +1,112 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Eav\Model\Config; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface + as FieldIndexResolver; + +/** + * Provide static fields for product. + */ +class StaticField implements FieldProviderInterface +{ + /** + * @var Config + */ + private $eavConfig; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @var FieldIndexResolver + */ + private $fieldIndexResolver; + + /** + * @param Config $eavConfig + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param IndexTypeConverterInterface $indexTypeConverter + * @param FieldTypeResolver $fieldTypeResolver + * @param FieldIndexResolver $fieldIndexResolver + * @param AttributeProvider $attributeAdapterProvider + */ + public function __construct( + Config $eavConfig, + FieldTypeConverterInterface $fieldTypeConverter, + IndexTypeConverterInterface $indexTypeConverter, + FieldTypeResolver $fieldTypeResolver, + FieldIndexResolver $fieldIndexResolver, + AttributeProvider $attributeAdapterProvider + ) { + $this->eavConfig = $eavConfig; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->indexTypeConverter = $indexTypeConverter; + $this->fieldTypeResolver = $fieldTypeResolver; + $this->fieldIndexResolver = $fieldIndexResolver; + $this->attributeAdapterProvider = $attributeAdapterProvider; + } + + /** + * {@inheritdoc} + */ + public function getFields(array $context = []): array + { + $attributes = $this->eavConfig->getEntityAttributes(ProductAttributeInterface::ENTITY_TYPE_CODE); + $allAttributes = []; + + foreach ($attributes as $attribute) { + $attributeAdapter = $this->attributeAdapterProvider->getByAttributeCode($attribute->getAttributeCode()); + $code = $attributeAdapter->getAttributeCode(); + + $allAttributes[$code] = [ + 'type' => $this->fieldTypeResolver->getFieldType($attributeAdapter), + ]; + + $index = $this->fieldIndexResolver->getFieldIndex($attributeAdapter); + if (null !== $index) { + $allAttributes[$code]['index'] = $index; + } + + if ($attributeAdapter->isComplexType()) { + $allAttributes[$code . '_value'] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING) + ]; + } + } + + $allAttributes['store_id'] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE), + ]; + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php new file mode 100644 index 0000000000000..2a68e3e2a3708 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +/** + * Product fields provider. + * Provide fields mapping configuration for elasticsearch service of internal product attributes. + */ +interface FieldProviderInterface +{ + /** + * Get fields. + * + * @param array $context + * @return array + */ + public function getFields(array $context = []): array; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php index e78983c62f6d2..657605bbd019b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -5,53 +5,13 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; -use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper as Elasticsearch5ProductFieldMapper; -use Magento\Elasticsearch\Model\Adapter\FieldType; /** * Class ProductFieldMapper */ class ProductFieldMapper extends Elasticsearch5ProductFieldMapper implements FieldMapperInterface { - /** - * @return array - */ - private function getAllStaticAttributesTypes() - { - $allAttributes = []; - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); - // List of attributes which are required to be indexable - $alwaysIndexableAttributes = [ - 'category_ids', - 'visibility', - ]; - - foreach ($attributeCodes as $attributeCode) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - - $allAttributes[$attributeCode] = [ - 'type' => $this->fieldType->getFieldType($attribute) - ]; - - if (!$attribute->getIsSearchable() && !$this->isAttributeUsedInAdvancedSearch($attribute) - && !in_array($attributeCode, $alwaysIndexableAttributes, true) - ) { - $allAttributes[$attributeCode] = array_merge( - $allAttributes[$attributeCode], - ['index' => 'no'] - ); - } - - if ($attribute->getFrontendInput() === 'select' || $attribute->getFrontendInput() === 'multiselect') { - $allAttributes[$attributeCode . '_value'] = [ - 'type' => FieldType::ES_DATA_TYPE_STRING, - ]; - } - } - - return $allAttributes; - } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 4315597a3cf58..be6462156c471 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -6,15 +6,23 @@ namespace Magento\Elasticsearch\Model\Adapter; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; /** * Class FieldType + * * @api * @since 100.1.0 + * + * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @see ResolverInterface */ class FieldType { /**#@+ + * @deprecated + * @see \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + * * Text flags for Elasticsearch field types */ const ES_DATA_TYPE_STRING = 'string'; @@ -27,12 +35,15 @@ class FieldType /**#@-*/ /** + * @deprecated + * @see ResolverInterface::getFieldType + * * @param AbstractAttribute $attribute * @return string - * @since 100.1.0 */ public function getFieldType($attribute) { + trigger_error('Class is deprecated', E_USER_DEPRECATED); $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php new file mode 100644 index 0000000000000..a4503924c8455 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -0,0 +1,161 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; + +class IndexResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + */ + private $resolver; + + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->converter = $this->getMockBuilder(ConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMockForAbstractClass(); + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + [ + 'converter' => $this->converter, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'fieldTypeResolver' => $this->fieldTypeResolver, + ] + ); + } + + /** + * @dataProvider getFieldIndexProvider + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $stringServiceFieldType + * @param $isComplexType + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $isFloatType + * @param $serviceFieldType + * @param $expected + * @return void + */ + public function testGetFieldName( + $isSearchable, + $isAlwaysIndexable, + $isComplexType, + $isIntegerType, + $isBooleanType, + $isUserDefined, + $isFloatType, + $serviceFieldType, + $expected + ) { + $this->converter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($serviceFieldType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('string'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods([ + 'isSearchable', + 'isAlwaysIndexable', + 'isComplexType', + 'isIntegerType', + 'isBooleanType', + 'isUserDefined', + 'isFloatType', + ]) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $attributeMock->expects($this->any()) + ->method('isFloatType') + ->willReturn($isFloatType); + + $this->assertEquals( + $expected, + $this->resolver->getFieldIndex($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + [true, true, true, true, true, true, true, 'string', null], + [false, false, true, false, false, false, false, 'string', 'something'], + [false, false, true, false, false, false, false, 'string', 'something'], + [false, false, false, false, false, false, false, 'string', 'something'], + [false, false, false, false, false, false, false, 'int', null], + [false, false, true, true, false, true, false, 'string', 'something'], + [false, false, true, false, true, true, false, 'string', 'something'], + [false, false, true, false, true, false, false, 'string', null], + [false, false, true, false, true, true, true, 'string', null], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php new file mode 100644 index 0000000000000..d4536e4a53b62 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IntegerTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $attributeCode + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $expected + * @return void + */ + public function testGetFieldType($attributeCode, $isIntegerType, $isBooleanType, $isUserDefined, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'isIntegerType', 'isBooleanType', 'isUserDefined']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['category_ids', true, true, true, 'something'], + ['category_ids', false, false, false, 'something'], + ['type', true, false, false, 'something'], + ['type', false, true, false, 'something'], + ['type', true, true, true, ''], + ['type', false, false, true, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php new file mode 100644 index 0000000000000..cd0b88e6ce51d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class KeywordTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isComplexType + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $isFilterable + * @param $expected + * @return void + */ + public function testGetFieldType($isComplexType, $isSearchable, $isAlwaysIndexable, $isFilterable, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isComplexType', 'isSearchable', 'isAlwaysIndexable', 'isFilterable']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + $attributeMock->expects($this->any()) + ->method('isFilterable') + ->willReturn($isFilterable); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, true, true, true, 'something'], + [true, false, false, false, 'something'], + [true, false, false, true, 'something'], + [false, false, false, true, 'something'], + [false, false, false, false, ''], + [false, false, true, false, ''], + [false, true, false, false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php deleted file mode 100644 index 6ee32a58698c6..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php +++ /dev/null @@ -1,296 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper; - -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -class ProductFieldMapperTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper - */ - protected $mapper; - - /** - * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject - */ - protected $coreRegistry; - - /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSession; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $storeManager; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * @var FieldType|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldType; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $store; - - /** - * Set up test environment - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $this->fieldType = $this->getMockBuilder(FieldType::class) - ->disableOriginalConstructor() - ->setMethods(['getFieldType']) - ->getMock(); - - $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['getCustomerGroupId']) - ->getMock(); - - $this->storeManager = $this->storeManager = $this->getMockForAbstractClass( - \Magento\Store\Model\StoreManagerInterface::class, - [], - '', - false - ); - - $this->store = $this->getMockForAbstractClass( - \Magento\Store\Api\Data\StoreInterface::class, - [], - '', - false, - false, - true, - ['getWebsiteId', 'getRootCategoryId'] - ); - - $this->coreRegistry = $this->createMock(\Magento\Framework\Registry::class); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->mapper = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper::class, - [ - 'eavConfig' => $this->eavConfig, - 'storeManager' => $this->storeManager, - 'fieldType' => $this->fieldType, - 'customerSession' => $this->customerSession, - 'coreRegistry' => $this->coreRegistry - ] - ); - } - - /** - * @dataProvider attributeCodeProvider - * @param string $attributeCode - * @param string $fieldName - * @param string $fieldType - * @param array $context - * - * @return void - */ - public function testGetFieldName($attributeCode, $fieldName, $fieldType, $context = []) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttribute']) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSession->expects($this->any()) - ->method('getCustomerGroupId') - ->willReturn('0'); - - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - $this->store->expects($this->any()) - ->method('getWebsiteId') - ->willReturn('1'); - $this->store->expects($this->any()) - ->method('getRootCategoryId') - ->willReturn('1'); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue('select')); - - $this->fieldType->expects($this->any())->method('getFieldType') - ->with($attributeMock) - ->willReturn($fieldType); - - $this->assertEquals( - $fieldName, - $this->mapper->getFieldName($attributeCode, $context) - ); - } - - /** - * @return void - */ - public function testGetFieldNameWithoutAttribute() - { - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, 'attr1') - ->willReturn(''); - - $this->assertEquals( - 'attr1', - $this->mapper->getFieldName('attr1', []) - ); - } - - /** - * @dataProvider attributeProvider - * @param string $attributeCode - * @param string $inputType - * @param array $searchAttributes - * @param array $expected - * @return void - */ - public function testGetAllAttributesTypes($attributeCode, $inputType, $searchAttributes, $expected) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->eavConfig->expects($this->any())->method('getEntityAttributeCodes') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE) - ->willReturn([$attributeCode]); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $this->fieldType->expects($this->once())->method('getFieldType')->willReturn(FieldType::ES_DATA_TYPE_INT); - - $attributeMock->expects($this->any()) - ->method('getIsSearchable') - ->willReturn($searchAttributes['searchable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterable') - ->willReturn($searchAttributes['filterable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterableInSearch') - ->willReturn($searchAttributes['filterableInSearch']); - $attributeMock->expects($this->any()) - ->method('getIsVisibleInAdvancedSearch') - ->willReturn($searchAttributes['advSearch']); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($inputType)); - - $this->assertEquals( - $expected, - $this->mapper->getAllAttributesTypes() - ); - } - - /** - * @return array - */ - public function attributeCodeProvider() - { - return [ - ['id', 'id', 'text'], - ['status', 'status', 'text'], - ['status', 'status_value', 'text', ['type'=>'default']], - ['price', 'price_0_1', 'text', ['type'=>'default']], - ['position', 'position_category_1', 'text', ['type'=>'default']], - ['price', 'price_2_3', 'text', ['type'=>'default', 'customerGroupId'=>'2', 'websiteId'=>'3']], - ['position', 'position_category_3', 'text', ['type'=>'default', 'categoryId'=>'3']], - ['color', 'color_value', 'text', ['type'=>'text']], - ['description', 'sort_description', 'text', ['type'=>'some']], - ['*', '_all', 'text', ['type'=>'text']], - ['description', 'description_value', 'text', ['type'=>'text']], - ]; - } - - /** - * @return array - */ - public function attributeProvider() - { - return [ - [ - 'category_ids', - 'select', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['category_ids' => ['type' => 'keyword'], 'category_ids_value' => ['type' => 'text']] - ], - [ - 'attr_code', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => true, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '1', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => true], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '1', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php deleted file mode 100644 index 63c993e27c9a9..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter; - -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use PHPUnit_Framework_MockObject_MockObject as MockObject; - -class FieldTypeTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldType - */ - protected $type; - - /** - * @var \Magento\Eav\Model\Config|MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * Set up test environment. - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->type = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType::class, - [ - 'eavConfig' => $this->eavConfig, - ] - ); - } - - /** - * Test getFieldType() method. - * - * @dataProvider attributeTypesProvider - * @param string $attributeCode - * @param string $backendType - * @param string $frontendType - * @param string $expectedFieldType - * @return void - */ - public function testGetFieldType($attributeCode, $backendType, $frontendType, $expectedFieldType) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttributeCode']) - ->disableOriginalConstructor() - ->getMock(); - - $attributeMock->expects($this->any())->method('getBackendType') - ->will($this->returnValue($backendType)); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($frontendType)); - - $attributeMock->expects($this->any())->method('getAttributeCode') - ->will($this->returnValue($attributeCode)); - - $this->assertEquals($expectedFieldType, $this->type->getFieldType($attributeMock)); - } - - /** - * @return array - */ - public static function attributeTypesProvider() - { - return [ - ['attr1', 'static', 'select', 'integer'], - ['attr1', 'static', 'text', 'text'], - ['attr1', 'timestamp', 'select', 'date'], - ['attr1', 'datetime', 'text', 'date'], - ['attr1', 'int', 'select', 'integer'], - ['attr1', 'decimal', 'text', 'float'], - ['attr1', 'varchar', 'select', 'text'], - ['attr1', 'array', 'multiselect', 'text'], - ['price', 'int', 'text', 'integer'], - ['tier_price', 'int', 'text', 'integer'], - ['tier_price', 'smallint', 'text', 'integer'], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php new file mode 100644 index 0000000000000..ccefb2c4844a7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -0,0 +1,375 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Model\AbstractExtensibleModel; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; + +class AttributeAdapterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter + */ + private $adapter; + + /** + * @var AbstractExtensibleModel + */ + private $attribute; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->attribute = $this->getMockBuilder(AbstractExtensibleModel::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getIsFilterable', + 'getIsFilterableInSearch', + 'getIsSearchable', + 'getIsVisibleInAdvancedSearch', + 'getBackendType', + 'getFrontendInput', + 'usesSource', + ]) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->adapter = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter::class, + [ + 'attribute' => $this->attribute, + 'attributeCode' => 'code', + ] + ); + } + + /** + * @dataProvider isFilterableProvider + * @param $isFilterable + * @param $isFilterableInSearch + * @param $expected + * @return void + */ + public function testIsFilterable($isFilterable, $isFilterableInSearch, $expected) + { + $this->attribute + ->method('getIsFilterable') + ->willReturn($isFilterable); + $this->attribute + ->method('getIsFilterableInSearch') + ->willReturn($isFilterableInSearch); + $this->assertEquals( + $expected, + $this->adapter->isFilterable() + ); + } + + /** + * @dataProvider isSearchableProvider + * @param $isSearchable + * @param $isVisibleInAdvancedSearch + * @param $isFilterable + * @param $isFilterableInSearch + * @param $expected + * @return void + */ + public function testIsSearchable( + $isSearchable, + $isVisibleInAdvancedSearch, + $isFilterable, + $isFilterableInSearch, + $expected + ) { + $this->attribute + ->method('getIsSearchable') + ->willReturn($isSearchable); + $this->attribute + ->method('getIsVisibleInAdvancedSearch') + ->willReturn($isVisibleInAdvancedSearch); + $this->attribute + ->method('getIsFilterable') + ->willReturn($isFilterable); + $this->attribute + ->method('getIsFilterableInSearch') + ->willReturn($isFilterableInSearch); + $this->assertEquals( + $expected, + $this->adapter->isSearchable() + ); + } + + /** + * @dataProvider isAlwaysIndexableProvider + * @param $expected + * @return void + */ + public function testIsAlwaysIndexable($expected) { + $this->assertEquals( + $expected, + $this->adapter->isAlwaysIndexable() + ); + } + + /** + * @dataProvider isDateTimeTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsDateTimeType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isDateTimeType() + ); + } + + /** + * @dataProvider isFloatTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsFloatType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isFloatType() + ); + } + + /** + * @dataProvider isIntegerTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsIntegerType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isIntegerType() + ); + } + + /** + * @dataProvider isBooleanTypeProvider + * @param $frontendInput + * @param $backendType + * @param $expected + * @return void + */ + public function testIsBooleanType($frontendInput, $backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->attribute + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->assertEquals( + $expected, + $this->adapter->isBooleanType() + ); + } + + /** + * @dataProvider isComplexTypeProvider + * @param $frontendInput + * @param $usesSource + * @param $expected + * @return void + */ + public function testIsComplexType($frontendInput, $usesSource, $expected) { + $this->attribute + ->method('usesSource') + ->willReturn($usesSource); + $this->attribute + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->assertEquals( + $expected, + $this->adapter->isComplexType() + ); + } + + /** + * @dataProvider isEavAttributeProvider + * @param $expected + * @return void + */ + public function testIsEavAttribute($expected) { + $this->assertEquals( + $expected, + $this->adapter->isEavAttribute() + ); + } + + /** + * @return array + */ + public function isEavAttributeProvider() + { + return [ + [false], + ]; + } + + /** + * @return array + */ + public function isComplexTypeProvider() + { + return [ + ['select', true, true], + ['multiselect', true, true], + ['multiselect', false, true], + ['int', false, false], + ['int', true, true], + ]; + } + + /** + * @return array + */ + public function isBooleanTypeProvider() + { + return [ + ['select', 'int', true], + ['boolean', 'int', true], + ['boolean', 'varchar', false], + ['select', 'varchar', false], + ['int', 'varchar', false], + ['int', 'int', false], + ]; + } + + /** + * @return array + */ + public function isIntegerTypeProvider() + { + return [ + ['smallint', true], + ['int', true], + ['string', false], + ]; + } + + /** + * @return array + */ + public function isFloatTypeProvider() + { + return [ + ['decimal', true], + ['int', false], + ]; + } + + /** + * @return array + */ + public function isDateTimeTypeProvider() + { + return [ + ['timestamp', true], + ['datetime', true], + ['int', false], + ]; + } + + /** + * @return array + */ + public function isAlwaysIndexableProvider() + { + return [ + [false] + ]; + } + + /** + * @return array + */ + public function isSearchableProvider() + { + return [ + [true, false, false, false, true], + [false, false, false, false, false], + [false, true, false, false, true], + [false, false, true, false, true], + [true, true, true, false, true], + [true, true, false, false, true], + ]; + } + + /** + * @return array + */ + public function isFilterableProvider() + { + return [ + [true, false, true,], + [true, false, true,], + [false, false, false,] + ]; + } + + /** + * @return array + */ + public function isStringServiceFieldTypeProvider() + { + return [ + ['string', 'text', false,], + ['text', 'text', true,] + ]; + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['name', [], 'name'] + ]; + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['type', 'type'] + ]; + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + ['type', 'no', 'no'] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php new file mode 100644 index 0000000000000..4907c89d35aaa --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -0,0 +1,327 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Catalog\Api\CategoryListInterface; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Catalog\Api\Data\CategorySearchResultsInterface; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Customer\Api\Data\GroupSearchResultsInterface; +use Magento\Customer\Api\Data\GroupInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; + +class DynamicFieldTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField + */ + private $provider; + + /** + * @var GroupRepositoryInterface + */ + private $groupRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var CategoryListInterface + */ + private $categoryList; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->groupRepository = $this->getMockBuilder(GroupRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->indexTypeConverter = $this->getMockBuilder(IndexTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->attributeAdapterProvider = $this->getMockBuilder(AttributeProvider::class) + ->disableOriginalConstructor() + ->setMethods(['getByAttributeCode', 'getByAttribute']) + ->getMock(); + $this->fieldNameResolver = $this->getMockBuilder(FieldNameResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldName']) + ->getMock(); + $this->categoryList = $this->getMockBuilder(CategoryListInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->provider = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField::class, + [ + 'groupRepository' => $this->groupRepository, + 'searchCriteriaBuilder' => $this->searchCriteriaBuilder, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'indexTypeConverter' => $this->indexTypeConverter, + 'attributeAdapterProvider' => $this->attributeAdapterProvider, + 'categoryList' => $this->categoryList, + 'fieldNameResolver' => $this->fieldNameResolver, + ] + ); + } + + /** + * @dataProvider attributeProvider + * @param $complexType + * @param $categoryId + * @param $groupId + * @param array $expected + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testGetAllAttributesTypes( + $complexType, + $categoryId, + $groupId, + $expected + ) { + $searchCriteria = $this->getMockBuilder(SearchCriteria::class) + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilder->expects($this->any()) + ->method('create') + ->willReturn($searchCriteria); + $categorySearchResults = $this->getMockBuilder(CategorySearchResultsInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getItems']) + ->getMockForAbstractClass(); + $groupSearchResults = $this->getMockBuilder(GroupSearchResultsInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getItems']) + ->getMockForAbstractClass(); + $group = $this->getMockBuilder(GroupInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $group->expects($this->any()) + ->method('getId') + ->willReturn($groupId); + $groupSearchResults->expects($this->any()) + ->method('getItems') + ->willReturn([$group]); + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn($categoryId); + $categorySearchResults->expects($this->any()) + ->method('getItems') + ->willReturn([$category]); + $this->categoryList->expects($this->any()) + ->method('getList') + ->willReturn($categorySearchResults); + + $categoryAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $categoryAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('category'); + $positionAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $positionAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('position'); + + $this->fieldNameResolver->expects($this->any()) + ->method('getFieldName') + ->will($this->returnCallback( + function($attribute)use ($categoryId) { + static $callCount = array(); + $attributeCode = $attribute->getAttributeCode(); + $callCount[$attributeCode] = !isset($callCount[$attributeCode]) ? 1 : ++$callCount[$attributeCode]; + + if ($attributeCode === 'category') { + return 'category_name_' . $categoryId; + } elseif ($attributeCode === 'position') { + return 'position_' . $categoryId; + } elseif ($attributeCode === 'price') { + return 'price_' . $categoryId . '_1'; + } + } + )); + $priceAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $priceAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('price'); + $this->indexTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('no_index'); + $this->groupRepository->expects($this->any()) + ->method('getList') + ->willReturn($groupSearchResults); + $this->attributeAdapterProvider->expects($this->any()) + ->method('getByAttributeCode') + ->with($this->anything()) + ->will($this->returnCallback( + function($code) use( + $categoryAttributeMock, + $positionAttributeMock, + $priceAttributeMock + ) { + static $callCount = array(); + $callCount[$code] = !isset($callCount[$code]) ? 1 : ++$callCount[$code]; + + if ($code === 'position') { + return $positionAttributeMock; + } elseif ($code === 'category_name') { + return $categoryAttributeMock; + } elseif ($code === 'price') { + return $priceAttributeMock; + } + } + )); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->with($this->anything()) + ->will($this->returnCallback( + function($type) use ($complexType) { + static $callCount = array(); + $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; + + if ($type === 'string') { + return 'string'; + } if ($type === 'string') { + return 'string'; + } elseif($type === 'float') { + return 'float'; + } else { + return $complexType; + } + } + )); + + + $this->assertEquals( + $expected, + $this->provider->getFields(['storeId' => 1]) + ); + } + + /** + * @return array + */ + public function attributeProvider() + { + return [ + [ + 'text', + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ] + ], + [ + null, + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ], + ], + [ + null, + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php new file mode 100644 index 0000000000000..497f3d957e181 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IndexResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + */ + private $resolver; + + /** + * @var ConverterInterface + */ + private $converter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->converter = $this->getMockBuilder(ConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + [ + 'converter' => $this->converter + ] + ); + } + + /** + * @dataProvider getFieldIndexProvider + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $serviceFieldType + * @param $expected + * @return void + */ + public function testGetFieldName( + $isSearchable, + $isAlwaysIndexable, + $serviceFieldType, + $expected + ) { + $this->converter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods([ + 'isSearchable', + 'isAlwaysIndexable', + ]) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + + $this->assertEquals( + $expected, + $this->resolver->getFieldIndex($attributeMock, $serviceFieldType) + ); + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + [true, true, 'string', null], + [false, false, 'string', 'something'], + [true, false, 'string', null], + [false, true, 'string', null], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php new file mode 100644 index 0000000000000..9944874b97a92 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class CategoryNameTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName + */ + private $resolver; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + $this->coreRegistry = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->setMethods(['registry']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName::class, + [ + 'storeManager' => $this->storeManager, + 'coreRegistry' => $this->coreRegistry, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $fromRegistry + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $fromRegistry, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getRootCategoryId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getRootCategoryId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + $category = null; + if ($fromRegistry) { + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn(1); + } + $this->coreRegistry->expects($this->any()) + ->method('registry') + ->willReturn($category); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['category_name', [], true, 'name_category_1'], + ['category_name', [], false, 'name_category_2'], + ['category_name', ['categoryId' => 3], false, 'name_category_3'], + ['price', ['categoryId' => 3], false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php new file mode 100644 index 0000000000000..2fe75d46eb36b --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; + +class DefaultResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver + */ + private $resolver; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMockForAbstractClass(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver::class, + [ + 'fieldTypeResolver' => $this->fieldTypeResolver, + 'fieldTypeConverter' => $this->fieldTypeConverter + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $fieldType + * @param $attributeCode + * @param $frontendInput + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName( + $fieldType, + $attributeCode, + $frontendInput, + $context, + $expected + ) { + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('string'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'getFrontendInput']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($fieldType); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['', 'code', '', [], 'code'], + ['', 'code', '', ['type' => 'default'], 'code'], + ['string', '*', '', ['type' => 'default'], '_all'], + ['', 'code', '', ['type' => 'default'], 'code'], + ['', 'code', 'select', ['type' => 'default'], 'code'], + ['', 'code', 'boolean', ['type' => 'default'], 'code'], + ['', 'code', '', ['type' => 'type'], 'sort_code'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php new file mode 100644 index 0000000000000..c76bb8661d761 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class NotEavAttributeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute + */ + private $resolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute::class + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $isEavAttribute + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $isEavAttribute, $context, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isEavAttribute', 'getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isEavAttribute') + ->willReturn($isEavAttribute); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['code', true, [], ''], + ['code', false, [], 'code'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php new file mode 100644 index 0000000000000..d1d6bb5a91c22 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class PositionTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position + */ + private $resolver; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + $this->coreRegistry = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->setMethods(['registry']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position::class, + [ + 'storeManager' => $this->storeManager, + 'coreRegistry' => $this->coreRegistry, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $fromRegistry + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $fromRegistry, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getRootCategoryId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getRootCategoryId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + $category = null; + if ($fromRegistry) { + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn(1); + } + $this->coreRegistry->expects($this->any()) + ->method('registry') + ->willReturn($category); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['position', [], true, 'position_category_1'], + ['position', [], false, 'position_category_2'], + ['position', ['categoryId' => 2], false, 'position_category_2'], + ['price', ['categoryId' => 2], false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php new file mode 100644 index 0000000000000..649244fd2a33c --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -0,0 +1,107 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class PriceTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price + */ + private $resolver; + + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->customerSession = $this->getMockBuilder(CustomerSession::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerGroupId']) + ->getMock(); + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price::class, + [ + 'customerSession' => $this->customerSession, + 'storeManager' => $this->storeManager, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->customerSession->expects($this->any()) + ->method('getCustomerGroupId') + ->willReturn(1); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getWebsiteId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getWebsiteId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['price', [], 'price_1_2'], + ['price', ['customerGroupId' => 2, 'websiteId' => 3], 'price_2_3'], + ['price', ['customerGroupId' => 2], 'price_2_2'], + ['sku', ['customerGroupId' => 2], ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php new file mode 100644 index 0000000000000..849bf0e35bf48 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class SpecialAttributeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute + */ + private $resolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute::class + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['id', 'id'], + ['sku', 'sku'], + ['store_id', 'store_id'], + ['visibility', 'visibility'], + ['price', ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php new file mode 100644 index 0000000000000..eec577988d046 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\FieldProvider\Product\FieldType; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Psr\Log\LoggerInterface; + +class ConverterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter + */ + private $converter; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->logger = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->converter = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class, + [ + 'logger' => $this->logger, + ] + ); + } + + /** + * @dataProvider convertProvider + * @param $internalType + * @param $expected + * @return void + */ + public function testConvert($internalType, $expected) + { + $this->assertEquals( + $expected, + $this->converter->convert($internalType) + ); + } + + /** + * @return array + */ + public function convertProvider() + { + return [ + ['string', 'string'], + ['float', 'float'], + ['integer', 'integer'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php new file mode 100644 index 0000000000000..43eff23702aa7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class DateTimeTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isDateTimeType + * @param $expected + * @return void + */ + public function testGetFieldType($isDateTimeType, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isDateTimeType']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isDateTimeType') + ->willReturn($isDateTimeType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, 'something'], + [false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php new file mode 100644 index 0000000000000..983a1b941a2c3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class DefaultResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $expected + * @return void + */ + public function testGetFieldType($expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->getMock(); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['something'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php new file mode 100644 index 0000000000000..757d830bb49b3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class FloatTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isFloatType + * @param $expected + * @return void + */ + public function testGetFieldType($isFloatType, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isFloatType']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isFloatType') + ->willReturn($isFloatType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, 'something'], + [false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php new file mode 100644 index 0000000000000..bd88b4bcc8a1b --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IntegerTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $attributeCode + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $expected + * @return void + */ + public function testGetFieldType($attributeCode, $isIntegerType, $isBooleanType, $isUserDefined, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'isIntegerType', 'isBooleanType', 'isUserDefined']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['category_ids', true, true, true, null], + ['category_ids', false, false, false, null], + ['type', true, false, false, 'something'], + ['type', false, true, false, 'something'], + ['type', true, true, true, ''], + ['type', false, false, true, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php new file mode 100644 index 0000000000000..1efc31ac0942f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -0,0 +1,245 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface + as FieldIndexResolver; + +class StaticFieldTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField + */ + private $provider; + + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldIndexResolver + */ + private $fieldIndexResolver; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->eavConfig = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->setMethods(['getEntityAttributes']) + ->getMock(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->indexTypeConverter = $this->getMockBuilder(IndexTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->attributeAdapterProvider = $this->getMockBuilder(AttributeProvider::class) + ->disableOriginalConstructor() + ->setMethods(['getByAttributeCode']) + ->getMock(); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMock(); + $this->fieldIndexResolver = $this->getMockBuilder(FieldIndexResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldIndex']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->provider = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField::class, + [ + 'eavConfig' => $this->eavConfig, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'indexTypeConverter' => $this->indexTypeConverter, + 'attributeAdapterProvider' => $this->attributeAdapterProvider, + 'fieldIndexResolver' => $this->fieldIndexResolver, + 'fieldTypeResolver' => $this->fieldTypeResolver, + ] + ); + } + + /** + * @dataProvider attributeProvider + * @param string $attributeCode + * @param string $inputType + * @param $indexType + * @param $isComplexType + * @param $complexType + * @param array $expected + * @return void + */ + public function testGetAllAttributesTypes( + $attributeCode, + $inputType, + $indexType, + $isComplexType, + $complexType, + $expected + ) { + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($inputType); + $this->fieldIndexResolver->expects($this->any()) + ->method('getFieldIndex') + ->willReturn($indexType); + $this->indexTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('no'); + + $productAttributeMock = $this->getMockBuilder(AbstractAttribute::class) + ->setMethods(['getAttributeCode']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $productAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->eavConfig->expects($this->any())->method('getEntityAttributes') + ->willReturn([$productAttributeMock]); + + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isComplexType', 'getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->attributeAdapterProvider->expects($this->any()) + ->method('getByAttributeCode') + ->with($this->anything()) + ->willReturn($attributeMock); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->with($this->anything()) + ->will($this->returnCallback( + function($type) use ($complexType) { + static $callCount = array(); + $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; + + if ($type === 'string') { + return 'string'; + } if ($type === 'string') { + return 'string'; + } elseif($type === 'float') { + return 'float'; + } else { + return $complexType; + } + } + )); + + + $this->assertEquals( + $expected, + $this->provider->getFields(['storeId' => 1]) + ); + } + + /** + * @return array + */ + public function attributeProvider() + { + return [ + [ + 'category_ids', + 'select', + true, + true, + 'text', + [ + 'category_ids' => [ + 'type' => 'select', + 'index' => true + ], + 'category_ids_value' => [ + 'type' => 'string' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ] + ], + [ + 'attr_code', + 'text', + 'no', + false, + null, + [ + 'attr_code' => [ + 'type' => 'text', + 'index' => 'no' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ], + ], + [ + 'attr_code', + 'text', + null, + false, + null, + [ + 'attr_code' => [ + 'type' => 'text' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php deleted file mode 100644 index 8b7ac6abbb190..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php +++ /dev/null @@ -1,298 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper; - -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Model\Adapter\FieldType; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -class ProductFieldMapperTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper - */ - protected $mapper; - - /** - * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject - */ - protected $coreRegistry; - - /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSession; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $storeManager; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * @var FieldType|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldType; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $store; - - /** - * Set up test environment - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $this->fieldType = $this->getMockBuilder(FieldType::class) - ->disableOriginalConstructor() - ->setMethods(['getFieldType']) - ->getMock(); - - $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['getCustomerGroupId']) - ->getMock(); - - $this->storeManager = $this->storeManager = $this->getMockForAbstractClass( - \Magento\Store\Model\StoreManagerInterface::class, - [], - '', - false - ); - - $this->store = $this->getMockForAbstractClass( - \Magento\Store\Api\Data\StoreInterface::class, - [], - '', - false, - false, - true, - ['getWebsiteId', 'getRootCategoryId'] - ); - - $this->coreRegistry = $this->createMock(\Magento\Framework\Registry::class); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->mapper = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper::class, - [ - 'eavConfig' => $this->eavConfig, - 'storeManager' => $this->storeManager, - 'fieldType' => $this->fieldType, - 'customerSession' => $this->customerSession, - 'coreRegistry' => $this->coreRegistry - ] - ); - } - - /** - * @dataProvider attributeCodeProvider - * @param string $attributeCode - * @param string $fieldName - * @param string $fieldType - * @param array $context - * - * @return void - */ - public function testGetFieldName($attributeCode, $fieldName, $fieldType, $context = []) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttribute']) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSession->expects($this->any()) - ->method('getCustomerGroupId') - ->willReturn('0'); - - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - $this->store->expects($this->any()) - ->method('getWebsiteId') - ->willReturn('1'); - $this->store->expects($this->any()) - ->method('getRootCategoryId') - ->willReturn('1'); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue('select')); - - $this->fieldType->expects($this->any())->method('getFieldType') - ->with($attributeMock) - ->willReturn($fieldType); - - $this->assertEquals( - $fieldName, - $this->mapper->getFieldName($attributeCode, $context) - ); - } - - /** - * @return void - */ - public function testGetFieldNameWithoutAttribute() - { - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, 'attr1') - ->willReturn(''); - - $this->assertEquals( - 'attr1', - $this->mapper->getFieldName('attr1', []) - ); - } - - /** - * @dataProvider attributeProvider - * @param string $attributeCode - * @param string $inputType - * @param array $searchAttributes - * @param array $expected - * @return void - */ - public function testGetAllAttributesTypes($attributeCode, $inputType, $searchAttributes, $expected) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->eavConfig->expects($this->any())->method('getEntityAttributeCodes') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE) - ->willReturn([$attributeCode]); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $this->fieldType->expects($this->once())->method('getFieldType')->willReturn(FieldType::ES_DATA_TYPE_INT); - - $attributeMock->expects($this->any()) - ->method('getIsSearchable') - ->willReturn($searchAttributes['searchable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterable') - ->willReturn($searchAttributes['filterable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterableInSearch') - ->willReturn($searchAttributes['filterableInSearch']); - $attributeMock->expects($this->any()) - ->method('getIsVisibleInAdvancedSearch') - ->willReturn($searchAttributes['advSearch']); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($inputType)); - - $this->assertEquals( - $expected, - $this->mapper->getAllAttributesTypes() - ); - } - - /** - * @return array - */ - public function attributeCodeProvider() - { - return [ - ['id', 'id', 'string'], - ['status', 'status', 'string'], - ['status', 'status_value', 'string', ['type'=>'default']], - ['price', 'price_0_1', 'string', ['type'=>'default']], - ['position', 'position_category_1', 'string', ['type'=>'default']], - ['price', 'price_2_3', 'string', ['type'=>'default', 'customerGroupId'=>'2', 'websiteId'=>'3']], - ['position', 'position_category_3', 'string', ['type'=>'default', 'categoryId'=>'3']], - ['color', 'color_value', 'string', ['type'=>'text']], - ['description', 'sort_description', 'string', ['type'=>'some']], - ['*', '_all', 'string', ['type'=>'text']], - ['description', 'description_value', 'string', ['type'=>'text']], - ]; - } - - /** - * @return array - */ - public function attributeProvider() - { - return [ - [ - 'category_ids', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['category_ids' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer', 'index' => 'no']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer', 'index' => 'no']] - ], - [ - 'attr_code', - 'string', - ['searchable' => true, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '1', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => true], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '1', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 18772756b12a2..8e39e048cfba6 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,7 +7,12 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -272,29 +277,139 @@ </argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper\CategoryFieldsProvider"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</argument> + <argument name="items" xsi:type="array"> + <item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item> + <item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item> + <item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item> + <item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item> + <item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item> + </argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldNameResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item> + <item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item> + <item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item> + <item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item> + <item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item> + <item name="default" xsi:type="object">elasticsearch5FieldNameDefaultResolver</item> + </argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldNameDefaultResolver" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver"> + <arguments> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="integer" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item> + <item name="datetime" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType</item> + <item name="float" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType</item> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver</item> + </argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="keyword" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType</item> + <item name="integer" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item> + <item name="datetime" xsi:type="object">elasticsearch5FieldTypeDateTimeResolver</item> + <item name="float" xsi:type="object">elasticsearch5FieldTypeFloatResolver</item> + <item name="default" xsi:type="object">elasticsearch5FieldTypeDefaultResolver</item> + </argument> + </arguments> + </type> + <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="static" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField</item> + <item name="dynamic" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField</item> + </argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldProvider" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="static" xsi:type="object">elasticsearch5StaticFieldProvider</item> + <item name="dynamic" xsi:type="object">elasticsearch5DynamicFieldProvider</item> + </argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5StaticFieldProvider" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="indexTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + <argument name="fieldIndexResolver" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver</argument> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5DynamicFieldProvider" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="indexTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldTypeDateTimeResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldTypeFloatResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldTypeDefaultResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper"> + <arguments> + <argument name="fieldProvider" xsi:type="object">elasticsearch5FieldProvider</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</argument> + <argument name="attributeAdapterProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider</argument> + <argument name="fieldProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</argument> + <argument name="converter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> </arguments> </type> </config> From 704e082d9f9df714a606e82e41d3d58cd967ec2b Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 2 Oct 2018 18:04:49 +0300 Subject: [PATCH 0524/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../CategoryFieldsProvider.php | 1 - .../Adapter/DataMapper/ProductDataMapper.php | 2 +- .../FieldProvider/FieldIndex/Converter.php | 10 +++- .../FieldIndex/IndexResolver.php | 4 +- .../FieldProvider/FieldType/Converter.php | 10 +++- .../FieldType/Resolver/CompositeResolver.php | 9 +++- .../FieldType/Resolver/IntegerType.php | 5 +- .../FieldType/Resolver/KeywordType.php | 5 +- .../FieldMapper/ProductFieldMapper.php | 1 - .../CategoryFieldsProvider.php | 1 - .../Adapter/DataMapper/ProductDataMapper.php | 1 - .../FieldMapper/Product/AttributeAdapter.php | 12 ++--- .../AttributeAdapter/DummyAttribute.php | 49 ++++++++++++++++++- .../FieldMapper/Product/AttributeProvider.php | 32 +++++++++--- .../Product/CompositeFieldProvider.php | 10 +++- .../Product/FieldProvider/DynamicField.php | 48 ++++++++++++------ .../FieldProvider/FieldIndex/Converter.php | 11 ++++- .../FieldIndex/ConverterInterface.php | 2 +- .../FieldIndex/IndexResolver.php | 6 +-- .../FieldName/Resolver/CategoryName.php | 28 +++++++++-- .../FieldName/Resolver/CompositeResolver.php | 12 +++-- .../FieldName/Resolver/DefaultResolver.php | 16 +++++- .../FieldName/Resolver/NotEavAttribute.php | 6 ++- .../FieldName/Resolver/Position.php | 22 +++++++-- .../FieldName/Resolver/Price.php | 33 ++++++++++--- .../FieldName/Resolver/SpecialAttribute.php | 6 ++- .../FieldProvider/FieldType/Converter.php | 11 ++++- .../FieldType/Resolver/CompositeResolver.php | 9 +++- .../FieldType/Resolver/DateTimeType.php | 5 +- .../FieldType/Resolver/DefaultResolver.php | 5 +- .../FieldType/Resolver/FloatType.php | 5 +- .../FieldType/Resolver/IntegerType.php | 5 +- .../Product/FieldProvider/StaticField.php | 12 +++-- .../Elasticsearch/Model/Adapter/FieldType.php | 3 +- .../FieldIndex/IndexResolverTest.php | 9 ++-- .../FieldType/Resolver/IntegerTypeTest.php | 8 ++- .../FieldType/Resolver/KeywordTypeTest.php | 8 ++- .../Product/AttributeAdapterTest.php | 29 +++++++---- .../FieldProvider/DynamicFieldTest.php | 23 +++++---- .../FieldIndex/IndexResolverTest.php | 3 ++ .../FieldName/Resolver/CategoryNameTest.php | 8 ++- .../Resolver/DefaultResolverTest.php | 8 ++- .../Resolver/NotEavAttributeTest.php | 3 ++ .../FieldName/Resolver/PositionTest.php | 3 ++ .../FieldName/Resolver/PriceTest.php | 3 ++ .../Resolver/SpecialAttributeTest.php | 8 ++- .../FieldProvider/FieldType/ConverterTest.php | 20 ++------ .../FieldType/Resolver/DateTimeTypeTest.php | 8 ++- .../Resolver/DefaultResolverTest.php | 8 ++- .../FieldType/Resolver/FloatTypeTest.php | 3 ++ .../FieldType/Resolver/IntegerTypeTest.php | 8 ++- .../Product/FieldProvider/StaticFieldTest.php | 13 +++-- app/code/Magento/Elasticsearch/etc/di.xml | 1 + 53 files changed, 432 insertions(+), 139 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 7892e18b9ee4c..2ff37dab4fd2d 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -71,7 +71,6 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array - * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index de72485ddb84f..8c4022604afdf 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -390,7 +390,7 @@ protected function getProductPriceData($productId, $storeId, array $priceIndexDa foreach ($productPriceIndexData as $customerGroupId => $price) { $fieldName = $this->fieldMapper->getFieldName( 'price', - ['customerGroupId' => $customerGroupId] + ['customerGroupId' => $customerGroupId, 'websiteId' => $storeId] ); $result[$fieldName] = sprintf('%F', $price); } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index b68d5e6f62d14..152c43d95e360 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -6,6 +6,7 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal index type to elastic service. @@ -27,10 +28,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field index type for elasticsearch 5. + * + * @param string $internalType + * @return string|boolean + * @throws LocalizedException */ public function convert(string $internalType) { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 21429bc564374..7812018516151 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -15,8 +15,8 @@ as FieldTypeResolver; /** - * Field index resolver that provide index type for attribute in mapping. - * For example we need to set 'no'/false in case when attribute must be present in index data, + * Field index resolver that provides index type for the attribute in mapping. + * For example, we need to set ‘no’/false in the case when attribute must be present in index data, * but stay as not indexable. */ class IndexResolver implements ResolverInterface diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 9cb773adf914d..58215aec8e46e 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -6,6 +6,7 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal data types to elastic service. @@ -36,10 +37,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field type for elasticsearch 5. + * + * @param string $internalType + * @return string + * @throws LocalizedException */ public function convert(string $internalType): string { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 719af357263d6..c1456dc55b0f1 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,11 +24,16 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index b777eb7e96ba5..d0ddd6115e557 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -36,7 +36,10 @@ public function __construct(ConverterInterface $fieldTypeConverter, $integerType } /** - * {@inheritdoc} + * Get integer field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php index 77ef77aaf8740..e27376f415610 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index e34e62a774925..463a7770357ad 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -107,7 +107,6 @@ public function __construct( * @param string $attributeCode * @param array $context * @return string - * @throws \Magento\Framework\Exception\LocalizedException */ public function getFieldName($attributeCode, $context = []) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 8feb8eb6088cc..fc557d427feea 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -71,7 +71,6 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array - * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index 1ca24a0c73025..f2082dd5fc243 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -14,5 +14,4 @@ */ class ProductDataMapper extends ElasticSearch5ProductDataMapper implements DataMapperInterface { - // } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php index 0661e86edceb7..6cfe4a256b11c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -6,7 +6,7 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; -use Magento\Framework\Model\AbstractExtensibleModel; +use Magento\Framework\Api\CustomAttributesDataInterface; /** * Product attribute adapter for elasticsearch context. @@ -14,7 +14,7 @@ class AttributeAdapter { /** - * @var AbstractExtensibleModel + * @var CustomAttributesDataInterface */ private $attribute; @@ -24,11 +24,11 @@ class AttributeAdapter private $attributeCode; /** - * @param AbstractExtensibleModel $attribute + * @param CustomAttributesDataInterface $attribute * @param string $attributeCode */ public function __construct( - AbstractExtensibleModel $attribute, + CustomAttributesDataInterface $attribute, string $attributeCode ) { $this->attribute = $attribute; @@ -168,9 +168,9 @@ public function getFrontendInput() /** * Get product attribute instance. * - * @return AbstractExtensibleModel|\Magento\Eav\Api\Data\AttributeInterface + * @return CustomAttributesDataInterface|\Magento\Eav\Api\Data\AttributeInterface */ - private function getAttribute(): AbstractExtensibleModel + private function getAttribute(): CustomAttributesDataInterface { return $this->attribute; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index de824e4aeedb2..99fa1dc2c389c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -5,10 +5,55 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Api\CustomAttributesDataInterface; + /** * Dummy class for Not EAV attribute. */ -class DummyAttribute extends \Magento\Framework\Model\AbstractExtensibleModel +class DummyAttribute implements CustomAttributesDataInterface { - // + /** + * Get an attribute value. + * + * @param string $attributeCode + * @return \Magento\Framework\Api\AttributeInterface|null + */ + public function getCustomAttribute($attributeCode) + { + return null; + } + + /** + * Set an attribute value for a given attribute code + * + * @param string $attributeCode + * @param mixed $attributeValue + * @return $this + */ + public function setCustomAttribute($attributeCode, $attributeValue) + { + return $this; + } + + /** + * Retrieve custom attributes values. + * + * @return \Magento\Framework\Api\AttributeInterface[]|null + */ + public function getCustomAttributes() + { + return null; + } + + /** + * Set array of custom attributes + * + * @param \Magento\Framework\Api\AttributeInterface[] $attributes + * @return $this + * @throws \LogicException + */ + public function setCustomAttributes(array $attributes) + { + return $this; + } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 8ae100f177494..1ab9d974aa75d 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -1,10 +1,15 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; use Magento\Eav\Model\Config; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; +use Magento\Framework\Exception\LocalizedException; +use Psr\Log\LoggerInterface; /** * Provide attribute adapter. @@ -16,14 +21,14 @@ class AttributeProvider * * @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager = null; + private $objectManager; /** * Instance name to create * * @var string */ - private $instanceName = null; + private $instanceName; /** * @var Config @@ -35,21 +40,29 @@ class AttributeProvider */ private $cachedPool = []; + /** + * @var LoggerInterface + */ + private $logger; + /** * Factory constructor * * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param Config $eavConfig + * @param LoggerInterface $logger * @param string $instanceName */ public function __construct( \Magento\Framework\ObjectManagerInterface $objectManager, Config $eavConfig, - $instanceName = 'Magento\\Elasticsearch\\Model\\Adapter\\FieldMapper\\Product\\AttributeAdapter' + LoggerInterface $logger, + $instanceName = AttributeAdapter::class ) { $this->objectManager = $objectManager; $this->instanceName = $instanceName; $this->eavConfig = $eavConfig; + $this->logger = $logger; } /** @@ -57,12 +70,19 @@ public function __construct( * * @param string $attributeCode * @return AttributeAdapter - * @throws \Magento\Framework\Exception\LocalizedException */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { if (!isset($this->cachedPool[$attributeCode])) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + $attribute = null; + try { + $attribute = $this->eavConfig->getAttribute( + ProductAttributeInterface::ENTITY_TYPE_CODE, + $attributeCode + ); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } if (null === $attribute) { $attribute = $this->objectManager->create(DummyAttribute::class); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index 7d0d5fccbcf6c..3fc18ec925a48 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; @@ -13,11 +17,13 @@ class CompositeFieldProvider implements FieldProviderInterface private $providers; /** - * @param array $providers + * @param FieldProviderInterface[] $providers */ public function __construct(array $providers) { - $this->providers = $providers; + $this->providers = (function (FieldProviderInterface ...$providers) { + return $providers; + })(...$providers); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index a7773f0afda7e..757591e2dbba7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Catalog\Api\CategoryListInterface; @@ -13,6 +16,8 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Exception\LocalizedException; +use Psr\Log\LoggerInterface; /** * Provide dynamic fields for product. @@ -60,6 +65,11 @@ class DynamicField implements FieldProviderInterface */ private $fieldNameResolver; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param FieldTypeConverterInterface $fieldTypeConverter * @param IndexTypeConverterInterface $indexTypeConverter @@ -68,6 +78,7 @@ class DynamicField implements FieldProviderInterface * @param CategoryListInterface $categoryList * @param FieldNameResolver $fieldNameResolver * @param AttributeProvider $attributeAdapterProvider + * @param LoggerInterface $logger */ public function __construct( FieldTypeConverterInterface $fieldTypeConverter, @@ -76,7 +87,8 @@ public function __construct( SearchCriteriaBuilder $searchCriteriaBuilder, CategoryListInterface $categoryList, FieldNameResolver $fieldNameResolver, - AttributeProvider $attributeAdapterProvider + AttributeProvider $attributeAdapterProvider, + LoggerInterface $logger ) { $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; @@ -85,10 +97,14 @@ public function __construct( $this->categoryList = $categoryList; $this->fieldNameResolver = $fieldNameResolver; $this->attributeAdapterProvider = $attributeAdapterProvider; + $this->logger = $logger; } /** - * {@inheritdoc} + * Get mapping for dynamic fields. + * + * @param array $context + * @return array */ public function getFields(array $context = []): array { @@ -116,17 +132,21 @@ public function getFields(array $context = []): array ]; } - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); - foreach ($groups as $group) { - $groupPriceKey = $this->fieldNameResolver->getFieldName( - $priceAttribute, - ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] - ); - $allAttributes[$groupPriceKey] = [ - 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), - 'store' => true - ]; + try { + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; + } + } catch (LocalizedException $exception) { + $this->logger->critical($exception); } return $allAttributes; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index bd24fe6fa82a3..31da3fe79118c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -5,6 +5,8 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; +use Magento\Framework\Exception\LocalizedException; + /** * Field type converter from internal index type to elastic service. */ @@ -25,10 +27,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field index type for elasticsearch 2. + * + * @param string $internalType + * @return string|boolean + * @throws LocalizedException */ public function convert(string $internalType) { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php index 8199639fb8045..968f73e2b5d92 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -17,7 +17,7 @@ interface ConverterInterface public const INTERNAL_INDEX_VALUE = 'index'; /** - * Get service field type. + * Get service field index type. * * @param string $internalType * @return string|boolean diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 5a7203bf30bf6..c5fcf758da325 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -9,8 +9,8 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; /** - * Field index resolver that provide index type for attribute in mapping. - * For example we need to set 'no'/false in case when attribute must be present in index data, + * Field index resolver that provides index type for the attribute in mapping. + * For example, we need to set ‘no’/false in the case when attribute must be present in index data, * but stay as not indexable. */ class IndexResolver implements ResolverInterface @@ -34,7 +34,7 @@ public function __construct(ConverterInterface $converter) public function getFieldIndex(AttributeAdapter $attribute) { $index = null; - if (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable()) { + if (!($attribute->isSearchable() || $attribute->isAlwaysIndexable())) { $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index 1ad42a55cbbd4..d270cee431176 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -7,10 +7,12 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; +use Psr\Log\LoggerInterface; /** * Resolver field name for Category name attribute. @@ -28,13 +30,21 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { + $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -42,7 +52,11 @@ public function __construct( } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -58,16 +72,20 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin * * @param array $context * @return int - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; + try { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 81ce3bf030806..0a7b2ae9538d7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -20,15 +20,21 @@ class CompositeResolver implements ResolverInterface private $items; /** - * @param array $items + * @param ResolverInterface[] $items */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index ab5486f3af292..b3f1a1d716557 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -42,7 +42,11 @@ public function __construct( } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -82,6 +86,8 @@ private function isStringServiceFieldType(string $serviceFieldType): bool } /** + * Get field name for query type fields. + * * @param string $frontendInput * @param string $fieldType * @param string $attributeCode @@ -98,6 +104,8 @@ private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCod } /** + * Prepare field name for complex fields. + * * @param string $frontendInput * @param string $fieldType * @param string $attributeCode @@ -105,9 +113,13 @@ private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCod */ private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) { + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); switch ($frontendInput) { case 'select': - return in_array($fieldType, ['text', 'integer'], true) ? $attributeCode . '_value' : $attributeCode; + case 'multiselect': + return in_array($fieldType, [$stringTypeKey, 'integer'], true) + ? $attributeCode . '_value' + : $attributeCode; case 'boolean': return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; default: diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php index 094148aa3e632..d92730595abfd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -15,7 +15,11 @@ class NotEavAttribute implements ResolverInterface { /** - * {@inheritdoc} + * Get field name for not EAV attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index beb1a675e89da..2e7ea841949f4 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -7,10 +7,12 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; +use Psr\Log\LoggerInterface; /** * Resolver field name for position attribute. @@ -28,13 +30,21 @@ class Position implements ResolverInterface private $coreRegistry; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { + $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -58,16 +68,20 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin * * @param array $context * @return int - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context) { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; + try { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 4449ec57523b9..89d43d7f5919f 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -7,9 +7,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Psr\Log\LoggerInterface; /** * Resolver field name for price attribute. @@ -27,17 +29,31 @@ class Price implements ResolverInterface private $storeManager; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param CustomerSession $customerSession * @param StoreManager $storeManager */ - public function __construct(CustomerSession $customerSession, StoreManager $storeManager) - { + public function __construct( + LoggerInterface $logger, + CustomerSession $customerSession = null, + StoreManager $storeManager = null + ) { $this->customerSession = $customerSession; $this->storeManager = $storeManager; + $this->logger = $logger; } /** - * {@inheritdoc} + * Get field name for price type attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -45,9 +61,14 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin $customerGroupId = !empty($context['customerGroupId']) ? $context['customerGroupId'] : $this->customerSession->getCustomerGroupId(); - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); + $websiteId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; + try { + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } return 'price_' . $customerGroupId . '_' . $websiteId; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php index 14906fa5cee82..813c6c71c9d1a 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -15,7 +15,11 @@ class SpecialAttribute implements ResolverInterface { /** - * {@inheritdoc} + * Get field name for special list of attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index be8ef76e666fe..0c5f5299344fe 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -5,6 +5,8 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; +use Magento\Framework\Exception\LocalizedException; + /** * Field type converter from internal data types to elastic service. */ @@ -33,10 +35,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field type for elasticsearch 2. + * + * @param string $internalType + * @return string + * @throws LocalizedException */ public function convert(string $internalType): string { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 7a4c06c56d095..6e541f1060898 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,11 +24,16 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php index ff029ff8610f5..3430288f59405 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get datetime field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php index 8e754cddd3e92..894834f30b47c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get default field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php index 9fe03d4cbab49..e45989b54b921 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get float field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index c4280505f1190..3fa24b3b2af56 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get integer field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php index 89748d6428e4d..d15040f24d775 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Eav\Model\Config; @@ -16,7 +19,7 @@ as FieldIndexResolver; /** - * Provide static fields for product. + * Provide static fields for mapping of product. */ class StaticField implements FieldProviderInterface { @@ -75,7 +78,10 @@ public function __construct( } /** - * {@inheritdoc} + * Get static fields. + * + * @param array $context + * @return array */ public function getFields(array $context = []): array { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index be6462156c471..7ad6539e6b718 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -14,7 +14,7 @@ * @api * @since 100.1.0 * - * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @deprecated This class provide not full data about field type. Only basic rules apply in this class. * @see ResolverInterface */ class FieldType @@ -35,6 +35,7 @@ class FieldType /**#@-*/ /** + * * @deprecated * @see ResolverInterface::getFieldType * diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index a4503924c8455..9b0159332d691 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -13,11 +13,15 @@ as FieldTypeConverterInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface as FieldTypeResolver; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver; +/** + * @SuppressWarnings(PHPMD) + */ class IndexResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + * @var IndexResolver */ private $resolver; @@ -58,7 +62,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + IndexResolver::class, [ 'converter' => $this->converter, 'fieldTypeConverter' => $this->fieldTypeConverter, @@ -71,7 +75,6 @@ protected function setUp() * @dataProvider getFieldIndexProvider * @param $isSearchable * @param $isAlwaysIndexable - * @param $stringServiceFieldType * @param $isComplexType * @param $isIntegerType * @param $isBooleanType diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index d4536e4a53b62..5f419dea1f26a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType; +/** + * @SuppressWarnings(PHPMD) + */ class IntegerTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + * @var IntegerType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + IntegerType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index cd0b88e6ce51d..be8b2e30e5f4b 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -9,11 +9,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType; +/** + * @SuppressWarnings(PHPMD) + */ class KeywordTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType + * @var KeywordType */ private $resolver; @@ -37,7 +41,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType::class, + KeywordType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php index ccefb2c4844a7..39543150dd849 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -6,11 +6,15 @@ namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; +use Magento\Framework\Api\CustomAttributesDataInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +/** + * @SuppressWarnings(PHPMD) + */ class AttributeAdapterTest extends \PHPUnit\Framework\TestCase { /** @@ -30,7 +34,7 @@ class AttributeAdapterTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->attribute = $this->getMockBuilder(AbstractExtensibleModel::class) + $this->attribute = $this->getMockBuilder(CustomAttributesDataInterface::class) ->disableOriginalConstructor() ->setMethods([ 'getIsFilterable', @@ -41,7 +45,7 @@ protected function setUp() 'getFrontendInput', 'usesSource', ]) - ->getMock(); + ->getMockForAbstractClass(); $objectManager = new ObjectManagerHelper($this); @@ -114,7 +118,8 @@ public function testIsSearchable( * @param $expected * @return void */ - public function testIsAlwaysIndexable($expected) { + public function testIsAlwaysIndexable($expected) + { $this->assertEquals( $expected, $this->adapter->isAlwaysIndexable() @@ -127,7 +132,8 @@ public function testIsAlwaysIndexable($expected) { * @param $expected * @return void */ - public function testIsDateTimeType($backendType, $expected) { + public function testIsDateTimeType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -143,7 +149,8 @@ public function testIsDateTimeType($backendType, $expected) { * @param $expected * @return void */ - public function testIsFloatType($backendType, $expected) { + public function testIsFloatType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -159,7 +166,8 @@ public function testIsFloatType($backendType, $expected) { * @param $expected * @return void */ - public function testIsIntegerType($backendType, $expected) { + public function testIsIntegerType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -176,7 +184,8 @@ public function testIsIntegerType($backendType, $expected) { * @param $expected * @return void */ - public function testIsBooleanType($frontendInput, $backendType, $expected) { + public function testIsBooleanType($frontendInput, $backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -196,7 +205,8 @@ public function testIsBooleanType($frontendInput, $backendType, $expected) { * @param $expected * @return void */ - public function testIsComplexType($frontendInput, $usesSource, $expected) { + public function testIsComplexType($frontendInput, $usesSource, $expected) + { $this->attribute ->method('usesSource') ->willReturn($usesSource); @@ -214,7 +224,8 @@ public function testIsComplexType($frontendInput, $usesSource, $expected) { * @param $expected * @return void */ - public function testIsEavAttribute($expected) { + public function testIsEavAttribute($expected) + { $this->assertEquals( $expected, $this->adapter->isEavAttribute() diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php index 4907c89d35aaa..b62fab78e6a0e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -24,6 +24,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DynamicFieldTest extends \PHPUnit\Framework\TestCase { /** @@ -184,8 +187,8 @@ public function testGetAllAttributesTypes( $this->fieldNameResolver->expects($this->any()) ->method('getFieldName') ->will($this->returnCallback( - function($attribute)use ($categoryId) { - static $callCount = array(); + function ($attribute) use ($categoryId) { + static $callCount = []; $attributeCode = $attribute->getAttributeCode(); $callCount[$attributeCode] = !isset($callCount[$attributeCode]) ? 1 : ++$callCount[$attributeCode]; @@ -215,12 +218,12 @@ function($attribute)use ($categoryId) { ->method('getByAttributeCode') ->with($this->anything()) ->will($this->returnCallback( - function($code) use( + function ($code) use ( $categoryAttributeMock, $positionAttributeMock, $priceAttributeMock ) { - static $callCount = array(); + static $callCount = []; $callCount[$code] = !isset($callCount[$code]) ? 1 : ++$callCount[$code]; if ($code === 'position') { @@ -236,15 +239,16 @@ function($code) use( ->method('convert') ->with($this->anything()) ->will($this->returnCallback( - function($type) use ($complexType) { - static $callCount = array(); + function ($type) use ($complexType) { + static $callCount = []; $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; if ($type === 'string') { return 'string'; - } if ($type === 'string') { + } + if ($type === 'string') { return 'string'; - } elseif($type === 'float') { + } elseif ($type === 'float') { return 'float'; } else { return $complexType; @@ -252,10 +256,9 @@ function($type) use ($complexType) { } )); - $this->assertEquals( $expected, - $this->provider->getFields(['storeId' => 1]) + $this->provider->getFields(['websiteId' => 1]) ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 497f3d957e181..96cebfe408db5 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -10,6 +10,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @SuppressWarnings(PHPMD) + */ class IndexResolverTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php index 9944874b97a92..1cdeb0ac867b4 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -12,11 +12,15 @@ use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName; +/** + * @SuppressWarnings(PHPMD) + */ class CategoryNameTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName + * @var CategoryName */ private $resolver; @@ -49,7 +53,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName::class, + CategoryName::class, [ 'storeManager' => $this->storeManager, 'coreRegistry' => $this->coreRegistry, diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 2fe75d46eb36b..3d2ecadd28463 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -12,11 +12,15 @@ as FieldTypeResolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DefaultResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver + * @var DefaultResolver */ private $resolver; @@ -48,7 +52,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver::class, + DefaultResolver::class, [ 'fieldTypeResolver' => $this->fieldTypeResolver, 'fieldTypeConverter' => $this->fieldTypeConverter diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index c76bb8661d761..3178c430835e1 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -13,6 +13,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class NotEavAttributeTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php index d1d6bb5a91c22..104db78d3c08f 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -13,6 +13,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class PositionTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php index 649244fd2a33c..584b7bf95f41c 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -12,6 +12,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class PriceTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php index 849bf0e35bf48..6efd7acee665a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -8,11 +8,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute; +/** + * @SuppressWarnings(PHPMD) + */ class SpecialAttributeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute + * @var SpecialAttribute */ private $resolver; @@ -26,7 +30,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute::class + SpecialAttribute::class ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php index eec577988d046..1a0fb93441ae7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -4,11 +4,13 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\FieldProvider\Product\FieldType; +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Psr\Log\LoggerInterface; +/** + * @SuppressWarnings(PHPMD) + */ class ConverterTest extends \PHPUnit\Framework\TestCase { /** @@ -16,11 +18,6 @@ class ConverterTest extends \PHPUnit\Framework\TestCase */ private $converter; - /** - * @var LoggerInterface - */ - private $logger; - /** * Set up test environment * @@ -28,17 +25,10 @@ class ConverterTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $objectManager = new ObjectManagerHelper($this); $this->converter = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class, - [ - 'logger' => $this->logger, - ] + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php index 43eff23702aa7..34c36bd456dfe 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType; +/** + * @SuppressWarnings(PHPMD) + */ class DateTimeTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType + * @var DateTimeType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType::class, + DateTimeType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php index 983a1b941a2c3..e086a959bdde7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DefaultResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver + * @var DefaultResolver */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver::class, + DefaultResolver::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php index 757d830bb49b3..435883c847b3c 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -11,6 +11,9 @@ as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @SuppressWarnings(PHPMD) + */ class FloatTypeTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index bd88b4bcc8a1b..bb111f5f5f97a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType; +/** + * @SuppressWarnings(PHPMD) + */ class IntegerTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + * @var IntegerType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + IntegerType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php index 1efc31ac0942f..0937bc570a1d5 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -20,6 +20,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface as FieldIndexResolver; +/** + * @SuppressWarnings(PHPMD) + */ class StaticFieldTest extends \PHPUnit\Framework\TestCase { /** @@ -158,15 +161,16 @@ public function testGetAllAttributesTypes( ->method('convert') ->with($this->anything()) ->will($this->returnCallback( - function($type) use ($complexType) { - static $callCount = array(); + function ($type) use ($complexType) { + static $callCount = []; $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; if ($type === 'string') { return 'string'; - } if ($type === 'string') { + } + if ($type === 'string') { return 'string'; - } elseif($type === 'float') { + } elseif ($type === 'float') { return 'float'; } else { return $complexType; @@ -174,7 +178,6 @@ function($type) use ($complexType) { } )); - $this->assertEquals( $expected, $this->provider->getFields(['storeId' => 1]) diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 8e39e048cfba6..db2d95553d4fc 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -403,6 +403,7 @@ <arguments> <argument name="attributeAdapterProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider</argument> <argument name="fieldProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface</argument> + <argument name="fieldNameResolver" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface</argument> </arguments> </type> <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver"> From d484aae7e66390f921c90e4bce1ce7cfc5b63db2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 3 Oct 2018 14:05:44 +0300 Subject: [PATCH 0525/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../FieldProvider/FieldIndex/Converter.php | 5 +-- .../FieldProvider/FieldType/Converter.php | 5 +-- .../FieldType/Resolver/CompositeResolver.php | 11 +++-- .../FieldMapper/Product/AttributeProvider.php | 19 +++----- .../Product/CompositeFieldProvider.php | 11 +++-- .../Product/FieldProvider/DynamicField.php | 43 ++++++------------- .../FieldProvider/FieldIndex/Converter.php | 6 +-- .../FieldName/Resolver/CategoryName.php | 26 ++--------- .../FieldName/Resolver/CompositeResolver.php | 11 +++-- .../FieldName/Resolver/Position.php | 26 ++--------- .../FieldName/Resolver/Price.php | 34 ++++----------- .../FieldProvider/FieldType/Converter.php | 6 +-- .../FieldType/Resolver/CompositeResolver.php | 11 +++-- 13 files changed, 75 insertions(+), 139 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index 152c43d95e360..a5969f58c27f9 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -6,7 +6,6 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; -use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal index type to elastic service. @@ -32,12 +31,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string|boolean - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType) { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field index type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 58215aec8e46e..ae9db7c5c348e 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -6,7 +6,6 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; -use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal data types to elastic service. @@ -41,12 +40,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType): string { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index c1456dc55b0f1..b098d2aab79bf 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 1ab9d974aa75d..bf8afb5e37530 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -8,7 +8,6 @@ use Magento\Eav\Model\Config; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; -use Magento\Framework\Exception\LocalizedException; use Psr\Log\LoggerInterface; /** @@ -66,23 +65,15 @@ public function __construct( } /** - * Create class instance with specified parameters - * - * @param string $attributeCode - * @return AttributeAdapter + * {@inheritdoc} */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { if (!isset($this->cachedPool[$attributeCode])) { - $attribute = null; - try { - $attribute = $this->eavConfig->getAttribute( - ProductAttributeInterface::ENTITY_TYPE_CODE, - $attributeCode - ); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $attribute = $this->eavConfig->getAttribute( + ProductAttributeInterface::ENTITY_TYPE_CODE, + $attributeCode + ); if (null === $attribute) { $attribute = $this->objectManager->create(DummyAttribute::class); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index 3fc18ec925a48..f1622a900c7b3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -21,9 +21,14 @@ class CompositeFieldProvider implements FieldProviderInterface */ public function __construct(array $providers) { - $this->providers = (function (FieldProviderInterface ...$providers) { - return $providers; - })(...$providers); + foreach ($providers as $provider) { + if (!$provider instanceof FieldProviderInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field provider is expected, got %s instead.', get_class($provider)) + ); + } + } + $this->providers = $providers; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 757591e2dbba7..877b81f367f4c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -16,8 +16,6 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\Exception\LocalizedException; -use Psr\Log\LoggerInterface; /** * Provide dynamic fields for product. @@ -65,11 +63,6 @@ class DynamicField implements FieldProviderInterface */ private $fieldNameResolver; - /** - * @var LoggerInterface - */ - private $logger; - /** * @param FieldTypeConverterInterface $fieldTypeConverter * @param IndexTypeConverterInterface $indexTypeConverter @@ -78,7 +71,6 @@ class DynamicField implements FieldProviderInterface * @param CategoryListInterface $categoryList * @param FieldNameResolver $fieldNameResolver * @param AttributeProvider $attributeAdapterProvider - * @param LoggerInterface $logger */ public function __construct( FieldTypeConverterInterface $fieldTypeConverter, @@ -87,8 +79,7 @@ public function __construct( SearchCriteriaBuilder $searchCriteriaBuilder, CategoryListInterface $categoryList, FieldNameResolver $fieldNameResolver, - AttributeProvider $attributeAdapterProvider, - LoggerInterface $logger + AttributeProvider $attributeAdapterProvider ) { $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; @@ -97,14 +88,10 @@ public function __construct( $this->categoryList = $categoryList; $this->fieldNameResolver = $fieldNameResolver; $this->attributeAdapterProvider = $attributeAdapterProvider; - $this->logger = $logger; } /** - * Get mapping for dynamic fields. - * - * @param array $context - * @return array + * {@inheritdoc} */ public function getFields(array $context = []): array { @@ -132,21 +119,17 @@ public function getFields(array $context = []): array ]; } - try { - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); - foreach ($groups as $group) { - $groupPriceKey = $this->fieldNameResolver->getFieldName( - $priceAttribute, - ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] - ); - $allAttributes[$groupPriceKey] = [ - 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), - 'store' => true - ]; - } - } catch (LocalizedException $exception) { - $this->logger->critical($exception); + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; } return $allAttributes; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index 31da3fe79118c..bbe72821671dc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -5,8 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; -use Magento\Framework\Exception\LocalizedException; - /** * Field type converter from internal index type to elastic service. */ @@ -31,12 +29,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string|boolean - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType) { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field index type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index d270cee431176..d5e2b09f4ea2c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -7,12 +7,10 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; -use Psr\Log\LoggerInterface; /** * Resolver field name for Category name attribute. @@ -30,21 +28,13 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { - $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -68,24 +58,16 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * Resolve category id. - * - * @param array $context - * @return int + * {@inheritdoc} */ private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; - try { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 0a7b2ae9538d7..5f48cc8b1a529 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field name resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 2e7ea841949f4..99c7f82be117e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -7,12 +7,10 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; -use Psr\Log\LoggerInterface; /** * Resolver field name for position attribute. @@ -30,21 +28,13 @@ class Position implements ResolverInterface private $coreRegistry; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { - $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -64,24 +54,16 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * Resolve category id. - * - * @param array $context - * @return int + * {@inheritdoc} */ private function resolveCategoryId($context) { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; - try { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 89d43d7f5919f..a7a4d506859c9 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -6,12 +6,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Framework\App\ObjectManager; use Magento\Customer\Model\Session as CustomerSession; -use Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; -use Psr\Log\LoggerInterface; /** * Resolver field name for price attribute. @@ -29,31 +28,21 @@ class Price implements ResolverInterface private $storeManager; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param CustomerSession $customerSession * @param StoreManager $storeManager */ public function __construct( - LoggerInterface $logger, CustomerSession $customerSession = null, StoreManager $storeManager = null ) { - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->logger = $logger; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->customerSession = $customerSession ?: ObjectManager::getInstance() + ->get(CustomerSession::class); } /** - * Get field name for price type attributes. - * - * @param AttributeAdapter $attribute - * @param array $context - * @return string + * {@inheritdoc} */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -61,14 +50,9 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin $customerGroupId = !empty($context['customerGroupId']) ? $context['customerGroupId'] : $this->customerSession->getCustomerGroupId(); - $websiteId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; - try { - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); return 'price_' . $customerGroupId . '_' . $websiteId; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 0c5f5299344fe..147abc893eba3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -5,8 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; -use Magento\Framework\Exception\LocalizedException; - /** * Field type converter from internal data types to elastic service. */ @@ -39,12 +37,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType): string { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 6e541f1060898..e2a0025625b93 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** From cf0c2dc6f16a01a09c5eb7cb68cf3105b1ed6d5b Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 3 Oct 2018 18:43:06 +0300 Subject: [PATCH 0526/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../FieldType/Resolver/CompositeResolver.php | 4 ++-- .../Product/AttributeAdapter/DummyAttribute.php | 1 + .../FieldName/Resolver/NotEavAttributeTest.php | 9 +++------ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index b098d2aab79bf..bcc6a430e6fa3 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -28,8 +28,8 @@ public function __construct(array $items) if (!$item instanceof ResolverInterface) { throw new \InvalidArgumentException( sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) - ); - } + ); + } } $this->items = $items; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index 99fa1dc2c389c..85e8722627c2b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -9,6 +9,7 @@ /** * Dummy class for Not EAV attribute. + * @SuppressWarnings(PHPMD) */ class DummyAttribute implements CustomAttributesDataInterface { diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index 3178c430835e1..fbf7479d9aa1f 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -6,12 +6,9 @@ namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; -use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Store\Api\Data\StoreInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute; /** * @SuppressWarnings(PHPMD) @@ -19,7 +16,7 @@ class NotEavAttributeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute + * @var NotEavAttribute */ private $resolver; @@ -33,7 +30,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute::class + NotEavAttribute::class ); } From b2279da535d04bc8f545d8e63d14f4c982d4a7bb Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 13:19:36 +0300 Subject: [PATCH 0527/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../CategoryFieldsProvider.php | 13 +++++------ .../Adapter/DataMapper/ProductDataMapper.php | 23 ++++++++++++++----- .../FieldIndex/IndexResolver.php | 2 +- .../FieldMapper/ProductFieldMapper.php | 11 ++++----- .../Model/Adapter/FieldType.php | 2 ++ .../CategoryFieldsProvider.php | 11 ++++----- .../BatchDataMapper/PriceFieldsProvider.php | 13 +++++------ .../Adapter/DataMapper/ProductDataMapper.php | 2 ++ .../Model/Adapter/Elasticsearch.php | 2 +- .../FieldMapper/Product/AttributeProvider.php | 2 +- .../Product/FieldProvider/DynamicField.php | 2 +- .../FieldIndex/IndexResolver.php | 2 +- .../FieldName/Resolver/CategoryName.php | 2 +- .../FieldName/Resolver/Position.php | 2 +- .../FieldName/Resolver/Price.php | 2 +- .../Elasticsearch/Model/Adapter/FieldType.php | 1 + .../FieldType/Resolver/IntegerTypeTest.php | 3 ++- .../FieldType/Resolver/KeywordTypeTest.php | 6 +++-- .../Annotation/AnnotationFormatValidator.php | 2 +- 19 files changed, 59 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 2ff37dab4fd2d..eb7874a936140 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -10,8 +10,7 @@ use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for categories fields @@ -29,29 +28,29 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; /** * @param Index $resourceIndex * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index 8c4022604afdf..f0b7380397235 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -17,10 +17,11 @@ use Magento\Elasticsearch\Model\Adapter\FieldType\Date as DateFieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** + * Don't use this product data mapper class. + * * @deprecated 100.2.0 * @see \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface */ @@ -89,7 +90,7 @@ class ProductDataMapper implements DataMapperInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -103,7 +104,7 @@ class ProductDataMapper implements DataMapperInterface * @param StoreManagerInterface $storeManager * @param DateFieldType $dateFieldType * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Builder $builder, @@ -113,7 +114,7 @@ public function __construct( StoreManagerInterface $storeManager, DateFieldType $dateFieldType, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->builder = $builder; $this->attributeContainer = $attributeContainer; @@ -124,7 +125,7 @@ public function __construct( $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); $this->mediaGalleryRoles = [ self::MEDIA_ROLE_IMAGE, @@ -226,6 +227,8 @@ protected function processAdvancedAttributes($productId, array $productIndexData } /** + * Check value. + * * @param mixed $value * @param Attribute $attribute * @param string $storeId @@ -316,6 +319,8 @@ protected function getProductMediaGalleryData($media, $roles) } /** + * Get media role image. + * * @param string $file * @param array $roles * @return string @@ -326,6 +331,8 @@ protected function getMediaRoleImage($file, $roles) } /** + * Get media role small image. + * * @param string $file * @param array $roles * @return string @@ -336,6 +343,8 @@ protected function getMediaRoleSmallImage($file, $roles) } /** + * Get media role thumbnail. + * * @param string $file * @param array $roles * @return string @@ -346,6 +355,8 @@ protected function getMediaRoleThumbnail($file, $roles) } /** + * Get media role swatch image. + * * @param string $file * @param array $roles * @return string diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 7812018516151..a7b839c99139d 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -52,7 +52,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldIndex(AttributeAdapter $attribute) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 463a7770357ad..5aea87e5e6ae1 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -10,8 +10,7 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; use Magento\Framework\Registry; @@ -59,7 +58,7 @@ class ProductFieldMapper implements FieldMapperInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -74,7 +73,7 @@ class ProductFieldMapper implements FieldMapperInterface * @param CustomerSession $customerSession * @param StoreManager $storeManager * @param Registry $coreRegistry - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver * @param AttributeProvider|null $attributeAdapterProvider * @param FieldProviderInterface|null $fieldProvider */ @@ -84,7 +83,7 @@ public function __construct( CustomerSession $customerSession, StoreManager $storeManager, Registry $coreRegistry, - FieldNameResolver $fieldNameResolver = null, + ResolverInterface $fieldNameResolver = null, AttributeProvider $attributeAdapterProvider = null, FieldProviderInterface $fieldProvider = null ) { @@ -94,7 +93,7 @@ public function __construct( $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldProvider = $fieldProvider ?: ObjectManager::getInstance() diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index 002a787fd031a..3b7e79ae88bcd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -36,6 +36,8 @@ class FieldType /**#@-*/ /** + * Get field type. + * * @deprecated * @see ResolverInterface::getFieldType * diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index fc557d427feea..108721fd8561f 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -10,8 +10,7 @@ use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for categories fields @@ -29,25 +28,25 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; /** * @param Index $resourceIndex * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index 1b749fd7039e5..875d384a20596 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -12,8 +12,7 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for price fields @@ -41,7 +40,7 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -50,14 +49,14 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, StoreManagerInterface $storeManager, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; @@ -65,11 +64,11 @@ public function __construct( $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index f2082dd5fc243..24b740b554fcb 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -9,6 +9,8 @@ use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper as ElasticSearch5ProductDataMapper; /** + * Don't use this product data mapper class. + * * @deprecated 100.2.0 * @see \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface */ diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 8e69001272b27..772868e4e3e59 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -284,8 +284,8 @@ protected function getDocsArrayInBulkIndexFormat( * Checks whether Elasticsearch index and alias exists. * * @param int $storeId - * @param bool $checkAlias * @param string $mappedIndexerId + * @param bool $checkAlias * @return $this */ public function checkIndex( diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index bf8afb5e37530..4338f4f1c8492 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -65,7 +65,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 877b81f367f4c..5e1cee9a0c390 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -91,7 +91,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $context = []): array { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index c5fcf758da325..f6a0b2dfac9fd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -29,7 +29,7 @@ public function __construct(ConverterInterface $converter) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldIndex(AttributeAdapter $attribute) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index d5e2b09f4ea2c..e248b3098d586 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -58,7 +58,7 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * {@inheritdoc} + * @inheritdoc */ private function resolveCategoryId($context): int { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 99c7f82be117e..3869ef8b661c7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -54,7 +54,7 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * {@inheritdoc} + * @inheritdoc */ private function resolveCategoryId($context) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index a7a4d506859c9..4b26d9a8e32a5 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -42,7 +42,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 7ad6539e6b718..97f159d13528d 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -35,6 +35,7 @@ class FieldType /**#@-*/ /** + * Get field type. * * @deprecated * @see ResolverInterface::getFieldType diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index 5f419dea1f26a..b5496628b3af9 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -4,7 +4,8 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; +namespace +Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index be8b2e30e5f4b..84adbdab7acdd 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -4,10 +4,12 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; +namespace +Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType; diff --git a/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php b/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php index 71ad99bb5c3e0..899a65c375321 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php +++ b/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php @@ -125,7 +125,7 @@ private function validateShortDescriptionFormat( $phpcsFile->addFixableError($error, $shortPtr, 'MethodAnnotation'); } if (strtolower($tokens[$shortPtr]['content']) === '{@inheritdoc}') { - $error = '{@inheritdoc} imports only short description, annotation must have long description'; + $error = 'If the @inheritdoc not inline it shouldn’t have braces'; $phpcsFile->addFixableError($error, $shortPtr, 'MethodAnnotation'); } $shortPtrContent = $tokens[$shortPtr]['content']; From 4c1b154e980a20afdf49f84d055d66f189aa6d17 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 14:31:03 +0300 Subject: [PATCH 0528/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../FieldMapper/Product/FieldProvider/FieldIndex/Converter.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolver.php | 1 + .../FieldMapper/Product/FieldProvider/FieldType/Converter.php | 2 ++ .../FieldProvider/FieldType/Resolver/CompositeResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/IntegerType.php | 1 + .../Product/FieldProvider/FieldType/Resolver/KeywordType.php | 1 + .../Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php | 2 +- .../Model/Adapter/FieldMapper/Product/AttributeAdapter.php | 1 + .../FieldMapper/Product/AttributeAdapter/DummyAttribute.php | 2 ++ .../Model/Adapter/FieldMapper/Product/AttributeProvider.php | 2 ++ .../Adapter/FieldMapper/Product/CompositeFieldProvider.php | 1 + .../Adapter/FieldMapper/Product/FieldProvider/DynamicField.php | 2 ++ .../FieldMapper/Product/FieldProvider/FieldIndex/Converter.php | 2 ++ .../Product/FieldProvider/FieldIndex/ConverterInterface.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolver.php | 1 + .../Product/FieldProvider/FieldIndex/ResolverInterface.php | 1 + .../Product/FieldProvider/FieldName/Resolver/CategoryName.php | 1 + .../FieldProvider/FieldName/Resolver/CompositeResolver.php | 1 + .../FieldProvider/FieldName/Resolver/DefaultResolver.php | 1 + .../FieldProvider/FieldName/Resolver/NotEavAttribute.php | 1 + .../Product/FieldProvider/FieldName/Resolver/Position.php | 3 ++- .../Product/FieldProvider/FieldName/Resolver/Price.php | 1 + .../FieldProvider/FieldName/Resolver/SpecialAttribute.php | 1 + .../Product/FieldProvider/FieldName/ResolverInterface.php | 1 + .../FieldMapper/Product/FieldProvider/FieldType/Converter.php | 2 ++ .../Product/FieldProvider/FieldType/ConverterInterface.php | 2 ++ .../FieldProvider/FieldType/Resolver/CompositeResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/DateTimeType.php | 1 + .../FieldProvider/FieldType/Resolver/DefaultResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/FloatType.php | 1 + .../Product/FieldProvider/FieldType/Resolver/IntegerType.php | 1 + .../Product/FieldProvider/FieldType/ResolverInterface.php | 1 + .../Adapter/FieldMapper/Product/FieldProvider/StaticField.php | 2 ++ .../Adapter/FieldMapper/Product/FieldProviderInterface.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolverTest.php | 1 + .../FieldProvider/FieldType/Resolver/IntegerTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/KeywordTypeTest.php | 1 + .../Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php | 1 + .../FieldMapper/Product/FieldProvider/DynamicFieldTest.php | 1 + .../Product/FieldProvider/FieldIndex/IndexResolverTest.php | 1 + .../FieldProvider/FieldName/Resolver/CategoryNameTest.php | 1 + .../FieldProvider/FieldName/Resolver/DefaultResolverTest.php | 1 + .../FieldProvider/FieldName/Resolver/NotEavAttributeTest.php | 1 + .../Product/FieldProvider/FieldName/Resolver/PositionTest.php | 1 + .../Product/FieldProvider/FieldName/Resolver/PriceTest.php | 1 + .../FieldProvider/FieldName/Resolver/SpecialAttributeTest.php | 1 + .../Product/FieldProvider/FieldType/ConverterTest.php | 1 + .../FieldProvider/FieldType/Resolver/DateTimeTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/DefaultResolverTest.php | 1 + .../Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/IntegerTypeTest.php | 1 + .../FieldMapper/Product/FieldProvider/StaticFieldTest.php | 1 + 52 files changed, 64 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index a5969f58c27f9..b7f21696162dd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index a7b839c99139d..954deaec639ef 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index ae9db7c5c348e..1f6e05c9e02fc 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index bcc6a430e6fa3..fed36ff6b1c8f 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index d0ddd6115e557..e5c8dd48c7af3 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php index e27376f415610..e522d4ae5e070 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 108721fd8561f..0e130c24e79d3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -50,7 +50,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php index 6cfe4a256b11c..17ebf9c83903e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index 85e8722627c2b..b8c0da53c53e0 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Api\CustomAttributesDataInterface; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 4338f4f1c8492..89c98d29ae03e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; use Magento\Eav\Model\Config; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index f1622a900c7b3..8038c8c05bc1c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 5e1cee9a0c390..c7e2a4beabb5c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Catalog\Api\CategoryListInterface; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index bbe72821671dc..5abe4972e34d0 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php index 968f73e2b5d92..02c4d29558dad 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index f6a0b2dfac9fd..590430a7e2431 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php index fb87e0756d621..663b1d865fb52 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index e248b3098d586..bc91f04ee380e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 5f48cc8b1a529..f1fed3f06fe35 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index b3f1a1d716557..3208ca7fc6171 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php index d92730595abfd..cbbd15083ee60 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 3869ef8b661c7..044d5d8da9a6c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; @@ -42,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 4b26d9a8e32a5..12e53ca2bd714 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php index 813c6c71c9d1a..4fa16db98639e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php index ecc46d2607cf8..3d36e026f70db 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 147abc893eba3..88dab83698794 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php index e5ec1ce445ab2..3e7c3e9b592bd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index e2a0025625b93..e83502e4fe32e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php index 3430288f59405..a4e3c634ce717 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php index 894834f30b47c..be4a8cca28814 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php index e45989b54b921..a6681a7f676ba 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index 3fa24b3b2af56..7793f60cd1efc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php index 118a440cddef2..43e512ecb025b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php index d15040f24d775..b5c78cbc28f45 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Eav\Model\Config; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php index 2a68e3e2a3708..aaafb699b33bd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 9b0159332d691..98284e49ad85d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index b5496628b3af9..39155e4f4fe02 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index 84adbdab7acdd..0e33498a16fba 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php index 39543150dd849..9ca65d8e675b9 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php index b62fab78e6a0e..ba5e97aa14b54 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 96cebfe408db5..86bcfeb06480e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php index 1cdeb0ac867b4..5ebeac2284435 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 3d2ecadd28463..4fa99f3bf834d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index fbf7479d9aa1f..cdd8dde585a5a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php index 104db78d3c08f..dcfd4d02988da 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php index 584b7bf95f41c..244da5a42e00a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php index 6efd7acee665a..dcbf64bbb2005 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php index 1a0fb93441ae7..842007aee294e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php index 34c36bd456dfe..ca474c4bee17d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php index e086a959bdde7..72b5320a050bd 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php index 435883c847b3c..c69a6f35b1eb4 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index bb111f5f5f97a..7570c8971b27b 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php index 0937bc570a1d5..bf8b601ed43ab 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; From 061af74816ee715eaf312b18a94ca3f30818eb59 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 15:09:05 +0300 Subject: [PATCH 0529/1415] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../Product/FieldProvider/FieldName/Resolver/CategoryName.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index bc91f04ee380e..5824aca6cdd54 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -71,6 +71,6 @@ private function resolveCategoryId($context): int : $this->storeManager->getStore()->getRootCategoryId(); } - return $id; + return (int)$id; } } From 7e56ae60210c2c02b343954e8c29bb6ea25b45e8 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Fri, 12 Oct 2018 13:26:05 +0300 Subject: [PATCH 0530/1415] Fixed the namespace --- .../Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php index f86747aac1259..c7ff1d95617b6 100644 --- a/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php +++ b/app/code/Magento/Backend/Test/Unit/Service/V1/ModuleServiceTest.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Backend\Test\Unit\Model; +namespace Magento\Backend\Test\Unit\Service\V1; use Magento\Backend\Service\V1\ModuleService; use Magento\Framework\Module\ModuleListInterface; From 93b8f297f0890a88deb52e8baefb09af1bed8abf Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Fri, 12 Oct 2018 14:03:11 +0300 Subject: [PATCH 0531/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix static tests --- .../Block/Product/ProductList/Toolbar.php | 14 ++++++++++++++ .../view/frontend/web/js/product/list/toolbar.js | 16 ++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 12c691d1365c3..c7a9fcce7bf7a 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -430,6 +430,8 @@ public function getPagerUrl($params = []) } /** + * Get pager encoded url. + * * @param array $params * @return string */ @@ -624,6 +626,8 @@ public function getLimit() } /** + * Check if limit is current used in toolbar. + * * @param int $limit * @return bool */ @@ -633,6 +637,8 @@ public function isLimitCurrent($limit) } /** + * Pager number of items from which products started on current page. + * * @return int */ public function getFirstNum() @@ -642,6 +648,8 @@ public function getFirstNum() } /** + * Pager number of items products finished on current page. + * * @return int */ public function getLastNum() @@ -651,6 +659,8 @@ public function getLastNum() } /** + * Total number of products in current category. + * * @return int */ public function getTotalNum() @@ -659,6 +669,8 @@ public function getTotalNum() } /** + * Check if current page is the first. + * * @return bool */ public function isFirstPage() @@ -667,6 +679,8 @@ public function isFirstPage() } /** + * Return last page number. + * * @return int */ public function getLastPageNum() diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 7c47f5bd04d5a..b8b6ff65be2b4 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -91,7 +91,7 @@ define([ baseUrl = urlPaths[0], urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], paramData = {}, - parameters, i; + parameters, i, form, params, key, input, formKey; for (i = 0; i < urlParams.length; i++) { parameters = urlParams[i].split('='); @@ -102,25 +102,25 @@ define([ paramData[paramName] = paramValue; if (this.options.post) { - var form = document.createElement('form'); + form = document.createElement('form'); + params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; - var params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; - for (var key in paramData) { - if (params.indexOf(key) !== -1) { - var input = document.createElement('input'); + for (key in paramData) { + if (params.indexOf(key) !== -1) { //eslint-disable-line max-depth + input = document.createElement('input'); input.name = key; input.value = paramData[key]; form.appendChild(input); delete paramData[key]; } } - var formKey = document.createElement('input'); + formKey = document.createElement('input'); formKey.name = 'form_key'; formKey.value = this.options.formKey; form.appendChild(formKey); paramData = $.param(paramData); - baseUrl = baseUrl + (paramData.length ? '?' + paramData : ''); + baseUrl += paramData.length ? '?' + paramData : ''; form.action = baseUrl; form.method = 'POST'; From 2e1d92f89e413f02c2e23b2c9e19870cf3a8e229 Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Fri, 12 Oct 2018 15:06:28 +0300 Subject: [PATCH 0532/1415] Update newsletter module Update module logic when customer have store_id = 0 --- .../Model/ResourceModel/Subscriber.php | 23 ++++++++++++++++--- .../Magento/Newsletter/Model/Subscriber.php | 11 +++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index b6e53b3695f78..57123d6842647 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -5,6 +5,9 @@ */ namespace Magento\Newsletter\Model\ResourceModel; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\ObjectManager; + /** * Newsletter subscriber resource model * @@ -48,6 +51,13 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $mathRandom; + /** + * Store manager + * + * @var StoreManagerInterface + */ + private $storeManager; + /** * Construct * @@ -55,15 +65,19 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * @param \Magento\Framework\Stdlib\DateTime\DateTime $date * @param \Magento\Framework\Math\Random $mathRandom * @param string $connectionName + * @param StoreManagerInterface $storeManager */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Stdlib\DateTime\DateTime $date, \Magento\Framework\Math\Random $mathRandom, - $connectionName = null + $connectionName = null, + StoreManagerInterface $storeManager = null ) { $this->_date = $date; $this->mathRandom = $mathRandom; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManagerInterface::class); parent::__construct($context, $connectionName); } @@ -117,6 +131,9 @@ public function loadByEmail($subscriberEmail) */ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer) { + $storeId = (int)$customer->getStoreId() ?: $this->storeManager + ->getWebsite($customer->getWebsiteId())->getDefaultStore()->getId(); + $select = $this->connection ->select() ->from($this->getMainTable()) @@ -127,7 +144,7 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select, [ 'customer_id' => $customer->getId(), - 'store_id' => $customer->getStoreId() + 'store_id' => $storeId ] ); @@ -145,7 +162,7 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select, [ 'subscriber_email' => $customer->getEmail(), - 'store_id' => $customer->getStoreId() + 'store_id' => $storeId ] ); diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..5527060a6e2f1 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -613,16 +613,17 @@ protected function _updateCustomerSubscription($customerId, $subscribe) $this->setStatus($status); + $storeId = $customerData->getStoreId(); + if ((int)$customerData->getStoreId() === 0) { + $storeId = $this->_storeManager->getWebsite($customerData->getWebsiteId())->getDefaultStore()->getId(); + } + if (!$this->getId()) { - $storeId = $customerData->getStoreId(); - if ($customerData->getStoreId() == 0) { - $storeId = $this->_storeManager->getWebsite($customerData->getWebsiteId())->getDefaultStore()->getId(); - } $this->setStoreId($storeId) ->setCustomerId($customerData->getId()) ->setEmail($customerData->getEmail()); } else { - $this->setStoreId($customerData->getStoreId()) + $this->setStoreId($storeId) ->setEmail($customerData->getEmail()); } From d3827507fa21d4cdc4b02c0b87ede4bf72ce980e Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Fri, 12 Oct 2018 15:07:02 +0300 Subject: [PATCH 0533/1415] Update newsletter module Fix unit tests according to new logic Add integration tests for case when customer have store_id = 0 --- .../Test/Unit/Model/SubscriberTest.php | 15 +++++--- .../Newsletter/Model/Plugin/PluginTest.php | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php index 9809a9ee4e430..6ccbba9f8828b 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php @@ -213,6 +213,7 @@ public function testSubscribeNotLoggedIn() public function testUpdateSubscription() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -234,7 +235,7 @@ public function testUpdateSubscription() ->method('getConfirmationStatus') ->with($customerId) ->willReturn('account_confirmation_required'); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $storeModel = $this->getMockBuilder(\Magento\Store\Model\Store::class) @@ -248,6 +249,7 @@ public function testUpdateSubscription() public function testUnsubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -265,7 +267,7 @@ public function testUnsubscribeCustomerById() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); @@ -274,6 +276,7 @@ public function testUnsubscribeCustomerById() public function testSubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -291,7 +294,7 @@ public function testSubscribeCustomerById() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); @@ -300,6 +303,7 @@ public function testSubscribeCustomerById() public function testSubscribeCustomerById1() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -317,7 +321,7 @@ public function testSubscribeCustomerById1() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); $this->customerAccountManagement->expects($this->once()) @@ -331,6 +335,7 @@ public function testSubscribeCustomerById1() public function testSubscribeCustomerByIdAfterConfirmation() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -348,7 +353,7 @@ public function testSubscribeCustomerByIdAfterConfirmation() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); $this->customerAccountManagement->expects($this->never())->method('getConfirmationStatus'); diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php index 39db400d2d637..dbc666e49b6cf 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php @@ -167,4 +167,42 @@ private function verifySubscriptionNotExist($email) $this->assertEquals(0, (int)$subscriber->getId()); return $subscriber; } + + /** + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + */ + public function testCustomerWithZeroStoreIdIsSubscribed() + { + $objectManager = Bootstrap::getObjectManager(); + + $currentStore = $objectManager->get( + \Magento\Store\Model\StoreManagerInterface::class + )->getStore()->getId(); + + $subscriber = $objectManager->create(\Magento\Newsletter\Model\Subscriber::class); + /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ + $subscriber->setStoreId($currentStore) + ->setCustomerId(0) + ->setSubscriberEmail('customer@example.com') + ->setSubscriberStatus(\Magento\Newsletter\Model\Subscriber::STATUS_SUBSCRIBED) + ->save(); + + /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory */ + $customerFactory = $objectManager->get(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); + $customerDataObject = $customerFactory->create() + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->setStoreId(0) + ->setEmail('customer@example.com'); + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ + $customer = $this->accountManagement->createAccount($customerDataObject); + + $this->customerRepository->save($customer); + + $subscriber->loadByEmail('customer@example.com'); + + $this->assertEquals($customer->getId(), (int)$subscriber->getCustomerId()); + $this->assertEquals($currentStore, (int)$subscriber->getStoreId()); + } } From a169f5c4b780bf6eae65f2ac40accbaca1ef7be3 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 12 Oct 2018 15:21:54 +0300 Subject: [PATCH 0534/1415] MAGETWO-95694: Issue with Magento upgrade within Web Setup Wizard --- setup/pub/magento/setup/app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/pub/magento/setup/app.js b/setup/pub/magento/setup/app.js index b433e3f19c8bf..f0abd15d106c2 100644 --- a/setup/pub/magento/setup/app.js +++ b/setup/pub/magento/setup/app.js @@ -56,6 +56,9 @@ app.config(['$httpProvider', '$stateProvider', function ($httpProvider, $statePr return $delegate; }); }) + .config(['$locationProvider', function($locationProvider) { + $locationProvider.hashPrefix(''); + }]) .run(function ($rootScope, $state) { $rootScope.$state = $state; }); From 88f99b2f23e285a6e9ae0a0eab7ac8bbbe5f66a7 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 12 Oct 2018 15:27:53 +0300 Subject: [PATCH 0535/1415] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Magento/Wishlist/Controller/Index/DownloadCustomOption.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index 9ffec68780aa1..b87afa8e5d0c4 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -6,6 +6,7 @@ namespace Magento\Wishlist\Controller\Index; use Magento\Framework\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Framework\Controller\ResultFactory; @@ -14,7 +15,7 @@ /** * Class DownloadCustomOption. Represents request-flow logic for option's file download */ -class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex +class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex implements HttpGetActionInterface { /** * @var \Magento\Framework\App\Response\Http\FileFactory From 9c01411858079ff9c12b968ea8d681f6edad39b7 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Thu, 14 Jun 2018 09:48:26 +0200 Subject: [PATCH 0536/1415] Fix typehint of customer-data updateSectionId parameters The typehint wrongly indicates the parameter should be a number, where in fact it is a boolean. It is passed through to the server side to the controller action \Magento\Customer\Controller\Section\Load::execute() where it is cast to a boolean and passed as the $updateIds parameter to \Magento\Customer\CustomerData\SectionPool::getSectionsData() and from there as the boolean parameter $forceUpdate to the \Magento\Customer\CustomerData\Section\Identifier::initMark() method. This PR introduces no backward incompatibilities, it only fixes the type hint to make the code more readable and improve compatibility with static code analysis tools. --- .../Magento/Customer/view/frontend/web/js/customer-data.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index cfa06c6e12003..8cbc779a99ab0 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -75,7 +75,7 @@ define([ /** * @param {Object} sectionNames - * @param {Number} updateSectionId + * @param {Boolean} updateSectionId * @return {*} */ getFromServer: function (sectionNames, updateSectionId) { @@ -326,7 +326,7 @@ define([ /** * @param {Array} sectionNames - * @param {Number} updateSectionId + * @param {Boolean} updateSectionId * @return {*} */ reload: function (sectionNames, updateSectionId) { From 696a0c22dac2b426c0685d9b626c323fd62709b1 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sat, 16 Jun 2018 20:51:24 +0200 Subject: [PATCH 0537/1415] Rename parameter variable to make intent more easy to understand. --- .../Customer/view/frontend/web/js/customer-data.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 8cbc779a99ab0..07d08847aa4ea 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -75,17 +75,17 @@ define([ /** * @param {Object} sectionNames - * @param {Boolean} updateSectionId + * @param {Boolean} forceNewSectionTimestamp * @return {*} */ - getFromServer: function (sectionNames, updateSectionId) { + getFromServer: function (sectionNames, forceNewSectionTimestamp) { var parameters; sectionNames = sectionConfig.filterClientSideSections(sectionNames); parameters = _.isArray(sectionNames) ? { sections: sectionNames.join(',') } : []; - parameters['update_section_id'] = updateSectionId; + parameters['update_section_id'] = forceNewSectionTimestamp; return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { throw new Error(jqXHR); @@ -326,11 +326,11 @@ define([ /** * @param {Array} sectionNames - * @param {Boolean} updateSectionId + * @param {Boolean} forceNewSectionTimestamp * @return {*} */ - reload: function (sectionNames, updateSectionId) { - return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) { + reload: function (sectionNames, forceNewSectionTimestamp) { + return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) { $(document).trigger('customer-data-reload', [sectionNames]); buffer.update(sections); }); From 3621c3c9b72278c8fd0b95c88eb9b9475dd4b51e Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Fri, 22 Jun 2018 08:47:36 -0400 Subject: [PATCH 0538/1415] Rename request parameter and variables to make them more expressive --- .../Customer/Controller/Section/Load.php | 8 +++---- .../CustomerData/Section/Identifier.php | 14 +++++------ .../Customer/CustomerData/SectionPool.php | 4 ++-- .../CustomerData/SectionPoolInterface.php | 4 ++-- .../Test/Unit/Controller/Section/LoadTest.php | 24 +++++++++---------- .../Unit/CustomerData/SectionPoolTest.php | 2 +- .../view/frontend/web/js/customer-data.js | 2 +- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php index e55b1d0df26c7..89d4417c79c19 100644 --- a/app/code/Magento/Customer/Controller/Section/Load.php +++ b/app/code/Magento/Customer/Controller/Section/Load.php @@ -71,11 +71,11 @@ public function execute() $sectionNames = $this->getRequest()->getParam('sections'); $sectionNames = $sectionNames ? array_unique(\explode(',', $sectionNames)) : null; - $updateSectionId = $this->getRequest()->getParam('update_section_id'); - if ('false' === $updateSectionId) { - $updateSectionId = false; + $forceNewSectionTimestamp = $this->getRequest()->getParam('force_new_section_timestamp'); + if ('false' === $forceNewSectionTimestamp) { + $forceNewSectionTimestamp = false; } - $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$updateSectionId); + $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$forceNewSectionTimestamp); } catch (\Exception $e) { $resultJson->setStatusHeader( \Zend\Http\Response::STATUS_CODE_400, diff --git a/app/code/Magento/Customer/CustomerData/Section/Identifier.php b/app/code/Magento/Customer/CustomerData/Section/Identifier.php index 2a770925d1c37..54d7cee2d90bd 100644 --- a/app/code/Magento/Customer/CustomerData/Section/Identifier.php +++ b/app/code/Magento/Customer/CustomerData/Section/Identifier.php @@ -43,12 +43,12 @@ public function __construct( /** * Init mark(identifier) for sections * - * @param bool $forceUpdate + * @param bool $forceNewTimestamp * @return int */ - public function initMark($forceUpdate) + public function initMark($forceNewTimestamp) { - if ($forceUpdate) { + if ($forceNewTimestamp) { $this->markId = time(); return $this->markId; } @@ -68,18 +68,18 @@ public function initMark($forceUpdate) * * @param array $sectionsData * @param null $sectionNames - * @param bool $updateIds + * @param bool $forceNewTimestamp * @return array */ - public function markSections(array $sectionsData, $sectionNames = null, $updateIds = false) + public function markSections(array $sectionsData, $sectionNames = null, $forceNewTimestamp = false) { if (!$sectionNames) { $sectionNames = array_keys($sectionsData); } - $markId = $this->initMark($updateIds); + $markId = $this->initMark($forceNewTimestamp); foreach ($sectionNames as $name) { - if ($updateIds || !array_key_exists(self::SECTION_KEY, $sectionsData[$name])) { + if ($forceNewTimestamp || !array_key_exists(self::SECTION_KEY, $sectionsData[$name])) { $sectionsData[$name][self::SECTION_KEY] = $markId; } } diff --git a/app/code/Magento/Customer/CustomerData/SectionPool.php b/app/code/Magento/Customer/CustomerData/SectionPool.php index 0e0d7b992e33a..618d52079973d 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPool.php +++ b/app/code/Magento/Customer/CustomerData/SectionPool.php @@ -55,10 +55,10 @@ public function __construct( /** * {@inheritdoc} */ - public function getSectionsData(array $sectionNames = null, $updateIds = false) + public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false) { $sectionsData = $sectionNames ? $this->getSectionDataByNames($sectionNames) : $this->getAllSectionData(); - $sectionsData = $this->identifier->markSections($sectionsData, $sectionNames, $updateIds); + $sectionsData = $this->identifier->markSections($sectionsData, $sectionNames, $forceNewTimestamp); return $sectionsData; } diff --git a/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php b/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php index c308804fd0f8d..ad73b9722b133 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php +++ b/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php @@ -14,8 +14,8 @@ interface SectionPoolInterface * Get section data by section names. If $sectionNames is null then return all sections data * * @param array $sectionNames - * @param bool $updateIds + * @param bool $forceNewTimestamp * @return array */ - public function getSectionsData(array $sectionNames = null, $updateIds = false); + public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false); } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php index f4bf184f9ebf2..5a7cf42be2c7e 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php @@ -83,13 +83,13 @@ protected function setUp() } /** - * @param $sectionNames - * @param $updateSectionID - * @param $sectionNamesAsArray - * @param $updateIds + * @param string $sectionNames + * @param bool $forceNewSectionTimestamp + * @param string[] $sectionNamesAsArray + * @param bool $forceNewTimestamp * @dataProvider executeDataProvider */ - public function testExecute($sectionNames, $updateSectionID, $sectionNamesAsArray, $updateIds) + public function testExecute($sectionNames, $forceNewSectionTimestamp, $sectionNamesAsArray, $forceNewTimestamp) { $this->resultJsonFactoryMock->expects($this->once()) ->method('create') @@ -103,12 +103,12 @@ public function testExecute($sectionNames, $updateSectionID, $sectionNamesAsArra $this->httpRequestMock->expects($this->exactly(2)) ->method('getParam') - ->withConsecutive(['sections'], ['update_section_id']) - ->willReturnOnConsecutiveCalls($sectionNames, $updateSectionID); + ->withConsecutive(['sections'], ['force_new_section_timestamp']) + ->willReturnOnConsecutiveCalls($sectionNames, $forceNewSectionTimestamp); $this->sectionPoolMock->expects($this->once()) ->method('getSectionsData') - ->with($sectionNamesAsArray, $updateIds) + ->with($sectionNamesAsArray, $forceNewTimestamp) ->willReturn([ 'message' => 'some message', 'someKey' => 'someValue' @@ -133,15 +133,15 @@ public function executeDataProvider() return [ [ 'sectionNames' => 'sectionName1,sectionName2,sectionName3', - 'updateSectionID' => 'updateSectionID', + 'forceNewSectionTimestamp' => 'forceNewSectionTimestamp', 'sectionNamesAsArray' => ['sectionName1', 'sectionName2', 'sectionName3'], - 'updateIds' => true + 'forceNewTimestamp' => true ], [ 'sectionNames' => null, - 'updateSectionID' => null, + 'forceNewSectionTimestamp' => null, 'sectionNamesAsArray' => null, - 'updateIds' => false + 'forceNewTimestamp' => false ], ]; } diff --git a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php index 98fee70e335f7..2b67df1aee292 100644 --- a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php +++ b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php @@ -63,7 +63,7 @@ public function testGetSectionsDataAllSections() $this->identifierMock->expects($this->once()) ->method('markSections') - //check also default value for $updateIds = false + //check also default value for $forceTimestamp = false ->with($allSectionsData, $sectionNames, false) ->willReturn($identifierResult); $modelResult = $this->model->getSectionsData($sectionNames); diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 07d08847aa4ea..39e3f8d95ee3b 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -85,7 +85,7 @@ define([ parameters = _.isArray(sectionNames) ? { sections: sectionNames.join(',') } : []; - parameters['update_section_id'] = forceNewSectionTimestamp; + parameters['force_new_section_timestamp'] = forceNewSectionTimestamp; return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { throw new Error(jqXHR); From c404de46a22640bfe844d9bbc63c28fe0ea0bffc Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sat, 23 Jun 2018 17:40:12 +0200 Subject: [PATCH 0539/1415] Update query parameter name in performance toolkit to match new name in code --- setup/performance-toolkit/benchmark.jmx | 76 ++++++++++---------- setup/performance-toolkit/benchmark_2015.jmx | 36 +++++----- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 8b295c9f5fc46..e8e033fe59024 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -2881,12 +2881,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -4906,12 +4906,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5272,12 +5272,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5566,12 +5566,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5739,12 +5739,12 @@ vars.put("product_sku", product.get("sku")); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6171,12 +6171,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6349,12 +6349,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6787,12 +6787,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -7153,12 +7153,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -7869,12 +7869,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -8105,12 +8105,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -8471,12 +8471,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9146,12 +9146,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9330,12 +9330,12 @@ vars.put("product_sku", product.get("sku")); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9662,12 +9662,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9929,12 +9929,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10295,12 +10295,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10492,12 +10492,12 @@ vars.put("item_id", vars.get("cart_items_qty_inputs_" + id)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10813,12 +10813,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> diff --git a/setup/performance-toolkit/benchmark_2015.jmx b/setup/performance-toolkit/benchmark_2015.jmx index 8be7749a08bc4..e58e610304199 100644 --- a/setup/performance-toolkit/benchmark_2015.jmx +++ b/setup/performance-toolkit/benchmark_2015.jmx @@ -2981,12 +2981,12 @@ vars.put("loadType", "Guest");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -3217,12 +3217,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -3565,12 +3565,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -4039,12 +4039,12 @@ vars.put("loadType", "Guest");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -4275,12 +4275,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -4623,12 +4623,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -5637,12 +5637,12 @@ vars.put("loadType", "Customer");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -5873,12 +5873,12 @@ vars.put("loadType", "Customer");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -6221,12 +6221,12 @@ vars.put("loadType", "Customer");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> From e1e201658be5c247334ef761ac028717cfe0b8a6 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 12 Oct 2018 15:48:14 +0300 Subject: [PATCH 0540/1415] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Catalog/Model/Product/Option/Type/File/ExistingValidate.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php index 8d4aea135eabb..c9afdf023b307 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Product\Option\Type\File; /** From 12753a6f9c73ed4ba3b14a6f94b43c81ea5e2ece Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Fri, 12 Oct 2018 09:55:49 -0500 Subject: [PATCH 0541/1415] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT - Use generateDate -1 day instead of 01/01/2018 --- .../SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml | 3 ++- .../Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml | 3 ++- .../Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml | 3 ++- .../Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml | 3 ++- .../Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml | 3 ++- .../Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml | 3 ++- .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml | 3 ++- 11 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml index 51062da6f2efe..92d221de9e157 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Buy X get Y free (discount amount is Y)" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="1" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 44145f9290457..3deb688de9c34 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -42,7 +42,8 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index a9083cb320ccb..ec835384a52f8 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -42,7 +42,8 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <checkOption selector="{{AdminCartPriceRulesFormSection.useAutoGeneration}}" stepKey="tickAutoGeneration"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml index 9d95b01b2f81d..08a08275ee07a 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml index 1adf2d22be4db..a39530f7607e4 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="19.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml index 42d84f13b9acf..1f7d849ac02b0 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="50" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index e8b8c6cd9e683..3eec020e26347 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index ae7d0eed739ff..73b5d2546f439 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml index c43aaf8d3c97c..51d11b4e5cb1c 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index 4e1944bed9b42..9395e87c20edb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml index 8fb27a9dd1ef3..7c9c52e1c02ac 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> From e86018e14e4ecf79b5df06352c952580e54aa6bf Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 12 Oct 2018 10:10:11 -0500 Subject: [PATCH 0542/1415] MAGETWO-95234: Change regular expression --- app/code/Magento/Sales/Helper/Admin.php | 40 +++++++++++-------- lib/internal/Magento/Framework/Escaper.php | 10 +++-- .../Framework/View/Element/AbstractBlock.php | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Sales/Helper/Admin.php b/app/code/Magento/Sales/Helper/Admin.php index 6b38f0046a983..22d3b76b6c920 100644 --- a/app/code/Magento/Sales/Helper/Admin.php +++ b/app/code/Magento/Sales/Helper/Admin.php @@ -158,25 +158,10 @@ public function escapeHtmlWithLinks($data, $allowedTags = null) .">?(?:(?:(?<text>.*?)(?:<\/a\s*>?|(?=<\w))|(?<text>.*)))#si"; while (preg_match($regexp, $data, $matches)) { $text = ''; - $url = ''; - //Revert the sprintf escaping - if (!empty($matches['link'])) { - $url = str_replace('%%', '%', $matches['link']); - } if (!empty($matches['text'])) { $text = str_replace('%%', '%', $matches['text']); } - //Check for an valid url - if ($url) { - $urlScheme = strtolower(parse_url($url, PHP_URL_SCHEME)); - if ($urlScheme !== 'http' && $urlScheme !== 'https') { - $url = null; - } - } - //Use hash tag as fallback - if (!$url) { - $url = '#'; - } + $url = $this->filterUrl($matches['link'] ?? ''); //Recreate a minimalistic secure a tag $links[] = sprintf( '<a href="%s">%s</a>', @@ -191,4 +176,27 @@ public function escapeHtmlWithLinks($data, $allowedTags = null) } return $this->escaper->escapeHtml($data, $allowedTags); } + + /** + * Filter the URL for allowed protocols. + * + * @param string $url + * @return string + */ + private function filterUrl(string $url): string + { + if ($url) { + //Revert the sprintf escaping + $url = str_replace('%%', '%', $url); + $urlScheme = parse_url($url, PHP_URL_SCHEME); + $urlScheme = $urlScheme ? strtolower($urlScheme) : ''; + if ($urlScheme !== 'http' && $urlScheme !== 'https') { + $url = null; + } + } else { + $url = '#'; + } + + return $url; + } } diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index d0181c2651868..4546de7978e5b 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -58,6 +58,10 @@ class Escaper */ public function escapeHtml($data, $allowedTags = null) { + if (!is_array($data)) { + $data = (string)$data; + } + if (is_array($data)) { $result = []; foreach ($data as $item) { @@ -208,7 +212,7 @@ public function escapeHtmlAttr($string, $escapeSingleQuote = true) if ($escapeSingleQuote) { return $this->getEscaper()->escapeHtmlAttr((string) $string); } - return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false); + return htmlspecialchars((string)$string, ENT_COMPAT, 'UTF-8', false); } /** @@ -289,7 +293,7 @@ public function escapeJsQuote($data, $quote = '\'') $result[] = $this->escapeJsQuote($item, $quote); } } else { - $result = str_replace($quote, '\\' . $quote, $data); + $result = str_replace($quote, '\\' . $quote, (string)$data); } return $result; } @@ -304,7 +308,7 @@ public function escapeJsQuote($data, $quote = '\'') public function escapeXssInUrl($data) { return htmlspecialchars( - $this->escapeScriptIdentifiers($data), + $this->escapeScriptIdentifiers((string)$data), ENT_COMPAT | ENT_HTML5 | ENT_HTML401, 'UTF-8', false diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php index b2f857bf29f45..3f88504f051e0 100644 --- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php +++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php @@ -952,7 +952,7 @@ public function stripTags($data, $allowableTags = null, $allowHtmlEntities = fal */ public function escapeUrl($string) { - return $this->_escaper->escapeUrl($string); + return $this->_escaper->escapeUrl((string)$string); } /** From 40e128c14e32e5005d35a79e0dc7936728414b0e Mon Sep 17 00:00:00 2001 From: Bartosz Kubicki <bartosz.kubicki@lizardmedia.pl> Date: Sat, 22 Sep 2018 19:07:05 +0200 Subject: [PATCH 0543/1415] Fix for custom product attribute changing 'backend_type' when 'is_user_defined = 1' and get updated/saved in Admin Backend Fix for custom product attribute changing 'backend_type' when 'is_user_defined = 1' and get updated/saved in Admin Backend Fix for custom product attribute changing 'backend_type' when 'is_user_defined = 1' and get updated/saved in Admin Backend --- .../Controller/Adminhtml/Product/Attribute/Save.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index 84ad6d2116726..2c74044416a57 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -230,14 +230,14 @@ public function execute() $data['backend_model'] = $this->productHelper->getAttributeBackendModelByInputType( $data['frontend_input'] ); + + if ($model->getIsUserDefined() === null) { + $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']); + } } $data += ['is_filterable' => 0, 'is_filterable_in_search' => 0]; - if ($model->getIsUserDefined() === null || $model->getIsUserDefined() != 0) { - $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']); - } - $defaultValueField = $model->getDefaultValueByInput($data['frontend_input']); if ($defaultValueField) { $data['default_value'] = $this->getRequest()->getParam($defaultValueField); From 2322baf10841259b122dba4350f7c2cbcbe2bba3 Mon Sep 17 00:00:00 2001 From: francesco <francesco.h@thesiteup.com> Date: Fri, 7 Sep 2018 14:15:48 +0200 Subject: [PATCH 0544/1415] Fix issue 12479, customer custom attributes lost after save --- app/code/Magento/Customer/Model/Customer.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 6d1c1549216e8..e9cf007f72186 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -1052,6 +1052,21 @@ public function beforeDelete() return parent::beforeDelete(); } + /** + * Processing object before save data + * + * @return $this + */ + public function beforeSave() { + // Need to use attribute set or future updates can cause data loss + if (!$this->getAttributeSetId()) { + $this->setAttributeSetId( + CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER + ); + } + return parent::beforeSave(); + } + /** * Processing object after save data * From ce82c5ce4784125429b0baa10478277dda3d689c Mon Sep 17 00:00:00 2001 From: francesco <francesco.h@thesiteup.com> Date: Fri, 7 Sep 2018 15:15:20 +0200 Subject: [PATCH 0545/1415] Opening brace should be on a new line --- app/code/Magento/Customer/Model/Customer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index e9cf007f72186..244964c097287 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -1057,7 +1057,8 @@ public function beforeDelete() * * @return $this */ - public function beforeSave() { + public function beforeSave() + { // Need to use attribute set or future updates can cause data loss if (!$this->getAttributeSetId()) { $this->setAttributeSetId( From 97076762561f7781ab2a8e36e6a7d29556d5e98e Mon Sep 17 00:00:00 2001 From: francesco <francesco.h@thesiteup.com> Date: Wed, 3 Oct 2018 14:30:36 +0200 Subject: [PATCH 0546/1415] Issue 12479 refactor, attribute_set_id always not null on customer --- app/code/Magento/Customer/Model/Address.php | 3 -- app/code/Magento/Customer/Model/Customer.php | 33 ++++++------------- .../ResourceModel/CustomerRepository.php | 4 --- .../Customer/Test/Unit/Model/CustomerTest.php | 2 -- .../ResourceModel/CustomerRepositoryTest.php | 12 ------- 5 files changed, 10 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Customer/Model/Address.php b/app/code/Magento/Customer/Model/Address.php index 1dcd8516af69f..c39420542248e 100644 --- a/app/code/Magento/Customer/Model/Address.php +++ b/app/code/Magento/Customer/Model/Address.php @@ -154,9 +154,6 @@ public function updateData(AddressInterface $address) // Need to explicitly set this due to discrepancy in the keys between model and data object $this->setIsDefaultBilling($address->isDefaultBilling()); $this->setIsDefaultShipping($address->isDefaultShipping()); - if (!$this->getAttributeSetId()) { - $this->setAttributeSetId(AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS); - } $customAttributes = $address->getCustomAttributes(); if ($customAttributes !== null) { foreach ($customAttributes as $attribute) { diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 244964c097287..f11322f17eea0 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -359,13 +359,6 @@ public function updateData($customer) $this->setId($customerId); } - // Need to use attribute set or future updates can cause data loss - if (!$this->getAttributeSetId()) { - $this->setAttributeSetId( - CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER - ); - } - return $this; } @@ -961,6 +954,16 @@ public function getSharedWebsiteIds() return $ids; } + /** + * Retrieve attribute set id for customer. + * + * @return int + */ + public function getAttributeSetId() + { + return parent::getAttributeSetId() ?: CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER; + } + /** * Set store to customer * @@ -1052,22 +1055,6 @@ public function beforeDelete() return parent::beforeDelete(); } - /** - * Processing object before save data - * - * @return $this - */ - public function beforeSave() - { - // Need to use attribute set or future updates can cause data loss - if (!$this->getAttributeSetId()) { - $this->setAttributeSetId( - CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER - ); - } - return parent::beforeSave(); - } - /** * Processing object after save data * diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index 29e35c721a3be..c0bbd32f938e5 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -194,10 +194,6 @@ public function save(CustomerInterface $customer, $passwordHash = null) if ($storeId === null) { $customerModel->setStoreId($this->storeManager->getStore()->getId()); } - // Need to use attribute set or future updates can cause data loss - if (!$customerModel->getAttributeSetId()) { - $customerModel->setAttributeSetId(CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER); - } $this->populateCustomerWithSecureData($customerModel, $passwordHash); // If customer email was changed, reset RpToken info if ($prevCustomerData && $prevCustomerData->getEmail() !== $customerModel->getEmail()) { diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php index 9848a09540cb0..cb396e32509b7 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php @@ -307,8 +307,6 @@ public function testUpdateData() } $expectedResult[$attribute->getAttributeCode()] = $attribute->getValue(); - $expectedResult['attribute_set_id'] = - \Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER; $this->assertEquals($this->_model->getData(), $expectedResult); } diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php index bd1dc774b5319..a142f87dcf6c4 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php @@ -334,12 +334,6 @@ public function testSave() $customerModel->expects($this->once()) ->method('setId') ->with($customerId); - $customerModel->expects($this->once()) - ->method('getAttributeSetId') - ->willReturn(null); - $customerModel->expects($this->once()) - ->method('setAttributeSetId') - ->with(\Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER); $customerAttributesMetaData->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -616,12 +610,6 @@ public function testSaveWithPasswordHash() $customerModel->expects($this->once()) ->method('setId') ->with($customerId); - $customerModel->expects($this->once()) - ->method('getAttributeSetId') - ->willReturn(null); - $customerModel->expects($this->once()) - ->method('setAttributeSetId') - ->with(\Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER); $customerModel->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); From 1f93850a824670a59ebba93a506df777f731c031 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 12 Oct 2018 11:37:00 -0500 Subject: [PATCH 0547/1415] MAGETWO-95238: Cannot reset customer password from Admin Panel - fix integration tests --- .../Magento/Customer/Controller/Adminhtml/IndexTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index 4262967aa8d1a..2fe49efd74a6d 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -738,7 +738,7 @@ public function testValidateCustomerWithAddressFailure() public function testResetPasswordActionNoCustomerId() { // No customer ID in post, will just get redirected to base - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl)); } @@ -749,7 +749,7 @@ public function testResetPasswordActionNoCustomerId() public function testResetPasswordActionBadCustomerId() { // Bad customer ID in post, will just get redirected to base - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->getRequest()->setPostValue(['customer_id' => '789']); $this->dispatch('backend/customer/index/resetPassword'); $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl)); @@ -761,7 +761,7 @@ public function testResetPasswordActionBadCustomerId() public function testResetPasswordActionSuccess() { $this->getRequest()->setPostValue(['customer_id' => '1']); - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), From da2b587418fb53f68795c13ba667cbbf86425870 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 10 Oct 2018 16:57:31 -0500 Subject: [PATCH 0548/1415] MAGETWO-95633: Updating default value for protected_extensions setting --- app/code/Magento/Store/etc/config.xml | 2 ++ .../Validator/NotProtectedExtensionTest.php | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Code/File/Validator/NotProtectedExtensionTest.php diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index d69fcad7aac61..b9e7ac1c6aca0 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -130,6 +130,8 @@ <html>html</html> <phtml>phtml</phtml> <shtml>shtml</shtml> + <phpt>phpt</phpt> + <pht>pht</pht> </protected_extensions> <public_files_valid_paths> <protected> diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/File/Validator/NotProtectedExtensionTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/File/Validator/NotProtectedExtensionTest.php new file mode 100644 index 0000000000000..622f17cbf9ce7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/File/Validator/NotProtectedExtensionTest.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Code\File\Validator; + +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Class NotProtectedExtension + */ +class NotProtectedExtensionTest extends \PHPUnit\Framework\TestCase +{ + /** + * Test that phpt, pht is invalid extension type + * @dataProvider isValidDataProvider + */ + public function testIsValid($extension) + { + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $model */ + $model = $objectManager->create(\Magento\MediaStorage\Model\File\Validator\NotProtectedExtension::class); + $this->assertFalse($model->isValid($extension)); + } + + public function isValidDataProvider() + { + return [ + ['phpt'], + ['pht'] + ]; + } +} From 1c61c43a93470dabe373353fa3e9351aa9fffc88 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 12 Oct 2018 12:08:02 -0500 Subject: [PATCH 0549/1415] MAGETWO-95234: Change regular expression --- app/code/Magento/Sales/Helper/Admin.php | 4 ++- lib/internal/Magento/Framework/Escaper.php | 34 +++++++++++++------ .../Framework/View/Element/AbstractBlock.php | 1 + 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Sales/Helper/Admin.php b/app/code/Magento/Sales/Helper/Admin.php index 22d3b76b6c920..7053a696dcab5 100644 --- a/app/code/Magento/Sales/Helper/Admin.php +++ b/app/code/Magento/Sales/Helper/Admin.php @@ -193,7 +193,9 @@ private function filterUrl(string $url): string if ($urlScheme !== 'http' && $urlScheme !== 'https') { $url = null; } - } else { + } + + if (!$url) { $url = '#'; } diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 4546de7978e5b..603c2b395462f 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -69,16 +69,7 @@ public function escapeHtml($data, $allowedTags = null) } } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { - $notAllowedTags = array_intersect( - array_map('strtolower', $allowedTags), - $this->notAllowedTags - ); - if (!empty($notAllowedTags)) { - $this->getLogger()->critical( - 'The following tag(s) are not allowed: ' . implode(', ', $notAllowedTags) - ); - $allowedTags = array_diff($allowedTags, $this->notAllowedTags); - } + $allowedTags = $this->filterProhibitedTags($allowedTags); $wrapperElementId = uniqid(); $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( @@ -378,4 +369,27 @@ private function getLogger() } return $this->logger; } + + /** + * Filter prohibited tags. + * + * @param array $allowedTags + * @return array + */ + private function filterProhibitedTags(array $allowedTags): array + { + $notAllowedTags = array_intersect( + array_map('strtolower', $allowedTags), + $this->notAllowedTags + ); + + if (!empty($notAllowedTags)) { + $this->getLogger()->critical( + 'The following tag(s) are not allowed: ' . implode(', ', $notAllowedTags) + ); + $allowedTags = array_diff($allowedTags, $this->notAllowedTags); + } + + return $allowedTags; + } } diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php index 3f88504f051e0..335006555d2f1 100644 --- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php +++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php @@ -1156,6 +1156,7 @@ public function getVar($name, $module = null) /** * Determine if the block scope is private or public. + * * Returns true if scope is private, false otherwise * * @return bool From 6380421a356b7f85fde10c7596f515467ab1f138 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 2 Oct 2018 16:09:57 +0300 Subject: [PATCH 0550/1415] MAGETWO-95435: [2.3] Profile changes for performance-toolkit --- setup/performance-toolkit/config/description.xml | 12 ++++++------ .../performance-toolkit/profiles/ce/extra_large.xml | 6 +++--- setup/performance-toolkit/profiles/ce/large.xml | 6 +++--- setup/performance-toolkit/profiles/ce/medium.xml | 6 +++--- .../performance-toolkit/profiles/ce/medium_msite.xml | 6 +++--- setup/performance-toolkit/profiles/ce/small.xml | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/setup/performance-toolkit/config/description.xml b/setup/performance-toolkit/config/description.xml index ae7e1e343b1da..06fa6a2618f68 100644 --- a/setup/performance-toolkit/config/description.xml +++ b/setup/performance-toolkit/config/description.xml @@ -7,16 +7,16 @@ --> <description> <paragraphs> - <count-min>4</count-min> - <count-max>10</count-max> + <count-min>7</count-min> + <count-max>7</count-max> <sentences> - <count-min>10</count-min> - <count-max>15</count-max> + <count-min>12</count-min> + <count-max>12</count-max> <words> - <count-min>5</count-min> - <count-max>7</count-max> + <count-min>6</count-min> + <count-max>6</count-max> </words> </sentences> </paragraphs> diff --git a/setup/performance-toolkit/profiles/ce/extra_large.xml b/setup/performance-toolkit/profiles/ce/extra_large.xml index 44b3512090b12..390bf7fb12003 100644 --- a/setup/performance-toolkit/profiles/ce/extra_large.xml +++ b/setup/performance-toolkit/profiles/ce/extra_large.xml @@ -40,9 +40,9 @@ <cart_price_rules>20</cart_price_rules> <!-- Number of cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> - <product_attribute_sets>200</product_attribute_sets> <!-- Number of product attribute sets --> - <product_attribute_sets_attributes>50</product_attribute_sets_attributes> <!-- Number of attributes per set --> - <product_attribute_sets_attributes_values>2</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> + <product_attribute_sets>100</product_attribute_sets> <!-- Number of product attribute sets --> + <product_attribute_sets_attributes>30</product_attribute_sets_attributes> <!-- Number of attributes per set --> + <product_attribute_sets_attributes_values>15</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> <order_quotes_enable>true</order_quotes_enable> <order_simple_product_count_from>2</order_simple_product_count_from> diff --git a/setup/performance-toolkit/profiles/ce/large.xml b/setup/performance-toolkit/profiles/ce/large.xml index 606c854d27adc..ed91b22930af5 100644 --- a/setup/performance-toolkit/profiles/ce/large.xml +++ b/setup/performance-toolkit/profiles/ce/large.xml @@ -40,9 +40,9 @@ <cart_price_rules>20</cart_price_rules> <!-- Number of cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> - <product_attribute_sets>200</product_attribute_sets> <!-- Number of product attribute sets --> - <product_attribute_sets_attributes>50</product_attribute_sets_attributes> <!-- Number of attributes per set --> - <product_attribute_sets_attributes_values>2</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> + <product_attribute_sets>50</product_attribute_sets> <!-- Number of product attribute sets --> + <product_attribute_sets_attributes>20</product_attribute_sets_attributes> <!-- Number of attributes per set --> + <product_attribute_sets_attributes_values>15</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> <order_quotes_enable>true</order_quotes_enable> <order_simple_product_count_from>2</order_simple_product_count_from> diff --git a/setup/performance-toolkit/profiles/ce/medium.xml b/setup/performance-toolkit/profiles/ce/medium.xml index 4f735ae4ac2d4..f01eabb7898f3 100644 --- a/setup/performance-toolkit/profiles/ce/medium.xml +++ b/setup/performance-toolkit/profiles/ce/medium.xml @@ -40,9 +40,9 @@ <cart_price_rules>20</cart_price_rules> <!-- Number of cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> - <product_attribute_sets>100</product_attribute_sets> <!-- Number of product attribute sets --> - <product_attribute_sets_attributes>50</product_attribute_sets_attributes> <!-- Number of attributes per set --> - <product_attribute_sets_attributes_values>2</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> + <product_attribute_sets>30</product_attribute_sets> <!-- Number of product attribute sets --> + <product_attribute_sets_attributes>10</product_attribute_sets_attributes> <!-- Number of attributes per set --> + <product_attribute_sets_attributes_values>8</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> <order_quotes_enable>true</order_quotes_enable> <order_simple_product_count_from>2</order_simple_product_count_from> diff --git a/setup/performance-toolkit/profiles/ce/medium_msite.xml b/setup/performance-toolkit/profiles/ce/medium_msite.xml index 24d51d170fbc2..a57fcad0779fe 100644 --- a/setup/performance-toolkit/profiles/ce/medium_msite.xml +++ b/setup/performance-toolkit/profiles/ce/medium_msite.xml @@ -46,9 +46,9 @@ <cart_price_rules>20</cart_price_rules> <!-- Number of cart price rules --> <cart_price_rules_floor>2</cart_price_rules_floor> - <product_attribute_sets>100</product_attribute_sets> <!-- Number of product attribute sets --> - <product_attribute_sets_attributes>50</product_attribute_sets_attributes> <!-- Number of attributes per set --> - <product_attribute_sets_attributes_values>2</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> + <product_attribute_sets>30</product_attribute_sets> <!-- Number of product attribute sets --> + <product_attribute_sets_attributes>10</product_attribute_sets_attributes> <!-- Number of attributes per set --> + <product_attribute_sets_attributes_values>8</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> <order_quotes_enable>true</order_quotes_enable> <order_simple_product_count_from>2</order_simple_product_count_from> diff --git a/setup/performance-toolkit/profiles/ce/small.xml b/setup/performance-toolkit/profiles/ce/small.xml index 270828c2a2c9d..60ae901d8f5e0 100644 --- a/setup/performance-toolkit/profiles/ce/small.xml +++ b/setup/performance-toolkit/profiles/ce/small.xml @@ -41,8 +41,8 @@ <cart_price_rules_floor>2</cart_price_rules_floor> <product_attribute_sets>10</product_attribute_sets> <!-- Number of product attribute sets --> - <product_attribute_sets_attributes>10</product_attribute_sets_attributes> <!-- Number of attributes per set --> - <product_attribute_sets_attributes_values>2</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> + <product_attribute_sets_attributes>5</product_attribute_sets_attributes> <!-- Number of attributes per set --> + <product_attribute_sets_attributes_values>5</product_attribute_sets_attributes_values> <!-- Number of values per attribute --> <order_quotes_enable>true</order_quotes_enable> <order_simple_product_count_from>2</order_simple_product_count_from> From cda686799600a3c631822a161eb40ec02a786b87 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 12 Oct 2018 13:03:40 -0500 Subject: [PATCH 0551/1415] MAGETWO-90660: Skip Flaky MTF Tests - skip tests --- .../Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml | 1 + .../app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml index 2cb0e2874040b..7c12b546d1359 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml @@ -105,6 +105,7 @@ <data name="issue" xsi:type="string">MAGETWO-66737: Magento\Checkout\Test\TestCase\OnePageCheckoutTest with OnePageCheckoutTestVariation3 and 4 is not stable</data> </variation> <variation name="OnePageCheckoutTestVariation4" summary="One Page Checkout Products with Special Prices" ticketId="MAGETWO-12429"> + <data name="issue" xsi:type="string">MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest</data> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_special_price</data> <data name="products/1" xsi:type="string">configurableProduct::product_with_special_price</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 5c05d4a840009..3480c88d652ee 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -29,6 +29,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> </variation> <variation name="OnePageCheckoutUsingNonDefaultAddress" summary="Checkout as Customer using non default address" ticketId="MAGETWO-42602"> + <data name="issue" xsi:type="string">MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_US_DE_UK</data> From b3d3f2eaa3d6aded859493da10ec274ed40bf388 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 12 Oct 2018 13:19:49 -0500 Subject: [PATCH 0552/1415] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Magento/Checkout/Model/ShippingInformationManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 6bd78cecd3a6b..cd3bd2c5a7deb 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -161,7 +161,7 @@ public function saveAddressInformation( $address->setCustomerAddressId(null); } - if (!$billingAddress->getCustomerAddressId()) { + if ($billingAddress && !$billingAddress->getCustomerAddressId()) { $billingAddress->setCustomerAddressId(null); } From e2e3be0f2afda3d04fa355516d50274aaaa5f220 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Fri, 12 Oct 2018 13:50:05 -0500 Subject: [PATCH 0553/1415] MAGETWO-95111: Creating new storeview validation - added mftf test changes to cover the bug fix --- .../AdminCreateStoreViewActionGroup.xml | 14 ++++++- .../AdminNewStoreViewActionsSection.xml | 1 + .../Mftf/Section/AdminStoresGridSection.xml | 1 - .../Test/AdminCreateStoreViewCodeTest.xml | 39 ------------------- .../Mftf/Test/AdminCreateStoreViewTest.xml | 14 ++++++- 5 files changed, 25 insertions(+), 44 deletions(-) delete mode 100644 app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 6ce33f3be3622..934fdf049bc61 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -24,8 +24,18 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForPageLoad stepKey="waitForPageLoad2" /> - <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> + <waitForElementNotVisible selector="{{AdminNewStoreViewActionsSection.loadingMask}}" stepKey="waitForElementVisible"/> + </actionGroup> + + <actionGroup name="AdminCreateStoreViewActionSaveGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> + <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> + + <actionGroup name="AdminCreateStoreViewCodeUniquenessActionGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForForm"/> + <see userInput="Store with the same code already exists." stepKey="seeMessage" /> + </actionGroup> + </actionGroups> diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml index faffc69dc6975..0e3a74fccf9f0 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml @@ -11,5 +11,6 @@ <element name="delete" type="button" selector="#delete" timeout="30"/> <element name="resetButton" type="button" selector="#reset" timeout="30"/> <element name="saveButton" type="button" selector="#save" timeout="60"/> + <element name="loadingMask" type="text" selector=".loading-mask"/> </section> </sections> diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml index 6b2c38502923a..04cbeb5bc596e 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml @@ -12,7 +12,6 @@ <element name="createWebsite" type="button" selector="#add"/> </section> <section name="AdminStoresGridSection"> - <element name="loadingMask" type="text" selector=".admin__data-grid-loading-mask[data-component*='notification_area.notification_area.columns']"/> <element name="storeGrpFilterTextField" type="input" selector="#storeGrid_filter_group_title"/> <element name="websiteFilterTextField" type="input" selector="#storeGrid_filter_website_title"/> <element name="storeFilterTextField" type="input" selector="#storeGrid_filter_store_title"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml deleted file mode 100644 index 473b0c1663033..0000000000000 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<!-- Test XML Example --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateStoreViewCodeTest"> - <annotations> - <features value="Store"/> - <stories value="Create a store view new in admin"/> - <title value="Admin should be able to create a store view new"/> - <description value="Admin should be able to create a store view new"/> - <group value="storeViewGroup"/> - <severity value="AVERAGE"/> - </annotations> - <before> - <actionGroup ref="LoginActionGroup" stepKey="login"/> - </before> - <amOnPage url="{{AdminSystemStoreViewPage.url}}" stepKey="navigateToNewStoreView"/> - <waitForPageLoad stepKey="waitForPageLoad1" /> - <!--Create Store View and and check for loading-mask!--> - <fillField selector="{{AdminNewStoreSection.storeNameTextField}}" userInput="{{customStore.name}}" stepKey="enterStoreViewName" /> - <fillField selector="{{AdminNewStoreSection.storeCodeTextField}}" userInput="{{customStore.code}}" stepKey="enterStoreViewCode" /> - <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> - <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> - <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> - <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForPageLoad time="60" stepKey="wait1"/> - <waitForElementNotVisible selector="{{AdminStoresGridSection.loadingMask}}" stepKey="waitForLoadingMaskToLoad"/> - <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> - <waitForPageLoad time="60" stepKey="wait2"/> - <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> - <see userInput="You saved the store view." stepKey="seeSavedMessage" /> - </test> -</tests> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml index 54d392d0c06f1..e7a3d03f337db 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml @@ -15,15 +15,25 @@ <description value="Admin should be able to create a store view"/> <group value="storeView"/> <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-95111"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + <!--<createData stepKey="b2" entity="customStoreGroup"/>--> </before> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> - <!--Confirm new store view on Store Grid--> + <!--Save store view on Store Grid--> + <actionGroup ref="AdminCreateStoreViewActionSaveGroup" stepKey="createStoreViewSave" /> + <!--Confirm new store view created on Store Grid--> <fillField selector="{{AdminStoresGridSection.storeFilterTextField}}" userInput="{{customStore.name}}" stepKey="fillStoreViewFilter"/> <click selector="{{AdminStoresGridSection.searchButton}}" stepKey="clickSearch" /> <waitForPageLoad stepKey="waitForPageLoad"/> <see selector="{{AdminStoresGridSection.storeNameInFirstRow}}" userInput="{{customStore.name}}" stepKey="seeNewStoreView" /> + <!--Creating the same store view to validate the code uniqueness on store form--> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView2" /> + <actionGroup ref="AdminCreateStoreViewCodeUniquenessActionGroup" stepKey="createStoreViewCode" /> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> </test> </tests> From 735a01df04dfbd8fb4f6abd2ba0e83044fa03fcf Mon Sep 17 00:00:00 2001 From: avattam <> Date: Fri, 12 Oct 2018 14:14:42 -0500 Subject: [PATCH 0554/1415] MAGETWO-95111: Creating new storeview validation - Added fixes to mftf tests --- .../Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 934fdf049bc61..6cbbb7ae22014 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -26,16 +26,15 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> <waitForElementNotVisible selector="{{AdminNewStoreViewActionsSection.loadingMask}}" stepKey="waitForElementVisible"/> </actionGroup> - + <!--Save the Store view--> <actionGroup name="AdminCreateStoreViewActionSaveGroup"> <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> - + <!--Save the same Store view code for code validation--> <actionGroup name="AdminCreateStoreViewCodeUniquenessActionGroup"> <waitForLoadingMaskToDisappear stepKey="waitForForm"/> <see userInput="Store with the same code already exists." stepKey="seeMessage" /> </actionGroup> - </actionGroups> From 96498d0aa646b9ef6a3a61e0aa3b1c6d05811ecd Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Fri, 12 Oct 2018 14:37:19 -0500 Subject: [PATCH 0555/1415] MAGETWO-60034: Cannot ship remaining items in an order for several of one product if credit memo is made for some - fix static test failure --- .../Constraint/AssertOrderCancelMassActionPartialFailMessage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php index 6aed5cd39aaad..ecc9af83580f3 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Sales\Test\Constraint; From d1d5fdbc48dc7159cb2e6fe1f378cf2408be6a87 Mon Sep 17 00:00:00 2001 From: Zack Craig <zack@zack6849.com> Date: Fri, 12 Oct 2018 16:04:55 -0400 Subject: [PATCH 0556/1415] Update documentation for Order#getAppliedRuleIds Update the documentation for getAppliedRuleIds, as it is not immediately clear if this is a single number in a string, or several that are comma separated. --- app/code/Magento/Sales/Api/Data/OrderInterface.php | 1 + app/code/Magento/Sales/Api/Data/OrderItemInterface.php | 1 + app/code/Magento/Sales/Model/Order.php | 1 + app/code/Magento/Sales/Model/Order/Item.php | 1 + 4 files changed, 4 insertions(+) diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php index 3ca936afd4090..e689738fb019b 100644 --- a/app/code/Magento/Sales/Api/Data/OrderInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php @@ -580,6 +580,7 @@ public function getAdjustmentPositive(); /** * Gets the applied rule IDs for the order. + * Rules are comma separated if there are more than one. * * @return string|null Applied rule IDs. */ diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php index ae4064c0ab3d1..fb81fea90053f 100644 --- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php @@ -414,6 +414,7 @@ public function getAmountRefunded(); /** * Gets the applied rule IDs for the order item. + * Rules are comma separated if there are more than one. * * @return string|null Applied rule IDs. */ diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 9f30342ed331f..e6605a67a1231 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -2112,6 +2112,7 @@ public function getAdjustmentPositive() /** * Returns applied_rule_ids + * Rules are comma separated if there are more than one. * * @return string|null */ diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index d2f5f5ce56692..02ba396601c82 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -724,6 +724,7 @@ public function getAmountRefunded() /** * Returns applied_rule_ids + * Rules are comma separated if there are more than one. * * @return string|null */ From b68802f2a07b342a56a36a74ff7383975f42332c Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Fri, 12 Oct 2018 15:08:56 -0500 Subject: [PATCH 0557/1415] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Modified store_id validation to take in store_id from filters, when store is null in params. --- .../Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php index b7655f7ee2862..83278ca78c738 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php @@ -87,7 +87,7 @@ public function execute() $filterRequest = $this->getRequest()->getParam('filters', null); $status = (int) $this->getRequest()->getParam('status'); - if (null !== $storeId && null !== $filterRequest) { + if (null === $storeId && null !== $filterRequest) { $storeId = (isset($filterRequest['store_id'])) ? (int) $filterRequest['store_id'] : 0; } From 1b56213a6d7e3c2afeb690ac9828f4dc6c0e8336 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 11 Oct 2018 16:06:29 -0500 Subject: [PATCH 0558/1415] MAGETWO-95356: Import is successful without notice about category name updates --- .../Import/Product/CategoryProcessor.php | 14 ++---- .../Import/Product/CategoryProcessorTest.php | 48 +++++++++++-------- .../Exception/UrlAlreadyExistsException.php | 6 ++- .../Catalog/_files/category_duplicates.php | 2 +- .../_files/category_duplicates_rollback.php | 34 +++++++++++++ .../Model/Import/ProductTest.php | 17 +------ .../_files/update_category_duplicates.php | 17 +++++++ .../update_category_duplicates_rollback.php | 18 +++++++ 8 files changed, 109 insertions(+), 47 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index a5aefff656bd3..951989146e67e 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -66,6 +66,8 @@ public function __construct( } /** + * Initialize categories + * * @return $this */ protected function initCategories() @@ -104,7 +106,6 @@ protected function initCategories() * * @param string $name * @param int $parentId - * * @return int */ protected function createCategory($name, $parentId) @@ -120,13 +121,8 @@ protected function createCategory($name, $parentId) $category->setIsActive(true); $category->setIncludeInMenu(true); $category->setAttributeSetId($category->getDefaultAttributeSetId()); - try { - $category->save(); - $this->categoriesCache[$category->getId()] = $category; - } catch (\Exception $e) { - $this->addFailedCategory($category, $e); - } - + $category->save(); + $this->categoriesCache[$category->getId()] = $category; return $category->getId(); } @@ -134,7 +130,6 @@ protected function createCategory($name, $parentId) * Returns ID of category by string path creating nonexistent ones. * * @param string $categoryPath - * * @return int */ protected function upsertCategory($categoryPath) @@ -165,7 +160,6 @@ protected function upsertCategory($categoryPath) * * @param string $categoriesString * @param string $categoriesSeparator - * * @return array */ public function upsertCategories($categoriesString, $categoriesSeparator) diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php index 69f4a465e3309..919f0cfda7cbe 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php @@ -34,41 +34,49 @@ class CategoryProcessorTest extends \PHPUnit\Framework\TestCase */ protected $product; + /** + * @var \Magento\Catalog\Model\Category + */ + private $childCategory; + + /** + * \Magento\Catalog\Model\Category + */ + private $parentCategory; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->objectManagerHelper = new ObjectManagerHelper($this); - $childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + $this->childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); - $childCategory->method('getId')->will($this->returnValue(self::CHILD_CATEGORY_ID)); - $childCategory->method('getName')->will($this->returnValue(self::CHILD_CATEGORY_NAME)); - $childCategory->method('getPath')->will($this->returnValue( + $this->childCategory->method('getId')->will($this->returnValue(self::CHILD_CATEGORY_ID)); + $this->childCategory->method('getName')->will($this->returnValue(self::CHILD_CATEGORY_NAME)); + $this->childCategory->method('getPath')->will($this->returnValue( self::PARENT_CATEGORY_ID . CategoryProcessor::DELIMITER_CATEGORY . self::CHILD_CATEGORY_ID )); - $childCategory->method('save')->willThrowException(new \Exception()); - - $parentCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + $this->parentCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); - $parentCategory->method('getId')->will($this->returnValue(self::PARENT_CATEGORY_ID)); - $parentCategory->method('getName')->will($this->returnValue('Parent')); - $parentCategory->method('getPath')->will($this->returnValue(self::PARENT_CATEGORY_ID)); + $this->parentCategory->method('getId')->will($this->returnValue(self::PARENT_CATEGORY_ID)); + $this->parentCategory->method('getName')->will($this->returnValue('Parent')); + $this->parentCategory->method('getPath')->will($this->returnValue(self::PARENT_CATEGORY_ID)); $categoryCollection = $this->objectManagerHelper->getCollectionMock( \Magento\Catalog\Model\ResourceModel\Category\Collection::class, [ - self::PARENT_CATEGORY_ID => $parentCategory, - self::CHILD_CATEGORY_ID => $childCategory, + self::PARENT_CATEGORY_ID => $this->parentCategory, + self::CHILD_CATEGORY_ID => $this->childCategory, ] ); $map = [ - [self::PARENT_CATEGORY_ID, $parentCategory], - [self::CHILD_CATEGORY_ID, $childCategory], + [self::PARENT_CATEGORY_ID, $this->parentCategory], + [self::CHILD_CATEGORY_ID, $this->childCategory], ]; $categoryCollection->expects($this->any()) ->method('getItemById') @@ -91,7 +99,7 @@ protected function setUp() $categoryFactory = $this->createPartialMock(\Magento\Catalog\Model\CategoryFactory::class, ['create']); - $categoryFactory->method('create')->will($this->returnValue($childCategory)); + $categoryFactory->method('create')->will($this->returnValue($this->childCategory)); $this->categoryProcessor = new \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor( @@ -110,11 +118,13 @@ public function testUpsertCategories() /** * Tests case when newly created category save throws exception. */ - public function testCreateCategoryException() + public function testUpsertCategoriesWithAlreadyExistsException() { - $method = new \ReflectionMethod(CategoryProcessor::class, 'createCategory'); - $method->setAccessible(true); - $method->invoke($this->categoryProcessor, self::CHILD_CATEGORY_NAME, self::PARENT_CATEGORY_ID); + $exception = new \Magento\Framework\Exception\AlreadyExistsException(); + $categoriesSeparator = '/'; + $categoryName = 'Exception Category'; + $this->childCategory->method('save')->willThrowException($exception); + $this->categoryProcessor->upsertCategories($categoryName, $categoriesSeparator); $this->assertNotEmpty($this->categoryProcessor->getFailedCategories()); } diff --git a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php index c7e83819f2569..c7071076bd55a 100644 --- a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php +++ b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php @@ -8,10 +8,12 @@ use Magento\Framework\Phrase; /** + * Specific exception for URL key already exists + * * @api * @since 100.2.0 */ -class UrlAlreadyExistsException extends \Magento\Framework\Exception\LocalizedException +class UrlAlreadyExistsException extends \Magento\Framework\Exception\AlreadyExistsException { /** * @var array @@ -34,6 +36,8 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** + * Get URLs + * * @return array * @since 100.2.0 */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php index d3825675b7244..46d5bfea6459c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php @@ -15,7 +15,7 @@ )->setParentId( 2 )->setPath( - '1/2' + '1/2/444' )->setLevel( '2' )->setDefaultSortBy( diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php new file mode 100644 index 0000000000000..a1dc418e15633 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Exception\NoSuchEntityException; + +/** @var \Magento\Framework\ObjectManagerInterface $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ +$categoryCollection = $objectManager->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); +$categoryCollection + ->addAttributeToFilter('level', 2) + ->load() + ->delete(); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +try { + $product = $productRepository->get('simple3', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index c5e704c2434b5..bbe96d89f5728 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1292,12 +1292,10 @@ public function categoryTestDataProvider() * @magentoAppArea adminhtml * @magentoDbIsolation disabled * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Catalog/_files/category_duplicates.php + * @magentoDataFixture Magento/CatalogImportExport/_files/update_category_duplicates.php */ public function testProductDuplicateCategories() { - $this->markTestSkipped('Due to MAGETWO-48956'); - $csvFixture = 'products_duplicate_category.csv'; // import data from CSV file $pathToFile = __DIR__ . '/_files/' . $csvFixture; @@ -1322,19 +1320,6 @@ public function testProductDuplicateCategories() $this->assertTrue($errors->getErrorsCount() === 0); - /** @var \Magento\Catalog\Model\Category $category */ - $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Category::class - ); - - $category->load(444); - - $this->assertTrue($category !== null); - - $category->setName( - 'Category 2-updated' - )->save(); - $this->_model->importData(); $errorProcessor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php new file mode 100644 index 0000000000000..27ca8e7a04413 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates.php'; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Catalog\Model\Category $category */ +$categoryModel = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categoryModel->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); + +$categoryModel->load(444) + ->setName('Category 2-updated') + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php new file mode 100644 index 0000000000000..f3bb3d0415afa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates_rollback.php'; + +//Delete products created in CSV import +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$csvProductSkus = ['simple1', 'simple2', 'simple3']; +foreach($csvProductSkus as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + } +} From 2d22b204052208e24ec586625397327e1aa08a56 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Thu, 11 Oct 2018 14:54:58 -0500 Subject: [PATCH 0559/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted - Removed deprecation of the classes necessary for the work of ElasticSearch (or any other search adapter) --- .../CatalogSearch/Block/Advanced/Result.php | 2 -- .../Adapter/Aggregation/AggregationResolver.php | 5 ++--- .../Aggregation/Checker/Query/CatalogView.php | 4 +--- .../Aggregation/RequestCheckerComposite.php | 5 ++--- .../Aggregation/RequestCheckerInterface.php | 3 --- .../Magento/CatalogSearch/Model/Advanced.php | 2 -- .../Model/Advanced/Request/Builder.php | 6 ++++-- .../Model/Indexer/Fulltext/Action/Full.php | 3 --- .../Indexer/Fulltext/Plugin/Product/Action.php | 2 -- .../Model/Indexer/IndexStructure.php | 16 ++++++---------- .../Model/Indexer/IndexStructureProxy.php | 7 +++---- .../Model/Indexer/IndexSwitcherInterface.php | 5 ++--- .../Model/Indexer/IndexSwitcherProxy.php | 5 +---- .../Model/Indexer/Scope/ScopeProxy.php | 10 ++-------- .../CatalogSearch/Model/Indexer/Scope/State.php | 7 ++++--- .../Model/ResourceModel/Advanced.php | 3 --- .../Model/ResourceModel/Advanced/Collection.php | 8 ++++---- .../Model/ResourceModel/Fulltext.php | 2 -- .../Model/ResourceModel/Fulltext/Collection.php | 1 + .../Model/ResourceModel/Search/Collection.php | 2 -- .../Model/Search/RequestGenerator.php | 4 ++-- .../Search/Adapter/Mysql/ConditionManager.php | 2 +- 22 files changed, 35 insertions(+), 69 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 79f6024132be7..7c8e65b249139 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -18,8 +18,6 @@ * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php index 639c0aecb3615..8a484d4cc7903 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php @@ -15,8 +15,7 @@ use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; /** - * @deprecated - * @see \Magento\ElasticSearch + * Aggregation resolver. */ class AggregationResolver implements AggregationResolverInterface { @@ -79,7 +78,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve(RequestInterface $request, array $documentIds) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php index 1ac7ad3773740..42da02f8ca4ff 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php @@ -17,8 +17,6 @@ * Request checker for catalog view. * * Checks catalog view query whether required to collect all attributes for entity. - * @deprecated - * @see \Magento\ElasticSearch */ class CatalogView implements RequestCheckerInterface { @@ -53,7 +51,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php index 7e0ad7c46d6f3..75910e1720734 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php @@ -10,8 +10,7 @@ use Magento\Store\Model\StoreManagerInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Composite request checker. */ class RequestCheckerComposite implements RequestCheckerInterface { @@ -57,7 +56,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php index 81b7414380bf1..7efe708a5755f 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php @@ -9,9 +9,6 @@ /** * RequestCheckerInterface provides the interface to work with query checkers. - * - * @deprecated - * @see \Magento\ElasticSearch */ interface RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index b49809cfc8059..28f67a7829e7e 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -43,8 +43,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php index be2609ccc338a..9e7737123b2ec 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php @@ -8,14 +8,16 @@ use Magento\Framework\Search\Request\Builder as RequestBuilder; /** + * Catalog search advanced request builder. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Builder extends RequestBuilder { /** + * Bind value to query. + * * @param string $attributeCode * @param array|string $attributeValue * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 9ea4007c6bde1..8a18c1bfcc576 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -22,9 +22,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * - * @deprecated - * @see \Magento\ElasticSearch */ class Full { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php index 2ead0ac0ac612..75bf4cbd0f3f6 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php @@ -24,8 +24,6 @@ class Action extends AbstractIndexerPlugin * @return ProductAction * * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @deprecated - * @see ElasticSearch module is default search engine starting from 2.3. CatalogSearch would be removed in 2.4 */ public function afterUpdateAttributes( ProductAction $subject, diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php index 0308fda657375..0d226acdc3d7b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php @@ -15,10 +15,10 @@ use Magento\Framework\Search\Request\IndexScopeResolverInterface; /** + * Catalog search index structure. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class IndexStructure implements IndexStructureInterface { @@ -45,9 +45,7 @@ public function __construct( } /** - * @param string $index - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function delete($index, array $dimensions = []) { @@ -58,11 +56,7 @@ public function delete($index, array $dimensions = []) } /** - * @param string $index - * @param array $fields - * @param array $dimensions - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @return void + * @inheritdoc */ public function create($index, array $fields, array $dimensions = []) { @@ -70,6 +64,8 @@ public function create($index, array $fields, array $dimensions = []) } /** + * Create fulltext index table. + * * @param string $tableName * @throws \Zend_Db_Exception * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php index f8863aca8db9c..c62d2a033565f 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php @@ -8,8 +8,7 @@ use Magento\Framework\Indexer\IndexStructureInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search index structure proxy. */ class IndexStructureProxy implements IndexStructureInterface { @@ -33,7 +32,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function delete( $index, @@ -43,7 +42,7 @@ public function delete( } /** - * {@inheritdoc} + * @inheritdoc */ public function create( $index, diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php index 1cdd9c5b9fa5e..f45ef11a86389 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php @@ -6,11 +6,10 @@ namespace Magento\CatalogSearch\Model\Indexer; /** - * Provides a functionality to replace main index with its temporary representation + * Provides a functionality to replace main index with its temporary representation. + * * @api * @since 100.2.0 - * @deprecated - * @see \Magento\ElasticSearch */ interface IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php index cd0aa12f9137b..e4a20cc188fbd 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php @@ -11,9 +11,6 @@ /** * Proxy for adapter-specific index switcher - * - * @deprecated - * @see \Magento\ElasticSearch */ class IndexSwitcherProxy implements IndexSwitcherInterface { @@ -54,7 +51,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritDoc * * As index switcher is an optional part of the search SPI, it may be not defined by a search engine. * It is especially reasonable for search engines with pre-defined indexes declaration (like Sphinx) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php index 02d533d7bcb49..fcecb36e7d508 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php @@ -9,11 +9,7 @@ use Magento\Framework\Search\Request\Dimension; /** - * Implementation of IndexScopeResolverInterface which resolves index scope dynamically - * depending on current scope state - * - * @deprecated - * @see \Magento\ElasticSearch + * Implementation of IndexScopeResolverInterface which resolves index scope dynamically depending on current scope state */ class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { @@ -67,9 +63,7 @@ private function create($state) } /** - * @param string $index - * @param Dimension[] $dimensions - * @return string + * @inheritdoc */ public function resolve($index, array $dimensions) { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php index 35f616f109638..a12ae8e69c310 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php @@ -18,9 +18,6 @@ * The 'use_temporary_table' state is an opposite for 'use_main_table' * which means that default indexer table should be left unchanged during indexation * and temporary table should be used instead. - * - * @deprecated - * @see \Magento\ElasticSearch */ class State { @@ -34,6 +31,7 @@ class State /** * Set the state to use temporary Index + * * @return void */ public function useTemporaryIndex() @@ -43,6 +41,7 @@ public function useTemporaryIndex() /** * Set the state to use regular Index + * * @return void */ public function useRegularIndex() @@ -51,6 +50,8 @@ public function useRegularIndex() } /** + * Get state. + * * @return string */ public function getState() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php index d88e5627df0e0..05254a50aadc6 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php @@ -8,11 +8,8 @@ /** * Advanced Catalog Search resource model * - * @author Magento Core Team <core@magentocommerce.com> * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index a660cf62b1ad9..948ae70793c6f 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -17,14 +17,13 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory; /** - * Collection Advanced + * Advanced search collection + * + * This collection should be refactored to not have dependencies on MySQL-specific implementation. * - * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { @@ -41,6 +40,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection /** * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @deprecated There must be no dependencies on specific adapter in generic search implementation */ private $temporaryStorageFactory; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php index ff9aeb4fb4474..0835fb66f876a 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php @@ -14,8 +14,6 @@ * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 79d03b6fad2ca..81121b9d21e12 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -72,6 +72,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection /** * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @deprecated There must be no dependencies on specific adapter in generic search implementation */ private $temporaryStorageFactory; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index aff558c6d0244..b958de91314f4 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -12,8 +12,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection implements \Magento\Search\Model\SearchCollectionInterface diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 6e6aee08f926e..0adc2fcecbfa7 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -14,10 +14,10 @@ use Magento\Framework\Search\Request\QueryInterface; /** + * Catalog search request generator. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class RequestGenerator { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php index 413af71814198..e56559563c35a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php @@ -34,7 +34,7 @@ public function __construct(ResourceConnection $resource) } /** - * Wrap query with parentheces. + * Wrap query with parentheses. * * @param string $query * @return string From cf28335ad72a3fdc86193b25b23bad993e2a01dd Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 12 Oct 2018 16:11:01 -0500 Subject: [PATCH 0560/1415] MAGETWO-90660: Skip Flaky MTF Tests - remove second issue node --- .../app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 3480c88d652ee..5c05d4a840009 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -29,7 +29,6 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> </variation> <variation name="OnePageCheckoutUsingNonDefaultAddress" summary="Checkout as Customer using non default address" ticketId="MAGETWO-42602"> - <data name="issue" xsi:type="string">MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_US_DE_UK</data> From 4e382cc735a883c9dcd8eaeeedc185d7faa06a7f Mon Sep 17 00:00:00 2001 From: hiren pandya <infinitehdp@gmail.com> Date: Sat, 13 Oct 2018 11:52:27 +0530 Subject: [PATCH 0561/1415] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index d82f4a04fb252..e14916f731ed8 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From fd8a5a90b32431fbdd275000624723b106c81841 Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:00:58 +0530 Subject: [PATCH 0562/1415] Revert "Special price date from issue resolve" This reverts commit 4e382cc735a883c9dcd8eaeeedc185d7faa06a7f. --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index e14916f731ed8..d82f4a04fb252 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,6 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 88592facd5d34872ac2f2051dda246703091cacc Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:03:07 +0530 Subject: [PATCH 0563/1415] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index d82f4a04fb252..8999b03b647a3 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 96507df2629a67616931f8aa404b5b2cf6f5440a Mon Sep 17 00:00:00 2001 From: Luuk Schakenraad <luuk@chessweb.eu> Date: Sat, 13 Oct 2018 13:56:47 +0200 Subject: [PATCH 0564/1415] Fix disappearing navigation arrows in fotorama zoom --- lib/web/fotorama/fotorama.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/fotorama/fotorama.js b/lib/web/fotorama/fotorama.js index a16e437c0d7ff..9f756696008cc 100644 --- a/lib/web/fotorama/fotorama.js +++ b/lib/web/fotorama/fotorama.js @@ -2098,7 +2098,7 @@ fotoramaVersion = '4.6.4'; o_navTop = opts.navposition === 'top'; classes.remove.push(selectClass); - $arrs.toggle(opts.arrows); + $arrs.toggle(!!opts.arrows); } else { o_nav = false; $arrs.hide(); From f5b496c2a033b48e8669db81b421f16240c359d0 Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoud.beekman@mediact.nl> Date: Sat, 13 Oct 2018 15:05:44 +0200 Subject: [PATCH 0565/1415] Use the correct method to validate if attribute is required --- app/code/Magento/Eav/Model/Attribute/Data/Text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index a26a92df385f2..a919a54cf6289 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -67,7 +67,7 @@ public function validateValue($value) $value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode()); } - if (!$attribute->isRequired() && empty($value)) { + if (!$attribute->getIsRequired() && empty($value)) { return true; } From cc3835f69324ec02ca7982259ebb0a41bad17425 Mon Sep 17 00:00:00 2001 From: Luuk Schakenraad <luuk@chessweb.eu> Date: Sat, 13 Oct 2018 15:47:34 +0200 Subject: [PATCH 0566/1415] Fix empty cart button --- .../Magento/Checkout/view/frontend/templates/cart/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml index 71b1392d5391f..6762033412274 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml @@ -24,7 +24,7 @@ <?php endif ?> <table id="shopping-cart-table" class="cart items data table" - data-mage-init='{"shoppingCart":{"emptyCartButton": "action.clear", + data-mage-init='{"shoppingCart":{"emptyCartButton": ".action.clear", "updateCartActionContainer": "#update_cart_action_container"}}'> <caption role="heading" aria-level="2" class="table-caption"><?= /* @escapeNotVerified */ __('Shopping Cart Items') ?></caption> <thead> From 487d2b3d28f0c107648dfdfa65d336d1708f5a39 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sat, 13 Oct 2018 21:28:41 +0300 Subject: [PATCH 0567/1415] Fix the typo in PHPDoc comment --- .../Backend/Model/Config/SessionLifetime/BackendModel.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Model/Config/SessionLifetime/BackendModel.php b/app/code/Magento/Backend/Model/Config/SessionLifetime/BackendModel.php index c106afb90a09d..f6d08883d7a6f 100644 --- a/app/code/Magento/Backend/Model/Config/SessionLifetime/BackendModel.php +++ b/app/code/Magento/Backend/Model/Config/SessionLifetime/BackendModel.php @@ -16,14 +16,17 @@ */ class BackendModel extends Value { - /** Maximum dmin session lifetime; 1 year*/ + /** Maximum admin session lifetime; 1 year*/ const MAX_LIFETIME = 31536000; /** Minimum admin session lifetime */ const MIN_LIFETIME = 60; /** + * Processing object before save data + * * @since 100.1.0 + * @throws LocalizedException */ public function beforeSave() { From ad85c9546bd06adddd908aef9cc0bb3b2346463e Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Sun, 14 Oct 2018 17:59:50 +0300 Subject: [PATCH 0568/1415] magento/graphql-ce#41: [Query] My Account > My Orders --- .../SalesGraphQl/Model/Resolver/Orders.php | 87 +++++++++++++ app/code/Magento/SalesGraphQl/README.md | 6 + app/code/Magento/SalesGraphQl/composer.json | 27 ++++ app/code/Magento/SalesGraphQl/etc/module.xml | 10 ++ .../Magento/SalesGraphQl/etc/schema.graphqls | 19 +++ .../Magento/SalesGraphQl/registration.php | 10 ++ dev/tests/api-functional/phpunit.xml.dist | 56 +++++++++ .../Magento/GraphQl/Sales/OrdersTest.php | 115 ++++++++++++++++++ .../Sales/_files/order_list_rollback.php | 2 - .../Sales/_files/orders_with_customer.php | 101 +++++++++++++++ .../_files/orders_with_customer_rollback.php | 7 ++ 11 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php create mode 100644 app/code/Magento/SalesGraphQl/README.md create mode 100644 app/code/Magento/SalesGraphQl/composer.json create mode 100644 app/code/Magento/SalesGraphQl/etc/module.xml create mode 100644 app/code/Magento/SalesGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/SalesGraphQl/registration.php create mode 100644 dev/tests/api-functional/phpunit.xml.dist create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php new file mode 100644 index 0000000000000..c6c6ac6203789 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesGraphQl\Model\Resolver; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; + +/** + * {@inheritdoc} + */ +class Orders implements ResolverInterface +{ + /** + * @var UserContextInterface + */ + private $userContext; + + /** + * @var CollectionFactoryInterface + */ + private $collectionFactory; + + /** + * @var CheckCustomerAccountInterface + */ + private $checkCustomerAccount; + + /** + * Orders constructor. + * @param UserContextInterface $userContext + * @param CollectionFactoryInterface $collectionFactory + */ + public function __construct( + UserContextInterface $userContext, + CollectionFactoryInterface $collectionFactory, + CheckCustomerAccountInterface $checkCustomerAccount + ) { + $this->userContext = $userContext; + $this->collectionFactory = $collectionFactory; + $this->checkCustomerAccount = $checkCustomerAccount; + + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + + $customerId = $this->userContext->getUserId(); + + $this->checkCustomerAccount->execute($customerId, $this->userContext->getUserType()); + + $orders = $this->collectionFactory->create($customerId); + $items = []; + + // @TODO Add shipping & billing address in response + // @TODO Add order currency object in response + /** @var \Magento\Sales\Model\Order $order */ + foreach ($orders as $order) { + $items[] = [ + 'id' => $order->getId(), + 'increment_id' => $order->getIncrementId(), + 'created_at' => $order->getCreatedAt(), + 'grant_total' => $order->getGrandTotal(), + 'state' => $order->getState(), + 'status' => $order->getStatus() + ]; + } + + return ['items' => $items]; + } +} \ No newline at end of file diff --git a/app/code/Magento/SalesGraphQl/README.md b/app/code/Magento/SalesGraphQl/README.md new file mode 100644 index 0000000000000..d827613570bad --- /dev/null +++ b/app/code/Magento/SalesGraphQl/README.md @@ -0,0 +1,6 @@ +# SalesGraphQl + +**SalesGraphQl** provides type and resolver information for the GraphQl module +to generate sales orders information endpoints. + +Also will provides endpoints for modifying an order. diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json new file mode 100644 index 0000000000000..b75e18c7b7a97 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -0,0 +1,27 @@ +{ + "name": "magento/module-sales-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-customer": "*", + "magento/module-catalog": "*", + "magento/module-store": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SalesGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/SalesGraphQl/etc/module.xml b/app/code/Magento/SalesGraphQl/etc/module.xml new file mode 100644 index 0000000000000..70a55db67a506 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/etc/module.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_SalesGraphQl"/> +</config> diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..c137484cd2f65 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -0,0 +1,19 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + customerOrders: Orders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") +} + +type Order @doc(description: "Order mapping fields") { + id: Int + increment_id: String + created_at: String + grant_total: Float + state: String + status: String +} + +type Orders { + items: [Order] @doc(description: "Array of orders") +} diff --git a/app/code/Magento/SalesGraphQl/registration.php b/app/code/Magento/SalesGraphQl/registration.php new file mode 100644 index 0000000000000..afb4091bfa32f --- /dev/null +++ b/app/code/Magento/SalesGraphQl/registration.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SalesGraphQl', __DIR__); diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist new file mode 100644 index 0000000000000..c869608462d08 --- /dev/null +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * PHPUnit configuration for GraphQL web API functional tests. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" + colors="true" + columns="max" + beStrictAboutTestsThatDoNotTestAnything="false" + bootstrap="./framework/bootstrap.php" +> + <!-- Test suites definition --> + <testsuites> + <testsuite name="Magento GraphQL web API functional tests"> + <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> + </testsuite> + </testsuites> + + <!-- PHP INI settings and constants definition --> + <php> + <includePath>./testsuite</includePath> + <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> + <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> + <!-- Webserver URL --> + <const name="TESTS_BASE_URL" value="http://magento.inno"/> + <!-- Webserver API user --> + <const name="TESTS_WEBSERVICE_USER" value="admin"/> + <!-- Webserver API key --> + <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> + <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> + <const name="TESTS_XDEBUG_ENABLED" value="true"/> + <!-- Define XDEBUG_SESSION cookie value--> + <const name="TESTS_XDEBUG_SESSION" value="MEETMAGENTO" /> + + <ini name="date.timezone" value="America/Los_Angeles"/> + + <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> + <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> + <!-- Whether to cleanup the application before running tests or not --> + <const name="TESTS_CLEANUP" value="enabled"/> + <!--Defines if Magento should be installed before tests execution--> + <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> + <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> + <const name="TESTS_MAGENTO_MODE" value="default"/> + </php> + + <!-- Test listeners --> + <listeners> + <listener class="Magento\TestFramework\Event\PhpUnit"/> + </listeners> +</phpunit> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php new file mode 100644 index 0000000000000..3a85c044f16a9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Sales; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Class OrdersTest + */ +class OrdersTest extends GraphQlAbstract +{ + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + parent::setUp(); + $objectManager = Bootstrap::getObjectManager(); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php + */ + public function testOrdersQuery() + { + $query = + <<<QUERY +query { + customerOrders { + items { + id + increment_id + created_at + grant_total + state + status + } + } +} +QUERY; + + $currentEmail = 'customer@example.com'; + $currentPassword = 'password'; + + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); + + $expectedData = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grant_total' => 120.00 + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grant_total' => 130.00 + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grant_total' => 140.00 + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grant_total' => 150.00 + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grant_total' => 160.00 + ] + ]; + + $actualData = $response['customerOrders']['items']; + + foreach ($expectedData as $key => $data) { + $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); + $this->assertEquals($data['grant_total'], $actualData[$key]['grant_total']); + $this->assertEquals($data['state'], $actualData[$key]['state']); + $this->assertEquals($data['status'], $actualData[$key]['status']); + } + } + + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php index aae4a557ba1ed..6e24cee501f51 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php @@ -4,6 +4,4 @@ * See COPYING.txt for license details. */ -use Magento\Sales\Model\Order; - require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php new file mode 100644 index 0000000000000..e649396391ca9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order\Address as OrderAddress; + +require 'order.php'; +/** @var Order $order */ +/** @var Order\Payment $payment */ +/** @var Order\Item $orderItem */ +/** @var array $addressData Data for creating addresses for the orders. */ +$orders = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'base_grand_total' => 120.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 130.00, + 'base_grand_total' => 130.00, + 'subtotal' => 130.00, + 'store_id' => 0, + 'website_id' => 0, + 'payment' => $payment + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 150.00, + 'base_grand_total' => 150.00, + 'subtotal' => 150.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 160.00, + 'base_grand_total' => 160.00, + 'subtotal' => 160.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], +]; + +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(OrderRepositoryInterface::class); +/** @var array $orderData */ +foreach ($orders as $orderData) { + /** @var $order \Magento\Sales\Model\Order */ + $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order::class + ); + + // Reset addresses + /** @var Order\Address $billingAddress */ + $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); + $billingAddress->setAddressType('billing'); + + $shippingAddress = clone $billingAddress; + $shippingAddress->setId(null)->setAddressType('shipping'); + + $order + ->setData($orderData) + ->addItem($orderItem) + ->setCustomerIsGuest(false) + ->setCustomerId(1) + ->setCustomerEmail('customer@example.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress); + + $orderRepository->save($order); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php new file mode 100644 index 0000000000000..6e24cee501f51 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; From 84853efc7beccee70ded5a4b0e2ffe96801488b9 Mon Sep 17 00:00:00 2001 From: Pratik Oza <pratik.oza@krishtechnolabs.com> Date: Sun, 14 Oct 2018 20:43:05 +0530 Subject: [PATCH 0569/1415] Replace intval() function by using direct type casting to (int) --- .../Adminhtml/Product/Attribute/Set/Main/Formgroup.php | 4 ++-- .../Catalog/Model/ProductLink/CollectionProvider.php | 4 ++-- .../CatalogImportExport/Model/Export/Product.php | 2 +- .../Config/Model/Config/Backend/Currency/Cron.php | 4 ++-- .../Magento/Config/Model/Config/Backend/Log/Cron.php | 4 ++-- .../Cron/Model/Config/Backend/Product/Alert.php | 4 ++-- app/code/Magento/Cron/Model/Config/Backend/Sitemap.php | 4 ++-- .../Block/Adminhtml/Edit/Tab/View/PersonalInfo.php | 2 +- app/code/Magento/Customer/Model/Renderer/Region.php | 2 +- app/code/Magento/Customer/Model/Visitor.php | 8 +++----- app/code/Magento/Directory/Block/Data.php | 2 +- .../Eav/Model/ResourceModel/Entity/Attribute.php | 2 +- .../Elasticsearch/Model/Adapter/Elasticsearch.php | 2 +- .../SearchAdapter/Dynamic/DataProvider.php | 2 +- .../GroupedProduct/Model/Product/Type/Grouped.php | 2 +- app/code/Magento/Paypal/Model/Api/AbstractApi.php | 2 +- app/code/Magento/Paypal/Model/Express.php | 8 ++++---- app/code/Magento/Paypal/Model/Report/Settlement.php | 2 +- app/code/Magento/Persistent/Helper/Data.php | 10 ++++------ app/code/Magento/Persistent/Model/Session.php | 2 +- app/code/Magento/Quote/Model/Quote.php | 2 +- .../Magento/Review/Block/Adminhtml/Rating/Detailed.php | 4 ++-- .../Magento/Review/Block/Rating/Entity/Detailed.php | 2 +- .../Controller/Adminhtml/Product/JsonProductInfo.php | 2 +- .../Security/Test/Unit/Model/SecurityCookieTest.php | 4 ++-- .../Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php | 2 +- app/code/Magento/Theme/Block/Html/Pager.php | 4 ++-- app/code/Magento/User/Block/Buttons.php | 4 ++-- app/code/Magento/User/Model/User.php | 2 +- app/code/Magento/Wishlist/Helper/Rss.php | 2 +- .../Wishlist/Model/ResourceModel/Item/Collection.php | 2 +- 31 files changed, 49 insertions(+), 53 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php index ee92fd7c19b80..d12b280e2341c 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php @@ -81,9 +81,9 @@ protected function _prepareForm() */ protected function _getSetId() { - return intval( + return (int)( $this->getRequest()->getParam('id') - ) > 0 ? intval( + ) > 0 ? (int)( $this->getRequest()->getParam('id') ) : $this->_typeFactory->create()->load( $this->_coreRegistry->registry('entityType') diff --git a/app/code/Magento/Catalog/Model/ProductLink/CollectionProvider.php b/app/code/Magento/Catalog/Model/ProductLink/CollectionProvider.php index 13f0dbf79a1b9..b96aff148e750 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/CollectionProvider.php +++ b/app/code/Magento/Catalog/Model/ProductLink/CollectionProvider.php @@ -58,8 +58,8 @@ public function getCollection(\Magento\Catalog\Model\Product $product, $type) } usort($sorterItems, function ($itemA, $itemB) { - $posA = intval($itemA['position']); - $posB = intval($itemB['position']); + $posA = (int)$itemA['position']; + $posB = (int)$itemB['position']; return $posA <=> $posB; }); diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 096d8495d70cd..345d323e6e129 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -806,7 +806,7 @@ protected function getItemsPerPage() // Maximal Products limit $maxProductsLimit = 5000; - $this->_itemsPerPage = intval( + $this->_itemsPerPage = (int)( ($memoryLimit * $memoryUsagePercent - memory_get_usage(true)) / $memoryPerProduct ); if ($this->_itemsPerPage < $minProductsLimit) { diff --git a/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php b/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php index 3f80e01802b8d..c3ec83d4dd981 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php +++ b/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php @@ -59,8 +59,8 @@ public function afterSave() $frequencyMonthly = \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY; $cronExprArray = [ - intval($time[1]), # Minute - intval($time[0]), # Hour + (int)$time[1], # Minute + (int)$time[0], # Hour $frequency == $frequencyMonthly ? '1' : '*', # Day of the Month '*', # Month of the Year $frequency == $frequencyWeekly ? '1' : '*', # Day of the Week diff --git a/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php b/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php index 3c36baf6f31f4..7a0eb6652d1ba 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php +++ b/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php @@ -73,8 +73,8 @@ public function afterSave() if ($enabled) { $cronExprArray = [ - intval($time[1]), # Minute - intval($time[0]), # Hour + (int)$time[1], # Minute + (int)$time[0], # Hour $frequency == $frequencyMonthly ? '1' : '*', # Day of the Month '*', # Month of the Year $frequency == $frequencyWeekly ? '1' : '*', # Day of the Week diff --git a/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php b/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php index 2fc0f0ab4c1a0..c5e3323716a1b 100644 --- a/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php +++ b/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php @@ -72,8 +72,8 @@ public function afterSave() $frequency = $this->getData('groups/productalert_cron/fields/frequency/value'); $cronExprArray = [ - intval($time[1]), //Minute - intval($time[0]), //Hour + (int)$time[1], //Minute + (int)$time[0], //Hour $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY ? '1' : '*', //Day of the Month '*', //Month of the Year $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_WEEKLY ? '1' : '*', //Day of the Week diff --git a/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php b/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php index 681129916647d..31d8ba59ee42d 100644 --- a/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php +++ b/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php @@ -70,8 +70,8 @@ public function afterSave() $frequency = $this->getData('groups/generate/fields/frequency/value'); $cronExprArray = [ - intval($time[1]), //Minute - intval($time[0]), //Hour + (int)$time[1], //Minute + (int)$time[0], //Hour $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY ? '1' : '*', //Day of the Month '*', //Month of the Year $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_WEEKLY ? '1' : '*', //# Day of the Week diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php index 81b7b8b3f96b5..c7023d0404f75 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php @@ -461,7 +461,7 @@ protected function getOnlineMinutesInterval() 'customer/online_customers/online_minutes_interval', \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); - return intval($configValue) > 0 ? intval($configValue) : self::DEFAULT_ONLINE_MINUTES_INTERVAL; + return (int)$configValue > 0 ? (int)$configValue : self::DEFAULT_ONLINE_MINUTES_INTERVAL; } /** diff --git a/app/code/Magento/Customer/Model/Renderer/Region.php b/app/code/Magento/Customer/Model/Renderer/Region.php index 5c7fcd38d6c52..ad620e4e4b3f2 100644 --- a/app/code/Magento/Customer/Model/Renderer/Region.php +++ b/app/code/Magento/Customer/Model/Renderer/Region.php @@ -80,7 +80,7 @@ public function render(AbstractElement $element) $regionCollection = self::$_regionCollections[$countryId]; } - $regionId = intval($element->getForm()->getElement('region_id')->getValue()); + $regionId = (int)$element->getForm()->getElement('region_id')->getValue(); $htmlAttributes = $element->getHtmlAttributes(); foreach ($htmlAttributes as $key => $attribute) { diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php index a0530389f902a..d144b7f6b70ec 100644 --- a/app/code/Magento/Customer/Model/Visitor.php +++ b/app/code/Magento/Customer/Model/Visitor.php @@ -320,11 +320,9 @@ public function clean() */ public function getOnlineInterval() { - $configValue = intval( - $this->scopeConfig->getValue( - static::XML_PATH_ONLINE_INTERVAL, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) + $configValue = (int)$this->scopeConfig->getValue( + static::XML_PATH_ONLINE_INTERVAL, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); return $configValue ?: static::DEFAULT_ONLINE_MINUTES_INTERVAL; } diff --git a/app/code/Magento/Directory/Block/Data.php b/app/code/Magento/Directory/Block/Data.php index ca2b4b95b5574..630c0966bc2f9 100644 --- a/app/code/Magento/Directory/Block/Data.php +++ b/app/code/Magento/Directory/Block/Data.php @@ -184,7 +184,7 @@ public function getRegionHtmlSelect() )->setClass( 'required-entry validate-state' )->setValue( - intval($this->getRegionId()) + (int)$this->getRegionId() )->setOptions( $options )->getHtml(); diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 88f58c6d0111c..44080ebd13001 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -119,7 +119,7 @@ public function loadByCode(AbstractModel $object, $entityTypeId, $code) */ private function _getMaxSortOrder(AbstractModel $object) { - if (intval($object->getAttributeGroupId()) > 0) { + if ((int)$object->getAttributeGroupId() > 0) { $connection = $this->getConnection(); $bind = [ ':attribute_set_id' => $object->getAttributeSetId(), diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 7fc45eed35650..8f606d179563b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -197,7 +197,7 @@ public function cleanIndex($storeId, $mappedIndexerId) // prepare new index name and increase version $indexPattern = $this->indexNameResolver->getIndexPattern($storeId, $mappedIndexerId); - $version = intval(str_replace($indexPattern, '', $indexName)); + $version = (int)(str_replace($indexPattern, '', $indexName)); $newIndexName = $indexPattern . ++$version; // remove index if already exists diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 0add517ba94ad..59dc4db553ebf 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -217,7 +217,7 @@ public function getAggregation( $queryResult = $this->connectionManager->getConnection() ->query($query); foreach ($queryResult['aggregations']['prices']['buckets'] as $bucket) { - $key = intval($bucket['key'] / $range + 1); + $key = (int)($bucket['key'] / $range + 1); $result[$key] = $bucket['doc_count']; } diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index e1c97c8912cf8..b6a3aede21ad2 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -341,7 +341,7 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr if ($isStrictProcessMode && !$subProduct->getQty()) { return __('Please specify the quantity of product(s).')->render(); } - $productsInfo[$subProduct->getId()] = intval($subProduct->getQty()); + $productsInfo[$subProduct->getId()] = (int)$subProduct->getQty(); } } diff --git a/app/code/Magento/Paypal/Model/Api/AbstractApi.php b/app/code/Magento/Paypal/Model/Api/AbstractApi.php index 6f578e44eae4f..d5cd69d68952c 100644 --- a/app/code/Magento/Paypal/Model/Api/AbstractApi.php +++ b/app/code/Magento/Paypal/Model/Api/AbstractApi.php @@ -584,7 +584,7 @@ protected function _buildQuery($request) */ protected function _filterQty($value) { - return intval($value); + return (int)$value; } /** diff --git a/app/code/Magento/Paypal/Model/Express.php b/app/code/Magento/Paypal/Model/Express.php index 4684abdc9be6d..196e59c6593b9 100644 --- a/app/code/Magento/Paypal/Model/Express.php +++ b/app/code/Magento/Paypal/Model/Express.php @@ -432,8 +432,8 @@ public function void(\Magento\Payment\Model\InfoInterface $payment) public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) { $authorizationTransaction = $payment->getAuthorizationTransaction(); - $authorizationPeriod = abs(intval($this->getConfigData('authorization_honor_period'))); - $maxAuthorizationNumber = abs(intval($this->getConfigData('child_authorization_number'))); + $authorizationPeriod = abs((int)$this->getConfigData('authorization_honor_period')); + $maxAuthorizationNumber = abs((int)$this->getConfigData('child_authorization_number')); $order = $payment->getOrder(); $isAuthorizationCreated = false; @@ -750,7 +750,7 @@ public function canCapture() return false; } - $orderValidPeriod = abs(intval($this->getConfigData('order_valid_period'))); + $orderValidPeriod = abs((int)$this->getConfigData('order_valid_period')); $dateCompass = new \DateTime($orderTransaction->getCreatedAt()); $dateCompass->modify('+' . $orderValidPeriod . ' days'); @@ -805,7 +805,7 @@ protected function _callDoAuthorize($amount, $payment, $parentTransactionId) */ protected function _isTransactionExpired(Transaction $transaction, $period) { - $period = intval($period); + $period = (int)$period; if (0 == $period) { return true; } diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index 5dc51518f0b11..0aa2387e623bc 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -446,7 +446,7 @@ private function formatDateTimeColumns($lineItem) */ private function formatAmountColumn($lineItem) { - return intval($lineItem) / 100; + return (int)$lineItem / 100; } /** diff --git a/app/code/Magento/Persistent/Helper/Data.php b/app/code/Magento/Persistent/Helper/Data.php index 39a9ce7a8ef43..c963084a1ecb1 100644 --- a/app/code/Magento/Persistent/Helper/Data.php +++ b/app/code/Magento/Persistent/Helper/Data.php @@ -136,12 +136,10 @@ public function isShoppingCartPersist($store = null) */ public function getLifeTime($store = null) { - $lifeTime = intval( - $this->scopeConfig->getValue( - self::XML_PATH_LIFE_TIME, - ScopeInterface::SCOPE_STORE, - $store - ) + $lifeTime = (int)$this->scopeConfig->getValue( + self::XML_PATH_LIFE_TIME, + ScopeInterface::SCOPE_STORE, + $store ); return $lifeTime < 0 ? 0 : $lifeTime; } diff --git a/app/code/Magento/Persistent/Model/Session.php b/app/code/Magento/Persistent/Model/Session.php index abc344671ab70..3aea20a090dd9 100644 --- a/app/code/Magento/Persistent/Model/Session.php +++ b/app/code/Magento/Persistent/Model/Session.php @@ -354,7 +354,7 @@ public function deleteExpired($websiteId = null) $lifetime = $this->_coreConfig->getValue( \Magento\Persistent\Helper\Data::XML_PATH_LIFE_TIME, 'website', - intval($websiteId) + (int)$websiteId ); if ($lifetime) { diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index 8991f7f06d150..3f04519713687 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -2329,7 +2329,7 @@ public function isVirtual() */ public function getIsVirtual() { - return intval($this->isVirtual()); + return (int)$this->isVirtual(); } /** diff --git a/app/code/Magento/Review/Block/Adminhtml/Rating/Detailed.php b/app/code/Magento/Review/Block/Adminhtml/Rating/Detailed.php index adad931da5a69..a02c998f856bd 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Rating/Detailed.php +++ b/app/code/Magento/Review/Block/Adminhtml/Rating/Detailed.php @@ -121,9 +121,9 @@ public function getRating() )->setStoreFilter( $stores )->setPositionOrder()->load()->addOptionToItems(); - if (intval($this->getRequest()->getParam('id'))) { + if ((int)$this->getRequest()->getParam('id')) { $this->_voteCollection = $this->_votesFactory->create()->setReviewFilter( - intval($this->getRequest()->getParam('id')) + (int)$this->getRequest()->getParam('id') )->addOptionInfo()->load()->addRatingOptions(); } } diff --git a/app/code/Magento/Review/Block/Rating/Entity/Detailed.php b/app/code/Magento/Review/Block/Rating/Entity/Detailed.php index eee00483ace66..eccbfe1acee54 100644 --- a/app/code/Magento/Review/Block/Rating/Entity/Detailed.php +++ b/app/code/Magento/Review/Block/Rating/Entity/Detailed.php @@ -42,7 +42,7 @@ public function __construct( protected function _toHtml() { $entityId = $this->_request->getParam('id'); - if (intval($entityId) <= 0) { + if ((int)$entityId <= 0) { return ''; } diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php index bfd4b5e747043..ea19e25ba6855 100644 --- a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php +++ b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php @@ -47,7 +47,7 @@ public function execute() { $response = new DataObject(); $id = $this->getRequest()->getParam('id'); - if (intval($id) > 0) { + if ((int)$id > 0) { $product = $this->productRepository->getById($id); $response->setId($id); $response->addData($product->getData()); diff --git a/app/code/Magento/Security/Test/Unit/Model/SecurityCookieTest.php b/app/code/Magento/Security/Test/Unit/Model/SecurityCookieTest.php index b310bf63bc989..3a1855b3a220f 100644 --- a/app/code/Magento/Security/Test/Unit/Model/SecurityCookieTest.php +++ b/app/code/Magento/Security/Test/Unit/Model/SecurityCookieTest.php @@ -87,7 +87,7 @@ public function testGetLogoutReasonCookie() ) ->willReturn($cookie); - $this->assertEquals(intval($cookie), $this->model->getLogoutReasonCookie()); + $this->assertEquals((int)$cookie, $this->model->getLogoutReasonCookie()); } /** @@ -114,7 +114,7 @@ public function testSetLogoutReasonCookie() ->method('setPublicCookie') ->with( SecurityCookie::LOGOUT_REASON_CODE_COOKIE_NAME, - intval($status), + (int)$status, $this->cookieMetadataMock ) ->willReturnSelf(); diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php index 4eaaa3be8a8f2..50e7437396b0c 100644 --- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php +++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php @@ -115,7 +115,7 @@ protected function _prepareLayout() ['label' => __('Reset'), 'onclick' => 'window.location.reload()', 'class' => 'reset'] ); - $rate = intval($this->getRequest()->getParam('rate')); + $rate = (int)$this->getRequest()->getParam('rate'); if ($rate) { $this->buttonList->add( 'delete', diff --git a/app/code/Magento/Theme/Block/Html/Pager.php b/app/code/Magento/Theme/Block/Html/Pager.php index d4cfe544f4792..3d66113ac613d 100644 --- a/app/code/Magento/Theme/Block/Html/Pager.php +++ b/app/code/Magento/Theme/Block/Html/Pager.php @@ -580,7 +580,7 @@ public function getJump() */ public function setFrameLength($frame) { - $frame = abs(intval($frame)); + $frame = abs((int)$frame); if ($frame == 0) { $frame = $this->_frameLength; } @@ -600,7 +600,7 @@ public function setFrameLength($frame) */ public function setJump($jump) { - $jump = abs(intval($jump)); + $jump = abs((int)$jump); if ($this->getJump() != $jump) { $this->_setFrameInitialized(false); $this->_jump = $jump; diff --git a/app/code/Magento/User/Block/Buttons.php b/app/code/Magento/User/Block/Buttons.php index b411f1c0cf8cd..bb7375ae83277 100644 --- a/app/code/Magento/User/Block/Buttons.php +++ b/app/code/Magento/User/Block/Buttons.php @@ -53,7 +53,7 @@ protected function _prepareLayout() ['label' => __('Reset'), 'onclick' => 'window.location.reload()', 'class' => 'reset'] ); - if (intval($this->getRequest()->getParam('rid'))) { + if ((int)$this->getRequest()->getParam('rid')) { $this->getToolbar()->addChild( 'deleteButton', \Magento\Backend\Block\Widget\Button::class, @@ -113,7 +113,7 @@ public function getSaveButtonHtml() */ public function getDeleteButtonHtml() { - if (intval($this->getRequest()->getParam('rid')) == 0) { + if ((int)$this->getRequest()->getParam('rid') == 0) { return; } return $this->getChildHtml('deleteButton'); diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index 4050d79e593ee..2994ac351fc78 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -276,7 +276,7 @@ public function beforeSave() } if ($this->getIsActive() !== null) { - $data['is_active'] = intval($this->getIsActive()); + $data['is_active'] = (int)$this->getIsActive(); } $this->addData($data); diff --git a/app/code/Magento/Wishlist/Helper/Rss.php b/app/code/Magento/Wishlist/Helper/Rss.php index 14ca52e92ad84..bb47aeb319410 100644 --- a/app/code/Magento/Wishlist/Helper/Rss.php +++ b/app/code/Magento/Wishlist/Helper/Rss.php @@ -104,7 +104,7 @@ public function getCustomer() if ($this->_customer === null) { $params = $this->urlDecoder->decode($this->_getRequest()->getParam('data')); $data = explode(',', $params); - $customerId = abs(intval($data[0])); + $customerId = abs((int)$data[0]); if ($customerId && ($customerId == $this->_customerSession->getCustomerId())) { $this->_customer = $this->_customerRepository->getById($customerId); } else { diff --git a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php index b285270c67ef8..5c131d27fb8d4 100644 --- a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php +++ b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php @@ -481,7 +481,7 @@ public function addDaysFilter($constraints) if (isset($constraints['to'])) { $firstDay = new \DateTime(); - $firstDay->modify('-' . $gmtOffset . ' second')->modify('-' . (intval($constraints['to']) + 1) . ' day'); + $firstDay->modify('-' . $gmtOffset . ' second')->modify('-' . ((int)($constraints['to']) + 1) . ' day'); $filter['from'] = $firstDay; } From 620d14d01365a1907f4abc19b3c50882aef86c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gheolt=CC=A6an?= <daniel.gheoltan@mindmagnetsoftware.com> Date: Sun, 14 Oct 2018 18:29:29 +0300 Subject: [PATCH 0570/1415] Binding to event collapsible scroll --- lib/web/mage/collapsible.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/web/mage/collapsible.js b/lib/web/mage/collapsible.js index 69e576bba604a..a6a1dcde6c87a 100644 --- a/lib/web/mage/collapsible.js +++ b/lib/web/mage/collapsible.js @@ -63,6 +63,12 @@ define([ this.icons = true; } + this.element.on('dimensionsChanged',function(e) { + if(e.target && e.target.classList.contains('active')) { + this._scrollToTopIfVisible(e.target); + } + }.bind(this)); + this._bind('click'); this._trigger('created'); }, @@ -453,9 +459,6 @@ define([ if (this.options.animate) { this._animate(showProps); } else { - if (this.content.length) { - this._scrollToTopIfVisible(this.content.get(0).parentElement); - } this.content.show(); } this._open(); From 087257703657d85bf06a9cf78f9efc80151389eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gheolt=CC=A6an?= <daniel.gheoltan@mindmagnetsoftware.com> Date: Sun, 14 Oct 2018 18:45:52 +0300 Subject: [PATCH 0571/1415] Binding to event collapsible scroll --- lib/web/mage/collapsible.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/mage/collapsible.js b/lib/web/mage/collapsible.js index a6a1dcde6c87a..3d283d102e323 100644 --- a/lib/web/mage/collapsible.js +++ b/lib/web/mage/collapsible.js @@ -63,8 +63,8 @@ define([ this.icons = true; } - this.element.on('dimensionsChanged',function(e) { - if(e.target && e.target.classList.contains('active')) { + this.element.on('dimensionsChanged', function (e) { + if (e.target && e.target.classList.contains('active')) { this._scrollToTopIfVisible(e.target); } }.bind(this)); From 623a6b01330545582c3337813d803691faefef87 Mon Sep 17 00:00:00 2001 From: Luuk Schakenraad <luuk@chessweb.eu> Date: Sun, 14 Oct 2018 19:25:42 +0200 Subject: [PATCH 0572/1415] Fix disappearing navigation arrows in fotorama zoom also in fotorama.min.js --- lib/web/fotorama/fotorama.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/fotorama/fotorama.min.js b/lib/web/fotorama/fotorama.min.js index 9842f20cdc2af..0a0cbd9db7e74 100644 --- a/lib/web/fotorama/fotorama.min.js +++ b/lib/web/fotorama/fotorama.min.js @@ -1 +1 @@ -fotoramaVersion="4.6.4";(function(window,document,location,$,undefined){"use strict";var _fotoramaClass="fotorama",_fullscreenClass="fotorama__fullscreen",wrapClass=_fotoramaClass+"__wrap",wrapCss2Class=wrapClass+"--css2",wrapCss3Class=wrapClass+"--css3",wrapVideoClass=wrapClass+"--video",wrapFadeClass=wrapClass+"--fade",wrapSlideClass=wrapClass+"--slide",wrapNoControlsClass=wrapClass+"--no-controls",wrapNoShadowsClass=wrapClass+"--no-shadows",wrapPanYClass=wrapClass+"--pan-y",wrapRtlClass=wrapClass+"--rtl",wrapOnlyActiveClass=wrapClass+"--only-active",wrapNoCaptionsClass=wrapClass+"--no-captions",wrapToggleArrowsClass=wrapClass+"--toggle-arrows",stageClass=_fotoramaClass+"__stage",stageFrameClass=stageClass+"__frame",stageFrameVideoClass=stageFrameClass+"--video",stageShaftClass=stageClass+"__shaft",grabClass=_fotoramaClass+"__grab",pointerClass=_fotoramaClass+"__pointer",arrClass=_fotoramaClass+"__arr",arrDisabledClass=arrClass+"--disabled",arrPrevClass=arrClass+"--prev",arrNextClass=arrClass+"--next",navClass=_fotoramaClass+"__nav",navWrapClass=navClass+"-wrap",navShaftClass=navClass+"__shaft",navShaftVerticalClass=navWrapClass+"--vertical",navShaftListClass=navWrapClass+"--list",navShafthorizontalClass=navWrapClass+"--horizontal",navDotsClass=navClass+"--dots",navThumbsClass=navClass+"--thumbs",navFrameClass=navClass+"__frame",fadeClass=_fotoramaClass+"__fade",fadeFrontClass=fadeClass+"-front",fadeRearClass=fadeClass+"-rear",shadowClass=_fotoramaClass+"__shadow",shadowsClass=shadowClass+"s",shadowsLeftClass=shadowsClass+"--left",shadowsRightClass=shadowsClass+"--right",shadowsTopClass=shadowsClass+"--top",shadowsBottomClass=shadowsClass+"--bottom",activeClass=_fotoramaClass+"__active",selectClass=_fotoramaClass+"__select",hiddenClass=_fotoramaClass+"--hidden",fullscreenClass=_fotoramaClass+"--fullscreen",fullscreenIconClass=_fotoramaClass+"__fullscreen-icon",errorClass=_fotoramaClass+"__error",loadingClass=_fotoramaClass+"__loading",loadedClass=_fotoramaClass+"__loaded",loadedFullClass=loadedClass+"--full",loadedImgClass=loadedClass+"--img",grabbingClass=_fotoramaClass+"__grabbing",imgClass=_fotoramaClass+"__img",imgFullClass=imgClass+"--full",thumbClass=_fotoramaClass+"__thumb",thumbArrLeft=thumbClass+"__arr--left",thumbArrRight=thumbClass+"__arr--right",thumbBorderClass=thumbClass+"-border",htmlClass=_fotoramaClass+"__html",videoContainerClass=_fotoramaClass+"-video-container",videoClass=_fotoramaClass+"__video",videoPlayClass=videoClass+"-play",videoCloseClass=videoClass+"-close",horizontalImageClass=_fotoramaClass+"_horizontal_ratio",verticalImageClass=_fotoramaClass+"_vertical_ratio",fotoramaSpinnerClass=_fotoramaClass+"__spinner",spinnerShowClass=fotoramaSpinnerClass+"--show";var JQUERY_VERSION=$&&$.fn.jquery.split(".");if(!JQUERY_VERSION||JQUERY_VERSION[0]<1||JQUERY_VERSION[0]==1&&JQUERY_VERSION[1]<8){throw"Fotorama requires jQuery 1.8 or later and will not run without it."}var _={};var Modernizr=function(window,document,undefined){var version="2.8.3",Modernizr={},docElement=document.documentElement,mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,inputElem,toString={}.toString,prefixes=" -webkit- -moz- -o- -ms- ".split(" "),omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),body=document.body,fakeBody=body||document.createElement("body");if(parseInt(nodes,10)){while(nodes--){node=document.createElement("div");node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node)}}style=["­",'<style id="s',mod,'">',rule,"</style>"].join("");div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background="";fakeBody.style.overflow="hidden";docOverflow=docElement.style.overflow;docElement.style.overflow="hidden";docElement.appendChild(fakeBody)}ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow}else{div.parentNode.removeChild(div)}return!!ret},_hasOwnProperty={}.hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,"undefined")&&!is(_hasOwnProperty.call,"undefined")){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property)}}else{hasOwnProp=function(object,property){return property in object&&is(object.constructor.prototype[property],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError}var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F;var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result}return self}else{return target.apply(that,args.concat(slice.call(arguments)))}};return bound}}function setCss(str){mStyle.cssText=str}function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}function is(obj,type){return typeof obj===type}function contains(str,substr){return!!~(""+str).indexOf(substr)}function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=="pfx"?prop:true}}return false}function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,"function")){return item.bind(elem||obj)}return item}}return false}function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed)}else{props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" ");return testDOMProps(props,prefixed,elem)}}tests["touch"]=function(){var bool;if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch){bool=true}else{injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=node.offsetTop===9})}return bool};tests["csstransforms3d"]=function(){var ret=!!testPropsAll("perspective");if(ret&&"webkitPerspective"in docElement.style){injectElementWithStyles("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3})}return ret};tests["csstransitions"]=function(){return testPropsAll("transition")};for(var feature in tests){if(hasOwnProp(tests,feature)){featureName=feature.toLowerCase();Modernizr[featureName]=tests[feature]();classes.push((Modernizr[featureName]?"":"no-")+featureName)}}Modernizr.addTest=function(feature,test){if(typeof feature=="object"){for(var key in feature){if(hasOwnProp(feature,key)){Modernizr.addTest(key,feature[key])}}}else{feature=feature.toLowerCase();if(Modernizr[feature]!==undefined){return Modernizr}test=typeof test=="function"?test():test;if(typeof enableClasses!=="undefined"&&enableClasses){docElement.className+=" "+(test?"":"no-")+feature}Modernizr[feature]=test}return Modernizr};setCss("");modElem=inputElem=null;Modernizr._version=version;Modernizr._prefixes=prefixes;Modernizr._domPrefixes=domPrefixes;Modernizr._cssomPrefixes=cssomPrefixes;Modernizr.testProp=function(prop){return testProps([prop])};Modernizr.testAllProps=testPropsAll;Modernizr.testStyles=injectElementWithStyles;Modernizr.prefixed=function(prop,obj,elem){if(!obj){return testPropsAll(prop,"pfx")}else{return testPropsAll(prop,obj,elem)}};return Modernizr}(window,document);var fullScreenApi={ok:false,is:function(){return false},request:function(){},cancel:function(){},event:"",prefix:""},browserPrefixes="webkit moz o ms khtml".split(" ");if(typeof document.cancelFullScreen!="undefined"){fullScreenApi.ok=true}else{for(var i=0,il=browserPrefixes.length;i<il;i++){fullScreenApi.prefix=browserPrefixes[i];if(typeof document[fullScreenApi.prefix+"CancelFullScreen"]!="undefined"){fullScreenApi.ok=true;break}}}if(fullScreenApi.ok){fullScreenApi.event=fullScreenApi.prefix+"fullscreenchange";fullScreenApi.is=function(){switch(this.prefix){case"":return document.fullScreen;case"webkit":return document.webkitIsFullScreen;default:return document[this.prefix+"FullScreen"]}};fullScreenApi.request=function(el){return this.prefix===""?el.requestFullScreen():el[this.prefix+"RequestFullScreen"]()};fullScreenApi.cancel=function(el){return this.prefix===""?document.cancelFullScreen():document[this.prefix+"CancelFullScreen"]()}}function bez(coOrdArray){var encodedFuncName="bez_"+$.makeArray(arguments).join("_").replace(".","p");if(typeof $["easing"][encodedFuncName]!=="function"){var polyBez=function(p1,p2){var A=[null,null],B=[null,null],C=[null,null],bezCoOrd=function(t,ax){C[ax]=3*p1[ax];B[ax]=3*(p2[ax]-p1[ax])-C[ax];A[ax]=1-C[ax]-B[ax];return t*(C[ax]+t*(B[ax]+t*A[ax]))},xDeriv=function(t){return C[0]+t*(2*B[0]+3*A[0]*t)},xForT=function(t){var x=t,i=0,z;while(++i<14){z=bezCoOrd(x,0)-t;if(Math.abs(z)<.001)break;x-=z/xDeriv(x)}return x};return function(t){return bezCoOrd(xForT(t),1)}};$["easing"][encodedFuncName]=function(x,t,b,c,d){return c*polyBez([coOrdArray[0],coOrdArray[1]],[coOrdArray[2],coOrdArray[3]])(t/d)+b}}return encodedFuncName}var $WINDOW=$(window),$DOCUMENT=$(document),$HTML,$BODY,QUIRKS_FORCE=location.hash.replace("#","")==="quirks",TRANSFORMS3D=Modernizr.csstransforms3d,CSS3=TRANSFORMS3D&&!QUIRKS_FORCE,COMPAT=TRANSFORMS3D||document.compatMode==="CSS1Compat",FULLSCREEN=fullScreenApi.ok,MOBILE=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),SLOW=!CSS3||MOBILE,MS_POINTER=navigator.msPointerEnabled,WHEEL="onwheel"in document.createElement("div")?"wheel":document.onmousewheel!==undefined?"mousewheel":"DOMMouseScroll",TOUCH_TIMEOUT=250,TRANSITION_DURATION=300,SCROLL_LOCK_TIMEOUT=1400,AUTOPLAY_INTERVAL=5e3,MARGIN=2,THUMB_SIZE=64,WIDTH=500,HEIGHT=333,STAGE_FRAME_KEY="$stageFrame",NAV_DOT_FRAME_KEY="$navDotFrame",NAV_THUMB_FRAME_KEY="$navThumbFrame",AUTO="auto",BEZIER=bez([.1,0,.25,1]),MAX_WIDTH=1200,thumbsPerSlide=1,OPTIONS={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:MARGIN,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:THUMB_SIZE,thumbheight:THUMB_SIZE,thumbmargin:MARGIN,thumbborderwidth:MARGIN,allowfullscreen:false,transition:"slide",clicktransition:null,transitionduration:TRANSITION_DURATION,captions:true,startindex:0,loop:false,autoplay:false,stopautoplayontouch:true,keyboard:false,arrows:true,click:true,swipe:false,trackpad:false,shuffle:false,direction:"ltr",shadows:true,showcaption:true,navdir:"horizontal",navarrows:true,navtype:"thumbs"},KEYBOARD_OPTIONS={left:true,right:true,down:true,up:true,space:false,home:false,end:false};function noop(){}function minMaxLimit(value,min,max){return Math.max(isNaN(min)?-Infinity:min,Math.min(isNaN(max)?Infinity:max,value))}function readTransform(css,dir){return css.match(/ma/)&&css.match(/-?\d+(?!d)/g)[css.match(/3d/)?dir==="vertical"?13:12:dir==="vertical"?5:4]}function readPosition($el,dir){if(CSS3){return+readTransform($el.css("transform"),dir)}else{return+$el.css(dir==="vertical"?"top":"left").replace("px","")}}function getTranslate(pos,direction){var obj={};if(CSS3){switch(direction){case"vertical":obj.transform="translate3d(0, "+pos+"px,0)";break;case"list":break;default:obj.transform="translate3d("+pos+"px,0,0)";break}}else{direction==="vertical"?obj.top=pos:obj.left=pos}return obj}function getDuration(time){return{"transition-duration":time+"ms"}}function unlessNaN(value,alternative){return isNaN(value)?alternative:value}function numberFromMeasure(value,measure){return unlessNaN(+String(value).replace(measure||"px",""))}function numberFromPercent(value){return/%$/.test(value)?numberFromMeasure(value,"%"):undefined}function numberFromWhatever(value,whole){return unlessNaN(numberFromPercent(value)/100*whole,numberFromMeasure(value))}function measureIsValid(value){return(!isNaN(numberFromMeasure(value))||!isNaN(numberFromMeasure(value,"%")))&&value}function getPosByIndex(index,side,margin,baseIndex){return(index-(baseIndex||0))*(side+(margin||0))}function getIndexByPos(pos,side,margin,baseIndex){return-Math.round(pos/(side+(margin||0))-(baseIndex||0))}function bindTransitionEnd($el){var elData=$el.data();if(elData.tEnd)return;var el=$el[0],transitionEndEvent={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};addEvent(el,transitionEndEvent[Modernizr.prefixed("transition")],function(e){elData.tProp&&e.propertyName.match(elData.tProp)&&elData.onEndFn()});elData.tEnd=true}function afterTransition($el,property,fn,time){var ok,elData=$el.data();if(elData){elData.onEndFn=function(){if(ok)return;ok=true;clearTimeout(elData.tT);fn()};elData.tProp=property;clearTimeout(elData.tT);elData.tT=setTimeout(function(){elData.onEndFn()},time*1.5);bindTransitionEnd($el)}}function stop($el,pos){var dir=$el.navdir||"horizontal";if($el.length){var elData=$el.data();if(CSS3){$el.css(getDuration(0));elData.onEndFn=noop;clearTimeout(elData.tT)}else{$el.stop()}var lockedPos=getNumber(pos,function(){return readPosition($el,dir)});$el.css(getTranslate(lockedPos,dir));return lockedPos}}function getNumber(){var number;for(var _i=0,_l=arguments.length;_i<_l;_i++){number=_i?arguments[_i]():arguments[_i];if(typeof number==="number"){break}}return number}function edgeResistance(pos,edge){return Math.round(pos+(edge-pos)/1.5)}function getProtocol(){getProtocol.p=getProtocol.p||(location.protocol==="https:"?"https://":"http://");return getProtocol.p}function parseHref(href){var a=document.createElement("a");a.href=href;return a}function findVideoId(href,forceVideo){if(typeof href!=="string")return href;href=parseHref(href);var id,type;if(href.host.match(/youtube\.com/)&&href.search){id=href.search.split("v=")[1];if(id){var ampersandPosition=id.indexOf("&");if(ampersandPosition!==-1){id=id.substring(0,ampersandPosition)}type="youtube"}}else if(href.host.match(/youtube\.com|youtu\.be/)){id=href.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,"");type="youtube"}else if(href.host.match(/vimeo\.com/)){type="vimeo";id=href.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,"")}if((!id||!type)&&forceVideo){id=href.href;type="custom"}return id?{id:id,type:type,s:href.search.replace(/^\?/,""),p:getProtocol()}:false}function getVideoThumbs(dataFrame,data,fotorama){var img,thumb,video=dataFrame.video;if(video.type==="youtube"){thumb=getProtocol()+"img.youtube.com/vi/"+video.id+"/default.jpg";img=thumb.replace(/\/default.jpg$/,"/hqdefault.jpg");dataFrame.thumbsReady=true}else if(video.type==="vimeo"){$.ajax({url:getProtocol()+"vimeo.com/api/v2/video/"+video.id+".json",dataType:"jsonp",success:function(json){dataFrame.thumbsReady=true;updateData(data,{img:json[0].thumbnail_large,thumb:json[0].thumbnail_small},dataFrame.i,fotorama)}})}else{dataFrame.thumbsReady=true}return{img:img,thumb:thumb}}function updateData(data,_dataFrame,i,fotorama){for(var _i=0,_l=data.length;_i<_l;_i++){var dataFrame=data[_i];if(dataFrame.i===i&&dataFrame.thumbsReady){var clear={videoReady:true};clear[STAGE_FRAME_KEY]=clear[NAV_THUMB_FRAME_KEY]=clear[NAV_DOT_FRAME_KEY]=false;fotorama.splice(_i,1,$.extend({},dataFrame,clear,_dataFrame));break}}}function getDataFromHtml($el){var data=[];function getDataFromImg($img,imgData,checkVideo){var $child=$img.children("img").eq(0),_imgHref=$img.attr("href"),_imgSrc=$img.attr("src"),_thumbSrc=$child.attr("src"),_video=imgData.video,video=checkVideo?findVideoId(_imgHref,_video===true):false;if(video){_imgHref=false}else{video=_video}getDimensions($img,$child,$.extend(imgData,{video:video,img:imgData.img||_imgHref||_imgSrc||_thumbSrc,thumb:imgData.thumb||_thumbSrc||_imgSrc||_imgHref}))}function getDimensions($img,$child,imgData){var separateThumbFLAG=imgData.thumb&&imgData.img!==imgData.thumb,width=numberFromMeasure(imgData.width||$img.attr("width")),height=numberFromMeasure(imgData.height||$img.attr("height"));$.extend(imgData,{width:width,height:height,thumbratio:getRatio(imgData.thumbratio||numberFromMeasure(imgData.thumbwidth||$child&&$child.attr("width")||separateThumbFLAG||width)/numberFromMeasure(imgData.thumbheight||$child&&$child.attr("height")||separateThumbFLAG||height))})}$el.children().each(function(){var $this=$(this),dataFrame=optionsToLowerCase($.extend($this.data(),{id:$this.attr("id")}));if($this.is("a, img")){getDataFromImg($this,dataFrame,true)}else if(!$this.is(":empty")){getDimensions($this,null,$.extend(dataFrame,{html:this,_html:$this.html()}))}else return;data.push(dataFrame)});return data}function isHidden(el){return el.offsetWidth===0&&el.offsetHeight===0}function isDetached(el){return!$.contains(document.documentElement,el)}function waitFor(test,fn,timeout,i){if(!waitFor.i){waitFor.i=1;waitFor.ii=[true]}i=i||waitFor.i;if(typeof waitFor.ii[i]==="undefined"){waitFor.ii[i]=true}if(test()){fn()}else{waitFor.ii[i]&&setTimeout(function(){waitFor.ii[i]&&waitFor(test,fn,timeout,i)},timeout||100)}return waitFor.i++}waitFor.stop=function(i){waitFor.ii[i]=false};function fit($el,measuresToFit){var elData=$el.data(),measures=elData.measures;if(measures&&(!elData.l||elData.l.W!==measures.width||elData.l.H!==measures.height||elData.l.r!==measures.ratio||elData.l.w!==measuresToFit.w||elData.l.h!==measuresToFit.h)){var height=minMaxLimit(measuresToFit.h,0,measures.height),width=height*measures.ratio;UTIL.setRatio($el,width,height);elData.l={W:measures.width,H:measures.height,r:measures.ratio,w:measuresToFit.w,h:measuresToFit.h}}return true}function setStyle($el,style){var el=$el[0];if(el.styleSheet){el.styleSheet.cssText=style}else{$el.html(style)}}function findShadowEdge(pos,min,max,dir){return min===max?false:dir==="vertical"?pos<=min?"top":pos>=max?"bottom":"top bottom":pos<=min?"left":pos>=max?"right":"left right"}function smartClick($el,fn,_options){_options=_options||{};$el.each(function(){var $this=$(this),thisData=$this.data(),startEvent;if(thisData.clickOn)return;thisData.clickOn=true;$.extend(touch($this,{onStart:function(e){startEvent=e;(_options.onStart||noop).call(this,e)},onMove:_options.onMove||noop,onTouchEnd:_options.onTouchEnd||noop,onEnd:function(result){if(result.moved)return;fn.call(this,startEvent)}}),{noMove:true})})}function div(classes,child){return'<div class="'+classes+'">'+(child||"")+"</div>"}function cls(className){return"."+className}function createVideoFrame(videoItem){var frame='<iframe src="'+videoItem.p+videoItem.type+".com/embed/"+videoItem.id+'" frameborder="0" allowfullscreen></iframe>';return frame}function shuffle(array){var l=array.length;while(l){var i=Math.floor(Math.random()*l--);var t=array[l];array[l]=array[i];array[i]=t}return array}function clone(array){return Object.prototype.toString.call(array)=="[object Array]"&&$.map(array,function(frame){return $.extend({},frame)})}function lockScroll($el,left,top){$el.scrollLeft(left||0).scrollTop(top||0)}function optionsToLowerCase(options){if(options){var opts={};$.each(options,function(key,value){opts[key.toLowerCase()]=value});return opts}}function getRatio(_ratio){if(!_ratio)return;var ratio=+_ratio;if(!isNaN(ratio)){return ratio}else{ratio=_ratio.split("/");return+ratio[0]/+ratio[1]||undefined}}function addEvent(el,e,fn,bool){if(!e)return;el.addEventListener?el.addEventListener(e,fn,!!bool):el.attachEvent("on"+e,fn)}function validateRestrictions(position,restriction){if(position>restriction.max){position=restriction.max}else{if(position<restriction.min){position=restriction.min}}return position}function validateSlidePos(opt,navShaftTouchTail,guessIndex,offsetNav,$guessNavFrame,$navWrap,dir){var position,size,wrapSize;if(dir==="horizontal"){size=opt.thumbwidth;wrapSize=$navWrap.width()}else{size=opt.thumbheight;wrapSize=$navWrap.height()}if((size+opt.margin)*(guessIndex+1)>=wrapSize-offsetNav){if(dir==="horizontal"){position=-$guessNavFrame.position().left}else{position=-$guessNavFrame.position().top}}else{if((size+opt.margin)*guessIndex<=Math.abs(offsetNav)){if(dir==="horizontal"){position=-$guessNavFrame.position().left+wrapSize-(size+opt.margin)}else{position=-$guessNavFrame.position().top+wrapSize-(size+opt.margin)}}else{position=offsetNav}}position=validateRestrictions(position,navShaftTouchTail);return position||0}function elIsDisabled(el){return!!el.getAttribute("disabled")}function disableAttr(FLAG,disable){if(disable){return{disabled:FLAG}}else{return{tabindex:FLAG*-1+"",disabled:FLAG}}}function addEnterUp(el,fn){addEvent(el,"keyup",function(e){elIsDisabled(el)||e.keyCode==13&&fn.call(el,e)})}function addFocus(el,fn){addEvent(el,"focus",el.onfocusin=function(e){fn.call(el,e)},true)}function stopEvent(e,stopPropagation){e.preventDefault?e.preventDefault():e.returnValue=false;stopPropagation&&e.stopPropagation&&e.stopPropagation()}function stubEvent($el,eventType){var isIOS=/ip(ad|hone|od)/i.test(window.navigator.userAgent);if(isIOS&&eventType==="touchend"){$el.on("touchend",function(e){$DOCUMENT.trigger("mouseup",e)})}$el.on(eventType,function(e){stopEvent(e,true);return false})}function getDirectionSign(forward){return forward?">":"<"}var UTIL=function(){function setRatioClass($el,wh,ht){var rateImg=wh/ht;if(rateImg<=1){$el.parent().removeClass(horizontalImageClass);$el.parent().addClass(verticalImageClass)}else{$el.parent().removeClass(verticalImageClass);$el.parent().addClass(horizontalImageClass)}}function setThumbAttr($frame,value,searchAttr){var attr=searchAttr;if(!$frame.attr(attr)&&$frame.attr(attr)!==undefined){$frame.attr(attr,value)}if($frame.find("["+attr+"]").length){$frame.find("["+attr+"]").each(function(){$(this).attr(attr,value)})}}function isExpectedCaption(frameItem,isExpected,undefined){var expected=false,frameExpected;frameItem.showCaption===undefined||frameItem.showCaption===true?frameExpected=true:frameExpected=false;if(!isExpected){return false}if(frameItem.caption&&frameExpected){expected=true}return expected}return{setRatio:setRatioClass,setThumbAttr:setThumbAttr,isExpectedCaption:isExpectedCaption}}(UTIL||{},jQuery);function slide($el,options){var elData=$el.data(),elPos=Math.round(options.pos),onEndFn=function(){if(elData&&elData.sliding){elData.sliding=false}(options.onEnd||noop)()};if(typeof options.overPos!=="undefined"&&options.overPos!==options.pos){elPos=options.overPos}var translate=$.extend(getTranslate(elPos,options.direction),options.width&&{width:options.width},options.height&&{height:options.height});if(elData&&elData.sliding){elData.sliding=true}if(CSS3){$el.css($.extend(getDuration(options.time),translate));if(options.time>10){afterTransition($el,"transform",onEndFn,options.time)}else{onEndFn()}}else{$el.stop().animate(translate,options.time,BEZIER,onEndFn)}}function fade($el1,$el2,$frames,options,fadeStack,chain){var chainedFLAG=typeof chain!=="undefined";if(!chainedFLAG){fadeStack.push(arguments);Array.prototype.push.call(arguments,fadeStack.length);if(fadeStack.length>1)return}$el1=$el1||$($el1);$el2=$el2||$($el2);var _$el1=$el1[0],_$el2=$el2[0],crossfadeFLAG=options.method==="crossfade",onEndFn=function(){if(!onEndFn.done){onEndFn.done=true;var args=(chainedFLAG||fadeStack.shift())&&fadeStack.shift();args&&fade.apply(this,args);(options.onEnd||noop)(!!args)}},time=options.time/(chain||1);$frames.removeClass(fadeRearClass+" "+fadeFrontClass);$el1.stop().addClass(fadeRearClass);$el2.stop().addClass(fadeFrontClass);crossfadeFLAG&&_$el2&&$el1.fadeTo(0,0);$el1.fadeTo(crossfadeFLAG?time:0,1,crossfadeFLAG&&onEndFn);$el2.fadeTo(time,0,onEndFn);_$el1&&crossfadeFLAG||_$el2||onEndFn()}var lastEvent,moveEventType,preventEvent,preventEventTimeout,dragDomEl;function extendEvent(e){var touch=(e.touches||[])[0]||e;e._x=touch.pageX||touch.originalEvent.pageX;e._y=touch.clientY||touch.originalEvent.clientY;e._now=$.now()}function touch($el,options){var el=$el[0],tail={},touchEnabledFLAG,startEvent,$target,controlTouch,touchFLAG,targetIsSelectFLAG,targetIsLinkFlag,tolerance,moved;function onStart(e){$target=$(e.target);tail.checked=targetIsSelectFLAG=targetIsLinkFlag=moved=false;if(touchEnabledFLAG||tail.flow||e.touches&&e.touches.length>1||e.which>1||lastEvent&&lastEvent.type!==e.type&&preventEvent||(targetIsSelectFLAG=options.select&&$target.is(options.select,el)))return targetIsSelectFLAG;touchFLAG=e.type==="touchstart";targetIsLinkFlag=$target.is("a, a *",el);controlTouch=tail.control;tolerance=tail.noMove||tail.noSwipe||controlTouch?16:!tail.snap?4:0;extendEvent(e);startEvent=lastEvent=e;moveEventType=e.type.replace(/down|start/,"move").replace(/Down/,"Move");(options.onStart||noop).call(el,e,{control:controlTouch,$target:$target});touchEnabledFLAG=tail.flow=true;if(!touchFLAG||tail.go)stopEvent(e)}function onMove(e){if(e.touches&&e.touches.length>1||MS_POINTER&&!e.isPrimary||moveEventType!==e.type||!touchEnabledFLAG){touchEnabledFLAG&&onEnd();(options.onTouchEnd||noop)();return}extendEvent(e);var xDiff=Math.abs(e._x-startEvent._x),yDiff=Math.abs(e._y-startEvent._y),xyDiff=xDiff-yDiff,xWin=(tail.go||tail.x||xyDiff>=0)&&!tail.noSwipe,yWin=xyDiff<0;if(touchFLAG&&!tail.checked){if(touchEnabledFLAG=xWin){stopEvent(e)}}else{stopEvent(e);if(movedEnough(xDiff,yDiff)){(options.onMove||noop).call(el,e,{touch:touchFLAG})}}if(!moved&&movedEnough(xDiff,yDiff)&&Math.sqrt(Math.pow(xDiff,2)+Math.pow(yDiff,2))>tolerance){moved=true}tail.checked=tail.checked||xWin||yWin}function movedEnough(xDiff,yDiff){return xDiff>yDiff&&xDiff>1.5}function onEnd(e){(options.onTouchEnd||noop)();var _touchEnabledFLAG=touchEnabledFLAG;tail.control=touchEnabledFLAG=false;if(_touchEnabledFLAG){tail.flow=false}if(!_touchEnabledFLAG||targetIsLinkFlag&&!tail.checked)return;e&&stopEvent(e);preventEvent=true;clearTimeout(preventEventTimeout);preventEventTimeout=setTimeout(function(){preventEvent=false},1e3);(options.onEnd||noop).call(el,{moved:moved,$target:$target,control:controlTouch,touch:touchFLAG,startEvent:startEvent,aborted:!e||e.type==="MSPointerCancel"})}function onOtherStart(){if(tail.flow)return;tail.flow=true}function onOtherEnd(){if(!tail.flow)return;tail.flow=false}if(MS_POINTER){addEvent(el,"MSPointerDown",onStart);addEvent(document,"MSPointerMove",onMove);addEvent(document,"MSPointerCancel",onEnd);addEvent(document,"MSPointerUp",onEnd)}else{addEvent(el,"touchstart",onStart);addEvent(el,"touchmove",onMove);addEvent(el,"touchend",onEnd);addEvent(document,"touchstart",onOtherStart);addEvent(document,"touchend",onOtherEnd);addEvent(document,"touchcancel",onOtherEnd);$WINDOW.on("scroll",onOtherEnd);$el.on("mousedown pointerdown",onStart);$DOCUMENT.on("mousemove pointermove",onMove).on("mouseup pointerup",onEnd)}if(Modernizr.touch){dragDomEl="a"}else{dragDomEl="div"}$el.on("click",dragDomEl,function(e){tail.checked&&stopEvent(e)});return tail}function moveOnTouch($el,options){var el=$el[0],elData=$el.data(),tail={},startCoo,coo,startElPos,moveElPos,edge,moveTrack,startTime,endTime,min,max,snap,dir,slowFLAG,controlFLAG,moved,tracked;function startTracking(e,noStop){tracked=true;startCoo=coo=dir==="vertical"?e._y:e._x;startTime=e._now;moveTrack=[[startTime,startCoo]];startElPos=moveElPos=tail.noMove||noStop?0:stop($el,(options.getPos||noop)());(options.onStart||noop).call(el,e)}function onStart(e,result){min=tail.min;max=tail.max;snap=tail.snap,dir=tail.direction||"horizontal",$el.navdir=dir;slowFLAG=e.altKey;tracked=moved=false;controlFLAG=result.control;if(!controlFLAG&&!elData.sliding){startTracking(e)}}function onMove(e,result){if(!tail.noSwipe){if(!tracked){startTracking(e)}coo=dir==="vertical"?e._y:e._x;moveTrack.push([e._now,coo]);moveElPos=startElPos-(startCoo-coo);edge=findShadowEdge(moveElPos,min,max,dir);if(moveElPos<=min){moveElPos=edgeResistance(moveElPos,min)}else if(moveElPos>=max){moveElPos=edgeResistance(moveElPos,max)}if(!tail.noMove){$el.css(getTranslate(moveElPos,dir));if(!moved){moved=true;result.touch||MS_POINTER||$el.addClass(grabbingClass)}(options.onMove||noop).call(el,e,{pos:moveElPos,edge:edge})}}}function onEnd(result){if(tail.noSwipe&&result.moved)return;if(!tracked){startTracking(result.startEvent,true)}result.touch||MS_POINTER||$el.removeClass(grabbingClass);endTime=$.now();var _backTimeIdeal=endTime-TOUCH_TIMEOUT,_backTime,_timeDiff,_timeDiffLast,backTime=null,backCoo,virtualPos,limitPos,newPos,overPos,time=TRANSITION_DURATION,speed,friction=options.friction;for(var _i=moveTrack.length-1;_i>=0;_i--){_backTime=moveTrack[_i][0];_timeDiff=Math.abs(_backTime-_backTimeIdeal);if(backTime===null||_timeDiff<_timeDiffLast){backTime=_backTime;backCoo=moveTrack[_i][1]}else if(backTime===_backTimeIdeal||_timeDiff>_timeDiffLast){break}_timeDiffLast=_timeDiff}newPos=minMaxLimit(moveElPos,min,max);var cooDiff=backCoo-coo,forwardFLAG=cooDiff>=0,timeDiff=endTime-backTime,longTouchFLAG=timeDiff>TOUCH_TIMEOUT,swipeFLAG=!longTouchFLAG&&moveElPos!==startElPos&&newPos===moveElPos;if(snap){newPos=minMaxLimit(Math[swipeFLAG?forwardFLAG?"floor":"ceil":"round"](moveElPos/snap)*snap,min,max);min=max=newPos}if(swipeFLAG&&(snap||newPos===moveElPos)){speed=-(cooDiff/timeDiff);time*=minMaxLimit(Math.abs(speed),options.timeLow,options.timeHigh);virtualPos=Math.round(moveElPos+speed*time/friction);if(!snap){newPos=virtualPos}if(!forwardFLAG&&virtualPos>max||forwardFLAG&&virtualPos<min){limitPos=forwardFLAG?min:max;overPos=virtualPos-limitPos;if(!snap){newPos=limitPos}overPos=minMaxLimit(newPos+overPos*.03,limitPos-50,limitPos+50);time=Math.abs((moveElPos-overPos)/(speed/friction))}}time*=slowFLAG?10:1;(options.onEnd||noop).call(el,$.extend(result,{moved:result.moved||longTouchFLAG&&snap,pos:moveElPos,newPos:newPos,overPos:overPos,time:time,dir:dir}))}tail=$.extend(touch(options.$wrap,$.extend({},options,{onStart:onStart,onMove:onMove,onEnd:onEnd})),tail);return tail}function wheel($el,options){var el=$el[0],lockFLAG,lastDirection,lastNow,tail={prevent:{}};addEvent(el,WHEEL,function(e){var yDelta=e.wheelDeltaY||-1*e.deltaY||0,xDelta=e.wheelDeltaX||-1*e.deltaX||0,xWin=Math.abs(xDelta)&&!Math.abs(yDelta),direction=getDirectionSign(xDelta<0),sameDirection=lastDirection===direction,now=$.now(),tooFast=now-lastNow<TOUCH_TIMEOUT;lastDirection=direction;lastNow=now;if(!xWin||!tail.ok||tail.prevent[direction]&&!lockFLAG){return}else{stopEvent(e,true);if(lockFLAG&&sameDirection&&tooFast){return}}if(options.shift){lockFLAG=true;clearTimeout(tail.t);tail.t=setTimeout(function(){lockFLAG=false},SCROLL_LOCK_TIMEOUT)}(options.onEnd||noop)(e,options.shift?direction:xDelta)});return tail}jQuery.Fotorama=function($fotorama,opts){$HTML=$("html");$BODY=$("body");var that=this,stamp=$.now(),stampClass=_fotoramaClass+stamp,fotorama=$fotorama[0],data,dataFrameCount=1,fotoramaData=$fotorama.data(),size,$style=$("<style></style>"),$anchor=$(div(hiddenClass)),$wrap=$fotorama.find(cls(wrapClass)),$stage=$wrap.find(cls(stageClass)),stage=$stage[0],$stageShaft=$fotorama.find(cls(stageShaftClass)),$stageFrame=$(),$arrPrev=$fotorama.find(cls(arrPrevClass)),$arrNext=$fotorama.find(cls(arrNextClass)),$arrs=$fotorama.find(cls(arrClass)),$navWrap=$fotorama.find(cls(navWrapClass)),$nav=$navWrap.find(cls(navClass)),$navShaft=$nav.find(cls(navShaftClass)),$navFrame,$navDotFrame=$(),$navThumbFrame=$(),stageShaftData=$stageShaft.data(),navShaftData=$navShaft.data(),$thumbBorder=$fotorama.find(cls(thumbBorderClass)),$thumbArrLeft=$fotorama.find(cls(thumbArrLeft)),$thumbArrRight=$fotorama.find(cls(thumbArrRight)),$fullscreenIcon=$fotorama.find(cls(fullscreenIconClass)),fullscreenIcon=$fullscreenIcon[0],$videoPlay=$(div(videoPlayClass)),$videoClose=$fotorama.find(cls(videoCloseClass)),videoClose=$videoClose[0],$spinner=$fotorama.find(cls(fotoramaSpinnerClass)),$videoPlaying,activeIndex=false,activeFrame,activeIndexes,repositionIndex,dirtyIndex,lastActiveIndex,prevIndex,nextIndex,nextAutoplayIndex,startIndex,o_loop,o_nav,o_navThumbs,o_navTop,o_allowFullScreen,o_nativeFullScreen,o_fade,o_thumbSide,o_thumbSide2,o_transitionDuration,o_transition,o_shadows,o_rtl,o_keyboard,lastOptions={},measures={},measuresSetFLAG,stageShaftTouchTail={},stageWheelTail={},navShaftTouchTail={},navWheelTail={},scrollTop,scrollLeft,showedFLAG,pausedAutoplayFLAG,stoppedAutoplayFLAG,toDeactivate={},toDetach={},measuresStash,touchedFLAG,hoverFLAG,navFrameKey,stageLeft=0,fadeStack=[];$wrap[STAGE_FRAME_KEY]=$('<div class="'+stageFrameClass+'"></div>');$wrap[NAV_THUMB_FRAME_KEY]=$($.Fotorama.jst.thumb());$wrap[NAV_DOT_FRAME_KEY]=$($.Fotorama.jst.dots());toDeactivate[STAGE_FRAME_KEY]=[];toDeactivate[NAV_THUMB_FRAME_KEY]=[];toDeactivate[NAV_DOT_FRAME_KEY]=[];toDetach[STAGE_FRAME_KEY]={};$wrap.addClass(CSS3?wrapCss3Class:wrapCss2Class);fotoramaData.fotorama=this;function checkForVideo(){$.each(data,function(i,dataFrame){if(!dataFrame.i){dataFrame.i=dataFrameCount++;var video=findVideoId(dataFrame.video,true);if(video){var thumbs={};dataFrame.video=video;if(!dataFrame.img&&!dataFrame.thumb){thumbs=getVideoThumbs(dataFrame,data,that)}else{dataFrame.thumbsReady=true}updateData(data,{img:thumbs.img,thumb:thumbs.thumb},dataFrame.i,that)}}})}function allowKey(key){return o_keyboard[key]}function setStagePosition(){if($stage!==undefined){if(opts.navdir=="vertical"){var padding=opts.thumbwidth+opts.thumbmargin;$stage.css("left",padding);$arrNext.css("right",padding);$fullscreenIcon.css("right",padding);$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width",$wrap.width()-padding)}else{$stage.css("left","");$arrNext.css("right","");$fullscreenIcon.css("right","");$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width","")}}}function bindGlobalEvents(FLAG){var keydownCommon="keydown."+_fotoramaClass,localStamp=_fotoramaClass+stamp,keydownLocal="keydown."+localStamp,keyupLocal="keyup."+localStamp,resizeLocal="resize."+localStamp+" "+"orientationchange."+localStamp,showParams;if(FLAG){$DOCUMENT.on(keydownLocal,function(e){var catched,index;if($videoPlaying&&e.keyCode===27){catched=true;unloadVideo($videoPlaying,true,true)}else if(that.fullScreen||opts.keyboard&&!that.index){if(e.keyCode===27){catched=true;that.cancelFullScreen()}else if(e.shiftKey&&e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===37&&allowKey("left")||e.keyCode===38&&allowKey("up")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index="<"}else if(e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===39&&allowKey("right")||e.keyCode===40&&allowKey("down")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index=">"}else if(e.keyCode===36&&allowKey("home")){that.longPress.progress();index="<<"}else if(e.keyCode===35&&allowKey("end")){that.longPress.progress();index=">>"}}(catched||index)&&stopEvent(e);showParams={index:index,slow:e.altKey,user:true};index&&(that.longPress.inProgress?that.showWhileLongPress(showParams):that.show(showParams))});if(FLAG){$DOCUMENT.on(keyupLocal,function(e){if(that.longPress.inProgress){that.showEndLongPress({user:true})}that.longPress.reset()})}if(!that.index){$DOCUMENT.off(keydownCommon).on(keydownCommon,"textarea, input, select",function(e){!$BODY.hasClass(_fullscreenClass)&&e.stopPropagation()})}$WINDOW.on(resizeLocal,that.resize)}else{$DOCUMENT.off(keydownLocal);$WINDOW.off(resizeLocal)}}function appendElements(FLAG){if(FLAG===appendElements.f)return;if(FLAG){$fotorama.addClass(_fotoramaClass+" "+stampClass).before($anchor).before($style);addInstance(that)}else{$anchor.detach();$style.detach();$fotorama.html(fotoramaData.urtext).removeClass(stampClass);hideInstance(that)}bindGlobalEvents(FLAG);appendElements.f=FLAG}function setData(){data=that.data=data||clone(opts.data)||getDataFromHtml($fotorama);size=that.size=data.length;ready.ok&&opts.shuffle&&shuffle(data);checkForVideo();activeIndex=limitIndex(activeIndex);size&&appendElements(true)}function stageNoMove(){var _noMove=size<2||$videoPlaying;stageShaftTouchTail.noMove=_noMove||o_fade;stageShaftTouchTail.noSwipe=_noMove||!opts.swipe;!o_transition&&$stageShaft.toggleClass(grabClass,!opts.click&&!stageShaftTouchTail.noMove&&!stageShaftTouchTail.noSwipe);MS_POINTER&&$wrap.toggleClass(wrapPanYClass,!stageShaftTouchTail.noSwipe)}function setAutoplayInterval(interval){if(interval===true)interval="";opts.autoplay=Math.max(+interval||AUTOPLAY_INTERVAL,o_transitionDuration*1.5)}function updateThumbArrow(opt){if(opt.navarrows&&opt.nav==="thumbs"){$thumbArrLeft.show();$thumbArrRight.show()}else{$thumbArrLeft.hide();$thumbArrRight.hide()}}function getThumbsInSlide($el,opts){return Math.floor($wrap.width()/(opts.thumbwidth+opts.thumbmargin))}function setOptions(){if(!opts.nav||opts.nav==="dots"){opts.navdir="horizontal"}that.options=opts=optionsToLowerCase(opts);thumbsPerSlide=getThumbsInSlide($wrap,opts);o_fade=opts.transition==="crossfade"||opts.transition==="dissolve";o_loop=opts.loop&&(size>2||o_fade&&(!o_transition||o_transition!=="slide"));o_transitionDuration=+opts.transitionduration||TRANSITION_DURATION;o_rtl=opts.direction==="rtl";o_keyboard=$.extend({},opts.keyboard&&KEYBOARD_OPTIONS,opts.keyboard);updateThumbArrow(opts);var classes={add:[],remove:[]};function addOrRemoveClass(FLAG,value){classes[FLAG?"add":"remove"].push(value)}if(size>1){o_nav=opts.nav;o_navTop=opts.navposition==="top";classes.remove.push(selectClass);$arrs.toggle(opts.arrows)}else{o_nav=false;$arrs.hide()}arrsUpdate();stageWheelUpdate();thumbArrUpdate();if(opts.autoplay)setAutoplayInterval(opts.autoplay);o_thumbSide=numberFromMeasure(opts.thumbwidth)||THUMB_SIZE;o_thumbSide2=numberFromMeasure(opts.thumbheight)||THUMB_SIZE;stageWheelTail.ok=navWheelTail.ok=opts.trackpad&&!SLOW;stageNoMove();extendMeasures(opts,[measures]);o_navThumbs=o_nav==="thumbs";if($navWrap.filter(":hidden")&&!!o_nav){$navWrap.show()}if(o_navThumbs){frameDraw(size,"navThumb");$navFrame=$navThumbFrame;navFrameKey=NAV_THUMB_FRAME_KEY;setStyle($style,$.Fotorama.jst.style({w:o_thumbSide,h:o_thumbSide2,b:opts.thumbborderwidth,m:opts.thumbmargin,s:stamp,q:!COMPAT}));$nav.addClass(navThumbsClass).removeClass(navDotsClass)}else if(o_nav==="dots"){frameDraw(size,"navDot");$navFrame=$navDotFrame;navFrameKey=NAV_DOT_FRAME_KEY;$nav.addClass(navDotsClass).removeClass(navThumbsClass)}else{$navWrap.hide();o_nav=false;$nav.removeClass(navThumbsClass+" "+navDotsClass)}if(o_nav){if(o_navTop){$navWrap.insertBefore($stage)}else{$navWrap.insertAfter($stage)}frameAppend.nav=false;frameAppend($navFrame,$navShaft,"nav")}o_allowFullScreen=opts.allowfullscreen;if(o_allowFullScreen){$fullscreenIcon.prependTo($stage);o_nativeFullScreen=FULLSCREEN&&o_allowFullScreen==="native";stubEvent($fullscreenIcon,"touchend")}else{$fullscreenIcon.detach();o_nativeFullScreen=false}addOrRemoveClass(o_fade,wrapFadeClass);addOrRemoveClass(!o_fade,wrapSlideClass);addOrRemoveClass(!opts.captions,wrapNoCaptionsClass);addOrRemoveClass(o_rtl,wrapRtlClass);addOrRemoveClass(opts.arrows,wrapToggleArrowsClass);o_shadows=opts.shadows&&!SLOW;addOrRemoveClass(!o_shadows,wrapNoShadowsClass);$wrap.addClass(classes.add.join(" ")).removeClass(classes.remove.join(" "));lastOptions=$.extend({},opts);setStagePosition()}function normalizeIndex(index){return index<0?(size+index%size)%size:index>=size?index%size:index}function limitIndex(index){return minMaxLimit(index,0,size-1)}function edgeIndex(index){return o_loop?normalizeIndex(index):limitIndex(index)}function getPrevIndex(index){return index>0||o_loop?index-1:false}function getNextIndex(index){return index<size-1||o_loop?index+1:false}function setStageShaftMinmaxAndSnap(){stageShaftTouchTail.min=o_loop?-Infinity:-getPosByIndex(size-1,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.max=o_loop?Infinity:-getPosByIndex(0,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.snap=measures.w+opts.margin}function setNavShaftMinMax(){var isVerticalDir=opts.navdir==="vertical";var param=isVerticalDir?$navShaft.height():$navShaft.width();var mainParam=isVerticalDir?measures.h:measures.nw;navShaftTouchTail.min=Math.min(0,mainParam-param);navShaftTouchTail.max=0;navShaftTouchTail.direction=opts.navdir;$navShaft.toggleClass(grabClass,!(navShaftTouchTail.noMove=navShaftTouchTail.min===navShaftTouchTail.max))}function eachIndex(indexes,type,fn){if(typeof indexes==="number"){indexes=new Array(indexes);var rangeFLAG=true}return $.each(indexes,function(i,index){if(rangeFLAG)index=i;if(typeof index==="number"){var dataFrame=data[normalizeIndex(index)];if(dataFrame){var key="$"+type+"Frame",$frame=dataFrame[key];fn.call(this,i,index,dataFrame,$frame,key,$frame&&$frame.data())}}})}function setMeasures(width,height,ratio,index){if(!measuresSetFLAG||measuresSetFLAG==="*"&&index===startIndex){width=measureIsValid(opts.width)||measureIsValid(width)||WIDTH;height=measureIsValid(opts.height)||measureIsValid(height)||HEIGHT;that.resize({width:width,ratio:opts.ratio||ratio||width/height},0,index!==startIndex&&"*")}}function loadImg(indexes,type,specialMeasures,again){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var fullFLAG=that.fullScreen&&!frameData.$full&&type==="stage";if(frameData.$img&&!again&&!fullFLAG)return;var img=new Image,$img=$(img),imgData=$img.data();frameData[fullFLAG?"$full":"$img"]=$img;var srcKey=type==="stage"?fullFLAG?"full":"img":"thumb",src=dataFrame[srcKey],dummy=fullFLAG?dataFrame["img"]:dataFrame[type==="stage"?"thumb":"img"];if(type==="navThumb")$frame=frameData.$wrap;function triggerTriggerEvent(event){var _index=normalizeIndex(index);triggerEvent(event,{index:_index,src:src,frame:data[_index]})}function error(){$img.remove();$.Fotorama.cache[src]="error";if((!dataFrame.html||type!=="stage")&&dummy&&dummy!==src){dataFrame[srcKey]=src=dummy;frameData.$full=null;loadImg([index],type,specialMeasures,true)}else{if(src&&!dataFrame.html&&!fullFLAG){$frame.trigger("f:error").removeClass(loadingClass).addClass(errorClass);triggerTriggerEvent("error")}else if(type==="stage"){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass);triggerTriggerEvent("load");setMeasures()}frameData.state="error";if(size>1&&data[index]===dataFrame&&!dataFrame.html&&!dataFrame.deleted&&!dataFrame.video&&!fullFLAG){dataFrame.deleted=true;that.splice(index,1)}}}function loaded(){$.Fotorama.measures[src]=imgData.measures=$.Fotorama.measures[src]||{width:img.width,height:img.height,ratio:img.width/img.height};setMeasures(imgData.measures.width,imgData.measures.height,imgData.measures.ratio,index);$img.off("load error").addClass(""+(fullFLAG?imgFullClass:imgClass)).attr("aria-hidden","false").prependTo($frame);if($frame.hasClass(stageFrameClass)&&!$frame.hasClass(videoContainerClass)){$frame.attr("href",$img.attr("src"))}fit($img,($.isFunction(specialMeasures)?specialMeasures():specialMeasures)||measures);$.Fotorama.cache[src]=frameData.state="loaded";setTimeout(function(){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass+" "+(fullFLAG?loadedFullClass:loadedImgClass));if(type==="stage"){triggerTriggerEvent("load")}else if(dataFrame.thumbratio===AUTO||!dataFrame.thumbratio&&opts.thumbratio===AUTO){dataFrame.thumbratio=imgData.measures.ratio;reset()}},0)}if(!src){error();return}function waitAndLoad(){var _i=10;waitFor(function(){return!touchedFLAG||!_i--&&!SLOW},function(){loaded()})}if(!$.Fotorama.cache[src]){$.Fotorama.cache[src]="*";$img.on("load",waitAndLoad).on("error",error)}else{(function justWait(){if($.Fotorama.cache[src]==="error"){error()}else if($.Fotorama.cache[src]==="loaded"){setTimeout(waitAndLoad,0)}else{setTimeout(justWait,100)}})()}frameData.state="";img.src=src;if(frameData.data.caption){img.alt=frameData.data.caption||""}if(frameData.data.full){$(img).data("original",frameData.data.full)}if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$(img).attr("aria-labelledby",dataFrame.labelledby)}})}function updateFotoramaState(){var $frame=activeFrame[STAGE_FRAME_KEY];if($frame&&!$frame.data().state){$spinner.addClass(spinnerShowClass);$frame.on("f:load f:error",function(){$frame.off("f:load f:error");$spinner.removeClass(spinnerShowClass)})}}function addNavFrameEvents(frame){addEnterUp(frame,onNavFrameClick);addFocus(frame,function(){setTimeout(function(){lockScroll($nav)},0);slideNavShaft({time:o_transitionDuration,guessIndex:$(this).data().eq,minMax:navShaftTouchTail})})}function frameDraw(indexes,type){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if($frame)return;$frame=dataFrame[key]=$wrap[key].clone();frameData=$frame.data();frameData.data=dataFrame;var frame=$frame[0],labelledbyValue="labelledby"+$.now();if(type==="stage"){if(dataFrame.html){$('<div class="'+htmlClass+'"></div>').append(dataFrame._html?$(dataFrame.html).removeAttr("id").html(dataFrame._html):dataFrame.html).appendTo($frame)}if(dataFrame.id){labelledbyValue=dataFrame.id||labelledbyValue}dataFrame.labelledby=labelledbyValue;if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$($.Fotorama.jst.frameCaption({caption:dataFrame.caption,labelledby:labelledbyValue})).appendTo($frame)}dataFrame.video&&$frame.addClass(stageFrameVideoClass).append($videoPlay.clone());addFocus(frame,function(){setTimeout(function(){lockScroll($stage)},0);clickToShow({index:frameData.eq,user:true})});$stageFrame=$stageFrame.add($frame)}else if(type==="navDot"){addNavFrameEvents(frame);$navDotFrame=$navDotFrame.add($frame)}else if(type==="navThumb"){addNavFrameEvents(frame);frameData.$wrap=$frame.children(":first");$navThumbFrame=$navThumbFrame.add($frame);if(dataFrame.video){frameData.$wrap.append($videoPlay.clone())}}})}function callFit($img,measuresToFit){return $img&&$img.length&&fit($img,measuresToFit)}function stageFramePosition(indexes){eachIndex(indexes,"stage",function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var normalizedIndex=normalizeIndex(index);frameData.eq=normalizedIndex;toDetach[STAGE_FRAME_KEY][normalizedIndex]=$frame.css($.extend({left:o_fade?0:getPosByIndex(index,measures.w,opts.margin,repositionIndex)},o_fade&&getDuration(0)));if(isDetached($frame[0])){$frame.appendTo($stageShaft);unloadVideo(dataFrame.$video)}callFit(frameData.$img,measures);callFit(frameData.$full,measures);if($frame.hasClass(stageFrameClass)&&!($frame.attr("aria-hidden")==="false"&&$frame.hasClass(activeClass))){$frame.attr("aria-hidden","true")}})}function thumbsDraw(pos,loadFLAG){var leftLimit,rightLimit,exceedLimit;if(o_nav!=="thumbs"||isNaN(pos))return;leftLimit=-pos;rightLimit=-pos+measures.nw;if(opts.navdir==="vertical"){pos=pos-opts.thumbheight;rightLimit=-pos+measures.h}$navThumbFrame.each(function(){var $this=$(this),thisData=$this.data(),eq=thisData.eq,getSpecialMeasures=function(){return{h:o_thumbSide2,w:thisData.w}},specialMeasures=getSpecialMeasures(),exceedLimit=opts.navdir==="vertical"?thisData.t>rightLimit:thisData.l>rightLimit;specialMeasures.w=thisData.w;if(thisData.l+thisData.w<leftLimit||exceedLimit||callFit(thisData.$img,specialMeasures))return;loadFLAG&&loadImg([eq],"navThumb",getSpecialMeasures)})}function frameAppend($frames,$shaft,type){if(!frameAppend[type]){var thumbsFLAG=type==="nav"&&o_navThumbs,left=0,top=0;$shaft.append($frames.filter(function(){var actual,$this=$(this),frameData=$this.data();for(var _i=0,_l=data.length;_i<_l;_i++){if(frameData.data===data[_i]){actual=true;frameData.eq=_i;break}}return actual||$this.remove()&&false}).sort(function(a,b){return $(a).data().eq-$(b).data().eq}).each(function(){var $this=$(this),frameData=$this.data();UTIL.setThumbAttr($this,frameData.data.caption,"aria-label")}).each(function(){if(!thumbsFLAG)return;var $this=$(this),frameData=$this.data(),thumbwidth=Math.round(o_thumbSide2*frameData.data.thumbratio)||o_thumbSide,thumbheight=Math.round(o_thumbSide/frameData.data.thumbratio)||o_thumbSide2;frameData.t=top;frameData.h=thumbheight;frameData.l=left;frameData.w=thumbwidth;$this.css({width:thumbwidth});top+=thumbheight+opts.thumbmargin;left+=thumbwidth+opts.thumbmargin}));frameAppend[type]=true}}function getDirection(x){return x-stageLeft>measures.w/3}function disableDirrection(i){return!o_loop&&(!(activeIndex+i)||!(activeIndex-size+i))&&!$videoPlaying}function arrsUpdate(){var disablePrev=disableDirrection(0),disableNext=disableDirrection(1);$arrPrev.toggleClass(arrDisabledClass,disablePrev).attr(disableAttr(disablePrev,false));$arrNext.toggleClass(arrDisabledClass,disableNext).attr(disableAttr(disableNext,false))}function thumbArrUpdate(){var isLeftDisable=false,isRightDisable=false;if(opts.navtype==="thumbs"&&!opts.loop){activeIndex==0?isLeftDisable=true:isLeftDisable=false;activeIndex==opts.data.length-1?isRightDisable=true:isRightDisable=false}if(opts.navtype==="slides"){var pos=readPosition($navShaft,opts.navdir);pos>=navShaftTouchTail.max?isLeftDisable=true:isLeftDisable=false;pos<=navShaftTouchTail.min?isRightDisable=true:isRightDisable=false}$thumbArrLeft.toggleClass(arrDisabledClass,isLeftDisable).attr(disableAttr(isLeftDisable,true));$thumbArrRight.toggleClass(arrDisabledClass,isRightDisable).attr(disableAttr(isRightDisable,true))}function stageWheelUpdate(){if(stageWheelTail.ok){stageWheelTail.prevent={"<":disableDirrection(0),">":disableDirrection(1)}}}function getNavFrameBounds($navFrame){var navFrameData=$navFrame.data(),left,top,width,height;if(o_navThumbs){left=navFrameData.l;top=navFrameData.t;width=navFrameData.w;height=navFrameData.h}else{left=$navFrame.position().left;width=$navFrame.width()}var horizontalBounds={c:left+width/2,min:-left+opts.thumbmargin*10,max:-left+measures.w-width-opts.thumbmargin*10};var verticalBounds={c:top+height/2,min:-top+opts.thumbmargin*10,max:-top+measures.h-height-opts.thumbmargin*10};return opts.navdir==="vertical"?verticalBounds:horizontalBounds}function slideThumbBorder(time){var navFrameData=activeFrame[navFrameKey].data();slide($thumbBorder,{time:time*1.2,pos:opts.navdir==="vertical"?navFrameData.t:navFrameData.l,width:navFrameData.w,height:navFrameData.h,direction:opts.navdir})}function slideNavShaft(options){var $guessNavFrame=data[options.guessIndex][navFrameKey],typeOfAnimation=opts.navtype;var overflowFLAG,time,minMax,boundTop,boundLeft,l,pos,x;if($guessNavFrame){if(typeOfAnimation==="thumbs"){overflowFLAG=navShaftTouchTail.min!==navShaftTouchTail.max;minMax=options.minMax||overflowFLAG&&getNavFrameBounds(activeFrame[navFrameKey]);boundTop=overflowFLAG&&(options.keep&&slideNavShaft.t?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));boundLeft=overflowFLAG&&(options.keep&&slideNavShaft.l?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));l=opts.navdir==="vertical"?boundTop:boundLeft;pos=overflowFLAG&&minMaxLimit(l,navShaftTouchTail.min,navShaftTouchTail.max)||0;time=options.time*1.1;slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));slideNavShaft.l=l}else{x=readPosition($navShaft,opts.navdir);time=options.time*1.11;pos=validateSlidePos(opts,navShaftTouchTail,options.guessIndex,x,$guessNavFrame,$navWrap,opts.navdir);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir))}}}function navUpdate(){deactivateFrames(navFrameKey);toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr("data-active",true))}function deactivateFrames(key){var _toDeactivate=toDeactivate[key];while(_toDeactivate.length){_toDeactivate.shift().removeClass(activeClass).attr("data-active",false)}}function detachFrames(key){var _toDetach=toDetach[key];$.each(activeIndexes,function(i,index){delete _toDetach[normalizeIndex(index)]});$.each(_toDetach,function(index,$frame){delete _toDetach[index];$frame.detach()})}function stageShaftReposition(skipOnEnd){repositionIndex=dirtyIndex=activeIndex;var $frame=activeFrame[STAGE_FRAME_KEY];if($frame){deactivateFrames(STAGE_FRAME_KEY);toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr("data-active",true));if($frame.hasClass(stageFrameClass)){$frame.attr("aria-hidden","false")}skipOnEnd||that.showStage.onEnd(true);stop($stageShaft,0,true);detachFrames(STAGE_FRAME_KEY);stageFramePosition(activeIndexes);setStageShaftMinmaxAndSnap();setNavShaftMinMax();addEnterUp($stageShaft[0],function(){if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen();$fullscreenIcon.focus()}})}}function extendMeasures(options,measuresArray){if(!options)return;$.each(measuresArray,function(i,measures){if(!measures)return;$.extend(measures,{width:options.width||measures.width,height:options.height,minwidth:options.minwidth,maxwidth:options.maxwidth,minheight:options.minheight,maxheight:options.maxheight,ratio:getRatio(options.ratio)})})}function triggerEvent(event,extra){$fotorama.trigger(_fotoramaClass+":"+event,[that,extra])}function onTouchStart(){clearTimeout(onTouchEnd.t);touchedFLAG=1;if(opts.stopautoplayontouch){that.stopAutoplay()}else{pausedAutoplayFLAG=true}}function onTouchEnd(){if(!touchedFLAG)return;if(!opts.stopautoplayontouch){releaseAutoplay();changeAutoplay()}onTouchEnd.t=setTimeout(function(){touchedFLAG=0},TRANSITION_DURATION+TOUCH_TIMEOUT)}function releaseAutoplay(){pausedAutoplayFLAG=!!($videoPlaying||stoppedAutoplayFLAG)}function changeAutoplay(){clearTimeout(changeAutoplay.t);waitFor.stop(changeAutoplay.w);if(!opts.autoplay||pausedAutoplayFLAG){if(that.autoplay){that.autoplay=false;triggerEvent("stopautoplay")}return}if(!that.autoplay){that.autoplay=true;triggerEvent("startautoplay")}var _activeIndex=activeIndex;var frameData=activeFrame[STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return frameData.state||_activeIndex!==activeIndex},function(){changeAutoplay.t=setTimeout(function(){if(pausedAutoplayFLAG||_activeIndex!==activeIndex)return;var _nextAutoplayIndex=nextAutoplayIndex,nextFrameData=data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return nextFrameData.state||_nextAutoplayIndex!==nextAutoplayIndex},function(){if(pausedAutoplayFLAG||_nextAutoplayIndex!==nextAutoplayIndex)return;that.show(o_loop?getDirectionSign(!o_rtl):nextAutoplayIndex)})},opts.autoplay)})}that.startAutoplay=function(interval){if(that.autoplay)return this;pausedAutoplayFLAG=stoppedAutoplayFLAG=false;setAutoplayInterval(interval||opts.autoplay);changeAutoplay();return this};that.stopAutoplay=function(){if(that.autoplay){pausedAutoplayFLAG=stoppedAutoplayFLAG=true;changeAutoplay()}return this};that.showSlide=function(slideDir){var currentPosition=readPosition($navShaft,opts.navdir),pos,time=500*1.1,size=opts.navdir==="horizontal"?opts.thumbwidth:opts.thumbheight,onEnd=function(){thumbArrUpdate()};if(slideDir==="next"){pos=currentPosition-(size+opts.margin)*thumbsPerSlide}if(slideDir==="prev"){pos=currentPosition+(size+opts.margin)*thumbsPerSlide}pos=validateRestrictions(pos,navShaftTouchTail);thumbsDraw(pos,true);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:onEnd})};that.showWhileLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showNav(silent,options,time);return this};that.showEndLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;return this};function calcActiveIndex(options){var index;if(typeof options!=="object"){index=options;options={}}else{index=options.index}index=index===">"?dirtyIndex+1:index==="<"?dirtyIndex-1:index==="<<"?0:index===">>"?size-1:index;index=isNaN(index)?undefined:index;index=typeof index==="undefined"?activeIndex||0:index;return index}function calcGlobalIndexes(index){that.activeIndex=activeIndex=edgeIndex(index);prevIndex=getPrevIndex(activeIndex);nextIndex=getNextIndex(activeIndex);nextAutoplayIndex=normalizeIndex(activeIndex+(o_rtl?-1:1));activeIndexes=[activeIndex,prevIndex,nextIndex];dirtyIndex=o_loop?index:activeIndex}function calcTime(options){var diffIndex=Math.abs(lastActiveIndex-dirtyIndex),time=getNumber(options.time,function(){return Math.min(o_transitionDuration*(1+(diffIndex-1)/12),o_transitionDuration*2)});if(options.slow){time*=10}return time}that.showStage=function(silent,options,time){unloadVideo($videoPlaying,activeFrame.i!==data[normalizeIndex(repositionIndex)].i);frameDraw(activeIndexes,"stage");stageFramePosition(SLOW?[dirtyIndex]:[dirtyIndex,getPrevIndex(dirtyIndex),getNextIndex(dirtyIndex)]);updateTouchTails("go",true);silent||triggerEvent("show",{user:options.user,time:time});pausedAutoplayFLAG=true;var overPos=options.overPos;var onEnd=that.showStage.onEnd=function(skipReposition){if(onEnd.ok)return;onEnd.ok=true;skipReposition||stageShaftReposition(true);if(!silent){triggerEvent("showend",{user:options.user})}if(!skipReposition&&o_transition&&o_transition!==opts.transition){that.setOptions({transition:o_transition});o_transition=false;return}updateFotoramaState();loadImg(activeIndexes,"stage");updateTouchTails("go",false);stageWheelUpdate();stageCursor();releaseAutoplay();changeAutoplay();if(that.fullScreen){activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",false);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",true)}else{activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",true);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",false)}};if(!o_fade){slide($stageShaft,{pos:-getPosByIndex(dirtyIndex,measures.w,opts.margin,repositionIndex),overPos:overPos,time:time,onEnd:onEnd})}else{var $activeFrame=activeFrame[STAGE_FRAME_KEY],$prevActiveFrame=data[lastActiveIndex]&&activeIndex!==lastActiveIndex?data[lastActiveIndex][STAGE_FRAME_KEY]:null;fade($activeFrame,$prevActiveFrame,$stageFrame,{time:time,method:opts.transition,onEnd:onEnd},fadeStack)}arrsUpdate()};that.showNav=function(silent,options,time){thumbArrUpdate();if(o_nav){navUpdate();var guessIndex=limitIndex(activeIndex+minMaxLimit(dirtyIndex-lastActiveIndex,-1,1));slideNavShaft({time:time,coo:guessIndex!==activeIndex&&options.coo,guessIndex:typeof options.coo!=="undefined"?guessIndex:activeIndex,keep:silent});if(o_navThumbs)slideThumbBorder(time)}};that.show=function(options){that.longPress.singlePressInProgress=true;var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options);var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);that.showNav(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;that.longPress.singlePressInProgress=false;return this};that.requestFullScreen=function(){if(o_allowFullScreen&&!that.fullScreen){var isVideo=$((that.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(isVideo){return}scrollTop=$WINDOW.scrollTop();scrollLeft=$WINDOW.scrollLeft();lockScroll($WINDOW);updateTouchTails("x",true);measuresStash=$.extend({},measures);$fotorama.addClass(fullscreenClass).appendTo($BODY.addClass(_fullscreenClass));$HTML.addClass(_fullscreenClass);unloadVideo($videoPlaying,true,true);that.fullScreen=true;if(o_nativeFullScreen){fullScreenApi.request(fotorama)}that.resize();loadImg(activeIndexes,"stage");updateFotoramaState();triggerEvent("fullscreenenter");if(!("ontouchstart"in window)){$fullscreenIcon.focus()}}return this};function cancelFullScreen(){if(that.fullScreen){that.fullScreen=false;if(FULLSCREEN){fullScreenApi.cancel(fotorama)}$BODY.removeClass(_fullscreenClass);$HTML.removeClass(_fullscreenClass);$fotorama.removeClass(fullscreenClass).insertAfter($anchor);measures=$.extend({},measuresStash);unloadVideo($videoPlaying,true,true);updateTouchTails("x",false);that.resize();loadImg(activeIndexes,"stage");lockScroll($WINDOW,scrollLeft,scrollTop);triggerEvent("fullscreenexit")}}that.cancelFullScreen=function(){if(o_nativeFullScreen&&fullScreenApi.is()){fullScreenApi.cancel(document)}else{cancelFullScreen()}return this};that.toggleFullScreen=function(){return that[(that.fullScreen?"cancel":"request")+"FullScreen"]()};that.resize=function(options){if(!data)return this;var time=arguments[1]||0,setFLAG=arguments[2];thumbsPerSlide=getThumbsInSlide($wrap,opts);extendMeasures(!that.fullScreen?optionsToLowerCase(options):{width:$(window).width(),maxwidth:null,minwidth:null,height:$(window).height(),maxheight:null,minheight:null},[measures,setFLAG||that.fullScreen||opts]);var width=measures.width,height=measures.height,ratio=measures.ratio,windowHeight=$WINDOW.height()-(o_nav?$nav.height():0);if(measureIsValid(width)){$wrap.css({width:""});$wrap.css({height:""});$stage.css({width:""});$stage.css({height:""});$stageShaft.css({width:""});$stageShaft.css({height:""});$nav.css({width:""});$nav.css({height:""});$wrap.css({minWidth:measures.minwidth||0,maxWidth:measures.maxwidth||MAX_WIDTH});if(o_nav==="dots"){$navWrap.hide()}width=measures.W=measures.w=$wrap.width();measures.nw=o_nav&&numberFromWhatever(opts.navwidth,width)||width;$stageShaft.css({width:measures.w,marginLeft:(measures.W-measures.w)/2});height=numberFromWhatever(height,windowHeight);height=height||ratio&&width/ratio;if(height){width=Math.round(width);height=measures.h=Math.round(minMaxLimit(height,numberFromWhatever(measures.minheight,windowHeight),numberFromWhatever(measures.maxheight,windowHeight)));$stage.css({width:width,height:height});if(opts.navdir==="vertical"&&!that.fullscreen){$nav.width(opts.thumbwidth+opts.thumbmargin*2)}if(opts.navdir==="horizontal"&&!that.fullscreen){$nav.height(opts.thumbheight+opts.thumbmargin*2)}if(o_nav==="dots"){$nav.width(width).height("auto");$navWrap.show()}if(opts.navdir==="vertical"&&that.fullScreen){$stage.css("height",$WINDOW.height())}if(opts.navdir==="horizontal"&&that.fullScreen){$stage.css("height",$WINDOW.height()-$nav.height())}if(o_nav){switch(opts.navdir){case"vertical":$navWrap.removeClass(navShafthorizontalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShaftVerticalClass);$nav.stop().animate({height:measures.h,width:opts.thumbwidth},time);break;case"list":$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShafthorizontalClass);$navWrap.addClass(navShaftListClass);break;default:$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShafthorizontalClass);$nav.stop().animate({width:measures.nw},time);break}stageShaftReposition();slideNavShaft({guessIndex:activeIndex,time:time,keep:true});if(o_navThumbs&&frameAppend.nav)slideThumbBorder(time)}measuresSetFLAG=setFLAG||true;ready.ok=true;ready()}}stageLeft=$stage.offset().left;setStagePosition();return this};that.setOptions=function(options){$.extend(opts,options);reset();return this};that.shuffle=function(){data&&shuffle(data)&&reset();return this};function setShadow($el,edge){if(o_shadows){$el.removeClass(shadowsLeftClass+" "+shadowsRightClass);$el.removeClass(shadowsTopClass+" "+shadowsBottomClass);edge&&!$videoPlaying&&$el.addClass(edge.replace(/^|\s/g," "+shadowsClass+"--"))}}that.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){if(!this.inProgress){this.count++;this.inProgress=this.count>this.threshold}},end:function(){if(this.inProgress){this.isEnded=true}},reset:function(){this.count=0;this.inProgress=false;this.isEnded=false}};that.destroy=function(){that.cancelFullScreen();that.stopAutoplay();data=that.data=null;appendElements();activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=false;return this};that.playVideo=function(){var dataFrame=activeFrame,video=dataFrame.video,_activeIndex=activeIndex;if(typeof video==="object"&&dataFrame.videoReady){o_nativeFullScreen&&that.fullScreen&&that.cancelFullScreen();waitFor(function(){return!fullScreenApi.is()||_activeIndex!==activeIndex},function(){if(_activeIndex===activeIndex){dataFrame.$video=dataFrame.$video||$(div(videoClass)).append(createVideoFrame(video));dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);$wrap.addClass(wrapVideoClass);$videoPlaying=dataFrame.$video;stageNoMove();$arrs.blur();$fullscreenIcon.blur();triggerEvent("loadvideo")}})}return this};that.stopVideo=function(){unloadVideo($videoPlaying,true,true);return this};that.spliceByIndex=function(index,newImgObj){newImgObj.i=index+1;newImgObj.img&&$.ajax({url:newImgObj.img,type:"HEAD",success:function(){data.splice(index,1,newImgObj);reset()}})};function unloadVideo($video,unloadActiveFLAG,releaseAutoplayFLAG){if(unloadActiveFLAG){$wrap.removeClass(wrapVideoClass);$videoPlaying=false;stageNoMove()}if($video&&$video!==$videoPlaying){$video.remove();triggerEvent("unloadvideo")}if(releaseAutoplayFLAG){releaseAutoplay();changeAutoplay()}}function toggleControlsClass(FLAG){$wrap.toggleClass(wrapNoControlsClass,FLAG)}function stageCursor(e){if(stageShaftTouchTail.flow)return;var x=e?e.pageX:stageCursor.x,pointerFLAG=x&&!disableDirrection(getDirection(x))&&opts.click;if(stageCursor.p!==pointerFLAG&&$stage.toggleClass(pointerClass,pointerFLAG)){stageCursor.p=pointerFLAG;stageCursor.x=x}}$stage.on("mousemove",stageCursor);function clickToShow(showOptions){clearTimeout(clickToShow.t);if(opts.clicktransition&&opts.clicktransition!==opts.transition){setTimeout(function(){var _o_transition=opts.transition;that.setOptions({transition:opts.clicktransition});o_transition=_o_transition;clickToShow.t=setTimeout(function(){that.show(showOptions)},10)},0)}else{that.show(showOptions)}}function onStageTap(e,toggleControlsFLAG){var target=e.target,$target=$(target);if($target.hasClass(videoPlayClass)){that.playVideo()}else if(target===fullscreenIcon){that.toggleFullScreen()}else if($videoPlaying){target===videoClose&&unloadVideo($videoPlaying,true,true)}else if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen()}}function updateTouchTails(key,value){stageShaftTouchTail[key]=navShaftTouchTail[key]=value}stageShaftTouchTail=moveOnTouch($stageShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($stage,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){var toggleControlsFLAG;setShadow($stage);toggleControlsFLAG=(MS_POINTER&&!hoverFLAG||result.touch)&&opts.arrows;if((result.moved||toggleControlsFLAG&&result.pos!==result.newPos&&!result.control)&&result.$target[0]!==$fullscreenIcon[0]){var index=getIndexByPos(result.newPos,measures.w,opts.margin,repositionIndex);that.show({index:index,time:o_fade?o_transitionDuration:result.time,overPos:result.overPos,user:true})}else if(!result.aborted&&!result.control){onStageTap(result.startEvent,toggleControlsFLAG)}},timeLow:1,timeHigh:1,friction:2,select:"."+selectClass+", ."+selectClass+" *",$wrap:$stage,direction:"horizontal"});navShaftTouchTail=moveOnTouch($navShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($nav,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){function onEnd(){slideNavShaft.l=result.newPos;releaseAutoplay();changeAutoplay();thumbsDraw(result.newPos,true);thumbArrUpdate()}if(!result.moved){var target=result.$target.closest("."+navFrameClass,$navShaft)[0];target&&onNavFrameClick.call(target,result.startEvent)}else if(result.pos!==result.newPos){pausedAutoplayFLAG=true;slide($navShaft,{time:result.time,pos:result.newPos,overPos:result.overPos,direction:opts.navdir,onEnd:onEnd});thumbsDraw(result.newPos);o_shadows&&setShadow($nav,findShadowEdge(result.newPos,navShaftTouchTail.min,navShaftTouchTail.max,result.dir))}else{onEnd()}},timeLow:.5,timeHigh:2,friction:5,$wrap:$nav,direction:opts.navdir});stageWheelTail=wheel($stage,{shift:true,onEnd:function(e,direction){onTouchStart();onTouchEnd();that.show({index:direction,slow:e.altKey})}});navWheelTail=wheel($nav,{onEnd:function(e,direction){onTouchStart();onTouchEnd();var newPos=stop($navShaft)+direction*.25;$navShaft.css(getTranslate(minMaxLimit(newPos,navShaftTouchTail.min,navShaftTouchTail.max),opts.navdir));o_shadows&&setShadow($nav,findShadowEdge(newPos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));navWheelTail.prevent={"<":newPos>=navShaftTouchTail.max,">":newPos<=navShaftTouchTail.min};clearTimeout(navWheelTail.t);navWheelTail.t=setTimeout(function(){slideNavShaft.l=newPos;thumbsDraw(newPos,true)},TOUCH_TIMEOUT);thumbsDraw(newPos)}});$wrap.hover(function(){setTimeout(function(){if(touchedFLAG)return;toggleControlsClass(!(hoverFLAG=true))},0)},function(){if(!hoverFLAG)return;toggleControlsClass(!(hoverFLAG=false))});function onNavFrameClick(e){var index=$(this).data().eq;if(opts.navtype==="thumbs"){clickToShow({index:index,slow:e.altKey,user:true,coo:e._x-$nav.offset().left})}else{clickToShow({index:index,slow:e.altKey,user:true})}}function onArrClick(e){clickToShow({index:$arrs.index(this)?">":"<",slow:e.altKey,user:true})}smartClick($arrs,function(e){stopEvent(e);onArrClick.call(this,e)},{onStart:function(){onTouchStart();stageShaftTouchTail.control=true},onTouchEnd:onTouchEnd});smartClick($thumbArrLeft,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show("<")}else{that.showSlide("prev")}});smartClick($thumbArrRight,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show(">")}else{that.showSlide("next")}});function addFocusOnControls(el){addFocus(el,function(){setTimeout(function(){lockScroll($stage)},0);toggleControlsClass(false)})}$arrs.each(function(){addEnterUp(this,function(e){onArrClick.call(this,e)});addFocusOnControls(this)});addEnterUp(fullscreenIcon,function(){if($fotorama.hasClass(fullscreenClass)){that.cancelFullScreen();$stageShaft.focus()}else{that.requestFullScreen();$fullscreenIcon.focus()}});addFocusOnControls(fullscreenIcon);function reset(){setData();setOptions();if(!reset.i){reset.i=true;var _startindex=opts.startindex;activeIndex=repositionIndex=dirtyIndex=lastActiveIndex=startIndex=edgeIndex(_startindex)||0}if(size){if(changeToRtl())return;if($videoPlaying){unloadVideo($videoPlaying,true)}activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=true;that.show({index:activeIndex,time:0});that.resize()}else{that.destroy()}}function changeToRtl(){if(!changeToRtl.f===o_rtl){changeToRtl.f=o_rtl;activeIndex=size-1-activeIndex;that.reverse();return true}}$.each("load push pop shift unshift reverse sort splice".split(" "),function(i,method){that[method]=function(){data=data||[];if(method!=="load"){Array.prototype[method].apply(data,arguments)}else if(arguments[0]&&typeof arguments[0]==="object"&&arguments[0].length){data=clone(arguments[0])}reset();return that}});function ready(){if(ready.ok){ready.ok=false;triggerEvent("ready")}}reset()};$.fn.fotorama=function(opts){return this.each(function(){var that=this,$fotorama=$(this),fotoramaData=$fotorama.data(),fotorama=fotoramaData.fotorama;if(!fotorama){waitFor(function(){return!isHidden(that)},function(){fotoramaData.urtext=$fotorama.html();new $.Fotorama($fotorama,$.extend({},OPTIONS,window.fotoramaDefaults,opts,fotoramaData))})}else{fotorama.setOptions(opts,true)}})};$.Fotorama.instances=[];function calculateIndexes(){$.each($.Fotorama.instances,function(index,instance){instance.index=index})}function addInstance(instance){$.Fotorama.instances.push(instance);calculateIndexes()}function hideInstance(instance){$.Fotorama.instances.splice(instance.index,1);calculateIndexes()}$.Fotorama.cache={};$.Fotorama.measures={};$=$||{};$.Fotorama=$.Fotorama||{};$.Fotorama.jst=$.Fotorama.jst||{};$.Fotorama.jst.dots=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__dot"></div>\r\n</div>';return __p};$.Fotorama.jst.frameCaption=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__caption" aria-hidden="true">\r\n <div class="fotorama__caption__wrap" id="'+((__t=v.labelledby)==null?"":__t)+'">'+((__t=v.caption)==null?"":__t)+"</div>\r\n</div>\r\n";return __p};$.Fotorama.jst.style=function(v){var __t,__p="",__e=_.escape;__p+=".fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+((__t=v.m)==null?"":__t)+"px;\r\nheight:"+((__t=v.h)==null?"":__t)+"px}\r\n.fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__thumb-border{\r\nheight:"+((__t=v.h)==null?"":__t)+"px;\r\nborder-width:"+((__t=v.b)==null?"":__t)+"px;\r\nmargin-top:"+((__t=v.m)==null?"":__t)+"px}";return __p};$.Fotorama.jst.thumb=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__thumb">\r\n </div>\r\n</div>';return __p}})(window,document,location,typeof jQuery!=="undefined"&&jQuery); +fotoramaVersion="4.6.4";(function(window,document,location,$,undefined){"use strict";var _fotoramaClass="fotorama",_fullscreenClass="fotorama__fullscreen",wrapClass=_fotoramaClass+"__wrap",wrapCss2Class=wrapClass+"--css2",wrapCss3Class=wrapClass+"--css3",wrapVideoClass=wrapClass+"--video",wrapFadeClass=wrapClass+"--fade",wrapSlideClass=wrapClass+"--slide",wrapNoControlsClass=wrapClass+"--no-controls",wrapNoShadowsClass=wrapClass+"--no-shadows",wrapPanYClass=wrapClass+"--pan-y",wrapRtlClass=wrapClass+"--rtl",wrapOnlyActiveClass=wrapClass+"--only-active",wrapNoCaptionsClass=wrapClass+"--no-captions",wrapToggleArrowsClass=wrapClass+"--toggle-arrows",stageClass=_fotoramaClass+"__stage",stageFrameClass=stageClass+"__frame",stageFrameVideoClass=stageFrameClass+"--video",stageShaftClass=stageClass+"__shaft",grabClass=_fotoramaClass+"__grab",pointerClass=_fotoramaClass+"__pointer",arrClass=_fotoramaClass+"__arr",arrDisabledClass=arrClass+"--disabled",arrPrevClass=arrClass+"--prev",arrNextClass=arrClass+"--next",navClass=_fotoramaClass+"__nav",navWrapClass=navClass+"-wrap",navShaftClass=navClass+"__shaft",navShaftVerticalClass=navWrapClass+"--vertical",navShaftListClass=navWrapClass+"--list",navShafthorizontalClass=navWrapClass+"--horizontal",navDotsClass=navClass+"--dots",navThumbsClass=navClass+"--thumbs",navFrameClass=navClass+"__frame",fadeClass=_fotoramaClass+"__fade",fadeFrontClass=fadeClass+"-front",fadeRearClass=fadeClass+"-rear",shadowClass=_fotoramaClass+"__shadow",shadowsClass=shadowClass+"s",shadowsLeftClass=shadowsClass+"--left",shadowsRightClass=shadowsClass+"--right",shadowsTopClass=shadowsClass+"--top",shadowsBottomClass=shadowsClass+"--bottom",activeClass=_fotoramaClass+"__active",selectClass=_fotoramaClass+"__select",hiddenClass=_fotoramaClass+"--hidden",fullscreenClass=_fotoramaClass+"--fullscreen",fullscreenIconClass=_fotoramaClass+"__fullscreen-icon",errorClass=_fotoramaClass+"__error",loadingClass=_fotoramaClass+"__loading",loadedClass=_fotoramaClass+"__loaded",loadedFullClass=loadedClass+"--full",loadedImgClass=loadedClass+"--img",grabbingClass=_fotoramaClass+"__grabbing",imgClass=_fotoramaClass+"__img",imgFullClass=imgClass+"--full",thumbClass=_fotoramaClass+"__thumb",thumbArrLeft=thumbClass+"__arr--left",thumbArrRight=thumbClass+"__arr--right",thumbBorderClass=thumbClass+"-border",htmlClass=_fotoramaClass+"__html",videoContainerClass=_fotoramaClass+"-video-container",videoClass=_fotoramaClass+"__video",videoPlayClass=videoClass+"-play",videoCloseClass=videoClass+"-close",horizontalImageClass=_fotoramaClass+"_horizontal_ratio",verticalImageClass=_fotoramaClass+"_vertical_ratio",fotoramaSpinnerClass=_fotoramaClass+"__spinner",spinnerShowClass=fotoramaSpinnerClass+"--show";var JQUERY_VERSION=$&&$.fn.jquery.split(".");if(!JQUERY_VERSION||JQUERY_VERSION[0]<1||JQUERY_VERSION[0]==1&&JQUERY_VERSION[1]<8){throw"Fotorama requires jQuery 1.8 or later and will not run without it."}var _={};var Modernizr=function(window,document,undefined){var version="2.8.3",Modernizr={},docElement=document.documentElement,mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,inputElem,toString={}.toString,prefixes=" -webkit- -moz- -o- -ms- ".split(" "),omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),body=document.body,fakeBody=body||document.createElement("body");if(parseInt(nodes,10)){while(nodes--){node=document.createElement("div");node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node)}}style=["­",'<style id="s',mod,'">',rule,"</style>"].join("");div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background="";fakeBody.style.overflow="hidden";docOverflow=docElement.style.overflow;docElement.style.overflow="hidden";docElement.appendChild(fakeBody)}ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow}else{div.parentNode.removeChild(div)}return!!ret},_hasOwnProperty={}.hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,"undefined")&&!is(_hasOwnProperty.call,"undefined")){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property)}}else{hasOwnProp=function(object,property){return property in object&&is(object.constructor.prototype[property],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError}var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F;var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result}return self}else{return target.apply(that,args.concat(slice.call(arguments)))}};return bound}}function setCss(str){mStyle.cssText=str}function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}function is(obj,type){return typeof obj===type}function contains(str,substr){return!!~(""+str).indexOf(substr)}function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=="pfx"?prop:true}}return false}function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,"function")){return item.bind(elem||obj)}return item}}return false}function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed)}else{props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" ");return testDOMProps(props,prefixed,elem)}}tests["touch"]=function(){var bool;if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch){bool=true}else{injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=node.offsetTop===9})}return bool};tests["csstransforms3d"]=function(){var ret=!!testPropsAll("perspective");if(ret&&"webkitPerspective"in docElement.style){injectElementWithStyles("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3})}return ret};tests["csstransitions"]=function(){return testPropsAll("transition")};for(var feature in tests){if(hasOwnProp(tests,feature)){featureName=feature.toLowerCase();Modernizr[featureName]=tests[feature]();classes.push((Modernizr[featureName]?"":"no-")+featureName)}}Modernizr.addTest=function(feature,test){if(typeof feature=="object"){for(var key in feature){if(hasOwnProp(feature,key)){Modernizr.addTest(key,feature[key])}}}else{feature=feature.toLowerCase();if(Modernizr[feature]!==undefined){return Modernizr}test=typeof test=="function"?test():test;if(typeof enableClasses!=="undefined"&&enableClasses){docElement.className+=" "+(test?"":"no-")+feature}Modernizr[feature]=test}return Modernizr};setCss("");modElem=inputElem=null;Modernizr._version=version;Modernizr._prefixes=prefixes;Modernizr._domPrefixes=domPrefixes;Modernizr._cssomPrefixes=cssomPrefixes;Modernizr.testProp=function(prop){return testProps([prop])};Modernizr.testAllProps=testPropsAll;Modernizr.testStyles=injectElementWithStyles;Modernizr.prefixed=function(prop,obj,elem){if(!obj){return testPropsAll(prop,"pfx")}else{return testPropsAll(prop,obj,elem)}};return Modernizr}(window,document);var fullScreenApi={ok:false,is:function(){return false},request:function(){},cancel:function(){},event:"",prefix:""},browserPrefixes="webkit moz o ms khtml".split(" ");if(typeof document.cancelFullScreen!="undefined"){fullScreenApi.ok=true}else{for(var i=0,il=browserPrefixes.length;i<il;i++){fullScreenApi.prefix=browserPrefixes[i];if(typeof document[fullScreenApi.prefix+"CancelFullScreen"]!="undefined"){fullScreenApi.ok=true;break}}}if(fullScreenApi.ok){fullScreenApi.event=fullScreenApi.prefix+"fullscreenchange";fullScreenApi.is=function(){switch(this.prefix){case"":return document.fullScreen;case"webkit":return document.webkitIsFullScreen;default:return document[this.prefix+"FullScreen"]}};fullScreenApi.request=function(el){return this.prefix===""?el.requestFullScreen():el[this.prefix+"RequestFullScreen"]()};fullScreenApi.cancel=function(el){return this.prefix===""?document.cancelFullScreen():document[this.prefix+"CancelFullScreen"]()}}function bez(coOrdArray){var encodedFuncName="bez_"+$.makeArray(arguments).join("_").replace(".","p");if(typeof $["easing"][encodedFuncName]!=="function"){var polyBez=function(p1,p2){var A=[null,null],B=[null,null],C=[null,null],bezCoOrd=function(t,ax){C[ax]=3*p1[ax];B[ax]=3*(p2[ax]-p1[ax])-C[ax];A[ax]=1-C[ax]-B[ax];return t*(C[ax]+t*(B[ax]+t*A[ax]))},xDeriv=function(t){return C[0]+t*(2*B[0]+3*A[0]*t)},xForT=function(t){var x=t,i=0,z;while(++i<14){z=bezCoOrd(x,0)-t;if(Math.abs(z)<.001)break;x-=z/xDeriv(x)}return x};return function(t){return bezCoOrd(xForT(t),1)}};$["easing"][encodedFuncName]=function(x,t,b,c,d){return c*polyBez([coOrdArray[0],coOrdArray[1]],[coOrdArray[2],coOrdArray[3]])(t/d)+b}}return encodedFuncName}var $WINDOW=$(window),$DOCUMENT=$(document),$HTML,$BODY,QUIRKS_FORCE=location.hash.replace("#","")==="quirks",TRANSFORMS3D=Modernizr.csstransforms3d,CSS3=TRANSFORMS3D&&!QUIRKS_FORCE,COMPAT=TRANSFORMS3D||document.compatMode==="CSS1Compat",FULLSCREEN=fullScreenApi.ok,MOBILE=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),SLOW=!CSS3||MOBILE,MS_POINTER=navigator.msPointerEnabled,WHEEL="onwheel"in document.createElement("div")?"wheel":document.onmousewheel!==undefined?"mousewheel":"DOMMouseScroll",TOUCH_TIMEOUT=250,TRANSITION_DURATION=300,SCROLL_LOCK_TIMEOUT=1400,AUTOPLAY_INTERVAL=5e3,MARGIN=2,THUMB_SIZE=64,WIDTH=500,HEIGHT=333,STAGE_FRAME_KEY="$stageFrame",NAV_DOT_FRAME_KEY="$navDotFrame",NAV_THUMB_FRAME_KEY="$navThumbFrame",AUTO="auto",BEZIER=bez([.1,0,.25,1]),MAX_WIDTH=1200,thumbsPerSlide=1,OPTIONS={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:MARGIN,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:THUMB_SIZE,thumbheight:THUMB_SIZE,thumbmargin:MARGIN,thumbborderwidth:MARGIN,allowfullscreen:false,transition:"slide",clicktransition:null,transitionduration:TRANSITION_DURATION,captions:true,startindex:0,loop:false,autoplay:false,stopautoplayontouch:true,keyboard:false,arrows:true,click:true,swipe:false,trackpad:false,shuffle:false,direction:"ltr",shadows:true,showcaption:true,navdir:"horizontal",navarrows:true,navtype:"thumbs"},KEYBOARD_OPTIONS={left:true,right:true,down:true,up:true,space:false,home:false,end:false};function noop(){}function minMaxLimit(value,min,max){return Math.max(isNaN(min)?-Infinity:min,Math.min(isNaN(max)?Infinity:max,value))}function readTransform(css,dir){return css.match(/ma/)&&css.match(/-?\d+(?!d)/g)[css.match(/3d/)?dir==="vertical"?13:12:dir==="vertical"?5:4]}function readPosition($el,dir){if(CSS3){return+readTransform($el.css("transform"),dir)}else{return+$el.css(dir==="vertical"?"top":"left").replace("px","")}}function getTranslate(pos,direction){var obj={};if(CSS3){switch(direction){case"vertical":obj.transform="translate3d(0, "+pos+"px,0)";break;case"list":break;default:obj.transform="translate3d("+pos+"px,0,0)";break}}else{direction==="vertical"?obj.top=pos:obj.left=pos}return obj}function getDuration(time){return{"transition-duration":time+"ms"}}function unlessNaN(value,alternative){return isNaN(value)?alternative:value}function numberFromMeasure(value,measure){return unlessNaN(+String(value).replace(measure||"px",""))}function numberFromPercent(value){return/%$/.test(value)?numberFromMeasure(value,"%"):undefined}function numberFromWhatever(value,whole){return unlessNaN(numberFromPercent(value)/100*whole,numberFromMeasure(value))}function measureIsValid(value){return(!isNaN(numberFromMeasure(value))||!isNaN(numberFromMeasure(value,"%")))&&value}function getPosByIndex(index,side,margin,baseIndex){return(index-(baseIndex||0))*(side+(margin||0))}function getIndexByPos(pos,side,margin,baseIndex){return-Math.round(pos/(side+(margin||0))-(baseIndex||0))}function bindTransitionEnd($el){var elData=$el.data();if(elData.tEnd)return;var el=$el[0],transitionEndEvent={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};addEvent(el,transitionEndEvent[Modernizr.prefixed("transition")],function(e){elData.tProp&&e.propertyName.match(elData.tProp)&&elData.onEndFn()});elData.tEnd=true}function afterTransition($el,property,fn,time){var ok,elData=$el.data();if(elData){elData.onEndFn=function(){if(ok)return;ok=true;clearTimeout(elData.tT);fn()};elData.tProp=property;clearTimeout(elData.tT);elData.tT=setTimeout(function(){elData.onEndFn()},time*1.5);bindTransitionEnd($el)}}function stop($el,pos){var dir=$el.navdir||"horizontal";if($el.length){var elData=$el.data();if(CSS3){$el.css(getDuration(0));elData.onEndFn=noop;clearTimeout(elData.tT)}else{$el.stop()}var lockedPos=getNumber(pos,function(){return readPosition($el,dir)});$el.css(getTranslate(lockedPos,dir));return lockedPos}}function getNumber(){var number;for(var _i=0,_l=arguments.length;_i<_l;_i++){number=_i?arguments[_i]():arguments[_i];if(typeof number==="number"){break}}return number}function edgeResistance(pos,edge){return Math.round(pos+(edge-pos)/1.5)}function getProtocol(){getProtocol.p=getProtocol.p||(location.protocol==="https:"?"https://":"http://");return getProtocol.p}function parseHref(href){var a=document.createElement("a");a.href=href;return a}function findVideoId(href,forceVideo){if(typeof href!=="string")return href;href=parseHref(href);var id,type;if(href.host.match(/youtube\.com/)&&href.search){id=href.search.split("v=")[1];if(id){var ampersandPosition=id.indexOf("&");if(ampersandPosition!==-1){id=id.substring(0,ampersandPosition)}type="youtube"}}else if(href.host.match(/youtube\.com|youtu\.be/)){id=href.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,"");type="youtube"}else if(href.host.match(/vimeo\.com/)){type="vimeo";id=href.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,"")}if((!id||!type)&&forceVideo){id=href.href;type="custom"}return id?{id:id,type:type,s:href.search.replace(/^\?/,""),p:getProtocol()}:false}function getVideoThumbs(dataFrame,data,fotorama){var img,thumb,video=dataFrame.video;if(video.type==="youtube"){thumb=getProtocol()+"img.youtube.com/vi/"+video.id+"/default.jpg";img=thumb.replace(/\/default.jpg$/,"/hqdefault.jpg");dataFrame.thumbsReady=true}else if(video.type==="vimeo"){$.ajax({url:getProtocol()+"vimeo.com/api/v2/video/"+video.id+".json",dataType:"jsonp",success:function(json){dataFrame.thumbsReady=true;updateData(data,{img:json[0].thumbnail_large,thumb:json[0].thumbnail_small},dataFrame.i,fotorama)}})}else{dataFrame.thumbsReady=true}return{img:img,thumb:thumb}}function updateData(data,_dataFrame,i,fotorama){for(var _i=0,_l=data.length;_i<_l;_i++){var dataFrame=data[_i];if(dataFrame.i===i&&dataFrame.thumbsReady){var clear={videoReady:true};clear[STAGE_FRAME_KEY]=clear[NAV_THUMB_FRAME_KEY]=clear[NAV_DOT_FRAME_KEY]=false;fotorama.splice(_i,1,$.extend({},dataFrame,clear,_dataFrame));break}}}function getDataFromHtml($el){var data=[];function getDataFromImg($img,imgData,checkVideo){var $child=$img.children("img").eq(0),_imgHref=$img.attr("href"),_imgSrc=$img.attr("src"),_thumbSrc=$child.attr("src"),_video=imgData.video,video=checkVideo?findVideoId(_imgHref,_video===true):false;if(video){_imgHref=false}else{video=_video}getDimensions($img,$child,$.extend(imgData,{video:video,img:imgData.img||_imgHref||_imgSrc||_thumbSrc,thumb:imgData.thumb||_thumbSrc||_imgSrc||_imgHref}))}function getDimensions($img,$child,imgData){var separateThumbFLAG=imgData.thumb&&imgData.img!==imgData.thumb,width=numberFromMeasure(imgData.width||$img.attr("width")),height=numberFromMeasure(imgData.height||$img.attr("height"));$.extend(imgData,{width:width,height:height,thumbratio:getRatio(imgData.thumbratio||numberFromMeasure(imgData.thumbwidth||$child&&$child.attr("width")||separateThumbFLAG||width)/numberFromMeasure(imgData.thumbheight||$child&&$child.attr("height")||separateThumbFLAG||height))})}$el.children().each(function(){var $this=$(this),dataFrame=optionsToLowerCase($.extend($this.data(),{id:$this.attr("id")}));if($this.is("a, img")){getDataFromImg($this,dataFrame,true)}else if(!$this.is(":empty")){getDimensions($this,null,$.extend(dataFrame,{html:this,_html:$this.html()}))}else return;data.push(dataFrame)});return data}function isHidden(el){return el.offsetWidth===0&&el.offsetHeight===0}function isDetached(el){return!$.contains(document.documentElement,el)}function waitFor(test,fn,timeout,i){if(!waitFor.i){waitFor.i=1;waitFor.ii=[true]}i=i||waitFor.i;if(typeof waitFor.ii[i]==="undefined"){waitFor.ii[i]=true}if(test()){fn()}else{waitFor.ii[i]&&setTimeout(function(){waitFor.ii[i]&&waitFor(test,fn,timeout,i)},timeout||100)}return waitFor.i++}waitFor.stop=function(i){waitFor.ii[i]=false};function fit($el,measuresToFit){var elData=$el.data(),measures=elData.measures;if(measures&&(!elData.l||elData.l.W!==measures.width||elData.l.H!==measures.height||elData.l.r!==measures.ratio||elData.l.w!==measuresToFit.w||elData.l.h!==measuresToFit.h)){var height=minMaxLimit(measuresToFit.h,0,measures.height),width=height*measures.ratio;UTIL.setRatio($el,width,height);elData.l={W:measures.width,H:measures.height,r:measures.ratio,w:measuresToFit.w,h:measuresToFit.h}}return true}function setStyle($el,style){var el=$el[0];if(el.styleSheet){el.styleSheet.cssText=style}else{$el.html(style)}}function findShadowEdge(pos,min,max,dir){return min===max?false:dir==="vertical"?pos<=min?"top":pos>=max?"bottom":"top bottom":pos<=min?"left":pos>=max?"right":"left right"}function smartClick($el,fn,_options){_options=_options||{};$el.each(function(){var $this=$(this),thisData=$this.data(),startEvent;if(thisData.clickOn)return;thisData.clickOn=true;$.extend(touch($this,{onStart:function(e){startEvent=e;(_options.onStart||noop).call(this,e)},onMove:_options.onMove||noop,onTouchEnd:_options.onTouchEnd||noop,onEnd:function(result){if(result.moved)return;fn.call(this,startEvent)}}),{noMove:true})})}function div(classes,child){return'<div class="'+classes+'">'+(child||"")+"</div>"}function cls(className){return"."+className}function createVideoFrame(videoItem){var frame='<iframe src="'+videoItem.p+videoItem.type+".com/embed/"+videoItem.id+'" frameborder="0" allowfullscreen></iframe>';return frame}function shuffle(array){var l=array.length;while(l){var i=Math.floor(Math.random()*l--);var t=array[l];array[l]=array[i];array[i]=t}return array}function clone(array){return Object.prototype.toString.call(array)=="[object Array]"&&$.map(array,function(frame){return $.extend({},frame)})}function lockScroll($el,left,top){$el.scrollLeft(left||0).scrollTop(top||0)}function optionsToLowerCase(options){if(options){var opts={};$.each(options,function(key,value){opts[key.toLowerCase()]=value});return opts}}function getRatio(_ratio){if(!_ratio)return;var ratio=+_ratio;if(!isNaN(ratio)){return ratio}else{ratio=_ratio.split("/");return+ratio[0]/+ratio[1]||undefined}}function addEvent(el,e,fn,bool){if(!e)return;el.addEventListener?el.addEventListener(e,fn,!!bool):el.attachEvent("on"+e,fn)}function validateRestrictions(position,restriction){if(position>restriction.max){position=restriction.max}else{if(position<restriction.min){position=restriction.min}}return position}function validateSlidePos(opt,navShaftTouchTail,guessIndex,offsetNav,$guessNavFrame,$navWrap,dir){var position,size,wrapSize;if(dir==="horizontal"){size=opt.thumbwidth;wrapSize=$navWrap.width()}else{size=opt.thumbheight;wrapSize=$navWrap.height()}if((size+opt.margin)*(guessIndex+1)>=wrapSize-offsetNav){if(dir==="horizontal"){position=-$guessNavFrame.position().left}else{position=-$guessNavFrame.position().top}}else{if((size+opt.margin)*guessIndex<=Math.abs(offsetNav)){if(dir==="horizontal"){position=-$guessNavFrame.position().left+wrapSize-(size+opt.margin)}else{position=-$guessNavFrame.position().top+wrapSize-(size+opt.margin)}}else{position=offsetNav}}position=validateRestrictions(position,navShaftTouchTail);return position||0}function elIsDisabled(el){return!!el.getAttribute("disabled")}function disableAttr(FLAG,disable){if(disable){return{disabled:FLAG}}else{return{tabindex:FLAG*-1+"",disabled:FLAG}}}function addEnterUp(el,fn){addEvent(el,"keyup",function(e){elIsDisabled(el)||e.keyCode==13&&fn.call(el,e)})}function addFocus(el,fn){addEvent(el,"focus",el.onfocusin=function(e){fn.call(el,e)},true)}function stopEvent(e,stopPropagation){e.preventDefault?e.preventDefault():e.returnValue=false;stopPropagation&&e.stopPropagation&&e.stopPropagation()}function stubEvent($el,eventType){var isIOS=/ip(ad|hone|od)/i.test(window.navigator.userAgent);if(isIOS&&eventType==="touchend"){$el.on("touchend",function(e){$DOCUMENT.trigger("mouseup",e)})}$el.on(eventType,function(e){stopEvent(e,true);return false})}function getDirectionSign(forward){return forward?">":"<"}var UTIL=function(){function setRatioClass($el,wh,ht){var rateImg=wh/ht;if(rateImg<=1){$el.parent().removeClass(horizontalImageClass);$el.parent().addClass(verticalImageClass)}else{$el.parent().removeClass(verticalImageClass);$el.parent().addClass(horizontalImageClass)}}function setThumbAttr($frame,value,searchAttr){var attr=searchAttr;if(!$frame.attr(attr)&&$frame.attr(attr)!==undefined){$frame.attr(attr,value)}if($frame.find("["+attr+"]").length){$frame.find("["+attr+"]").each(function(){$(this).attr(attr,value)})}}function isExpectedCaption(frameItem,isExpected,undefined){var expected=false,frameExpected;frameItem.showCaption===undefined||frameItem.showCaption===true?frameExpected=true:frameExpected=false;if(!isExpected){return false}if(frameItem.caption&&frameExpected){expected=true}return expected}return{setRatio:setRatioClass,setThumbAttr:setThumbAttr,isExpectedCaption:isExpectedCaption}}(UTIL||{},jQuery);function slide($el,options){var elData=$el.data(),elPos=Math.round(options.pos),onEndFn=function(){if(elData&&elData.sliding){elData.sliding=false}(options.onEnd||noop)()};if(typeof options.overPos!=="undefined"&&options.overPos!==options.pos){elPos=options.overPos}var translate=$.extend(getTranslate(elPos,options.direction),options.width&&{width:options.width},options.height&&{height:options.height});if(elData&&elData.sliding){elData.sliding=true}if(CSS3){$el.css($.extend(getDuration(options.time),translate));if(options.time>10){afterTransition($el,"transform",onEndFn,options.time)}else{onEndFn()}}else{$el.stop().animate(translate,options.time,BEZIER,onEndFn)}}function fade($el1,$el2,$frames,options,fadeStack,chain){var chainedFLAG=typeof chain!=="undefined";if(!chainedFLAG){fadeStack.push(arguments);Array.prototype.push.call(arguments,fadeStack.length);if(fadeStack.length>1)return}$el1=$el1||$($el1);$el2=$el2||$($el2);var _$el1=$el1[0],_$el2=$el2[0],crossfadeFLAG=options.method==="crossfade",onEndFn=function(){if(!onEndFn.done){onEndFn.done=true;var args=(chainedFLAG||fadeStack.shift())&&fadeStack.shift();args&&fade.apply(this,args);(options.onEnd||noop)(!!args)}},time=options.time/(chain||1);$frames.removeClass(fadeRearClass+" "+fadeFrontClass);$el1.stop().addClass(fadeRearClass);$el2.stop().addClass(fadeFrontClass);crossfadeFLAG&&_$el2&&$el1.fadeTo(0,0);$el1.fadeTo(crossfadeFLAG?time:0,1,crossfadeFLAG&&onEndFn);$el2.fadeTo(time,0,onEndFn);_$el1&&crossfadeFLAG||_$el2||onEndFn()}var lastEvent,moveEventType,preventEvent,preventEventTimeout,dragDomEl;function extendEvent(e){var touch=(e.touches||[])[0]||e;e._x=touch.pageX||touch.originalEvent.pageX;e._y=touch.clientY||touch.originalEvent.clientY;e._now=$.now()}function touch($el,options){var el=$el[0],tail={},touchEnabledFLAG,startEvent,$target,controlTouch,touchFLAG,targetIsSelectFLAG,targetIsLinkFlag,tolerance,moved;function onStart(e){$target=$(e.target);tail.checked=targetIsSelectFLAG=targetIsLinkFlag=moved=false;if(touchEnabledFLAG||tail.flow||e.touches&&e.touches.length>1||e.which>1||lastEvent&&lastEvent.type!==e.type&&preventEvent||(targetIsSelectFLAG=options.select&&$target.is(options.select,el)))return targetIsSelectFLAG;touchFLAG=e.type==="touchstart";targetIsLinkFlag=$target.is("a, a *",el);controlTouch=tail.control;tolerance=tail.noMove||tail.noSwipe||controlTouch?16:!tail.snap?4:0;extendEvent(e);startEvent=lastEvent=e;moveEventType=e.type.replace(/down|start/,"move").replace(/Down/,"Move");(options.onStart||noop).call(el,e,{control:controlTouch,$target:$target});touchEnabledFLAG=tail.flow=true;if(!touchFLAG||tail.go)stopEvent(e)}function onMove(e){if(e.touches&&e.touches.length>1||MS_POINTER&&!e.isPrimary||moveEventType!==e.type||!touchEnabledFLAG){touchEnabledFLAG&&onEnd();(options.onTouchEnd||noop)();return}extendEvent(e);var xDiff=Math.abs(e._x-startEvent._x),yDiff=Math.abs(e._y-startEvent._y),xyDiff=xDiff-yDiff,xWin=(tail.go||tail.x||xyDiff>=0)&&!tail.noSwipe,yWin=xyDiff<0;if(touchFLAG&&!tail.checked){if(touchEnabledFLAG=xWin){stopEvent(e)}}else{stopEvent(e);if(movedEnough(xDiff,yDiff)){(options.onMove||noop).call(el,e,{touch:touchFLAG})}}if(!moved&&movedEnough(xDiff,yDiff)&&Math.sqrt(Math.pow(xDiff,2)+Math.pow(yDiff,2))>tolerance){moved=true}tail.checked=tail.checked||xWin||yWin}function movedEnough(xDiff,yDiff){return xDiff>yDiff&&xDiff>1.5}function onEnd(e){(options.onTouchEnd||noop)();var _touchEnabledFLAG=touchEnabledFLAG;tail.control=touchEnabledFLAG=false;if(_touchEnabledFLAG){tail.flow=false}if(!_touchEnabledFLAG||targetIsLinkFlag&&!tail.checked)return;e&&stopEvent(e);preventEvent=true;clearTimeout(preventEventTimeout);preventEventTimeout=setTimeout(function(){preventEvent=false},1e3);(options.onEnd||noop).call(el,{moved:moved,$target:$target,control:controlTouch,touch:touchFLAG,startEvent:startEvent,aborted:!e||e.type==="MSPointerCancel"})}function onOtherStart(){if(tail.flow)return;tail.flow=true}function onOtherEnd(){if(!tail.flow)return;tail.flow=false}if(MS_POINTER){addEvent(el,"MSPointerDown",onStart);addEvent(document,"MSPointerMove",onMove);addEvent(document,"MSPointerCancel",onEnd);addEvent(document,"MSPointerUp",onEnd)}else{addEvent(el,"touchstart",onStart);addEvent(el,"touchmove",onMove);addEvent(el,"touchend",onEnd);addEvent(document,"touchstart",onOtherStart);addEvent(document,"touchend",onOtherEnd);addEvent(document,"touchcancel",onOtherEnd);$WINDOW.on("scroll",onOtherEnd);$el.on("mousedown pointerdown",onStart);$DOCUMENT.on("mousemove pointermove",onMove).on("mouseup pointerup",onEnd)}if(Modernizr.touch){dragDomEl="a"}else{dragDomEl="div"}$el.on("click",dragDomEl,function(e){tail.checked&&stopEvent(e)});return tail}function moveOnTouch($el,options){var el=$el[0],elData=$el.data(),tail={},startCoo,coo,startElPos,moveElPos,edge,moveTrack,startTime,endTime,min,max,snap,dir,slowFLAG,controlFLAG,moved,tracked;function startTracking(e,noStop){tracked=true;startCoo=coo=dir==="vertical"?e._y:e._x;startTime=e._now;moveTrack=[[startTime,startCoo]];startElPos=moveElPos=tail.noMove||noStop?0:stop($el,(options.getPos||noop)());(options.onStart||noop).call(el,e)}function onStart(e,result){min=tail.min;max=tail.max;snap=tail.snap,dir=tail.direction||"horizontal",$el.navdir=dir;slowFLAG=e.altKey;tracked=moved=false;controlFLAG=result.control;if(!controlFLAG&&!elData.sliding){startTracking(e)}}function onMove(e,result){if(!tail.noSwipe){if(!tracked){startTracking(e)}coo=dir==="vertical"?e._y:e._x;moveTrack.push([e._now,coo]);moveElPos=startElPos-(startCoo-coo);edge=findShadowEdge(moveElPos,min,max,dir);if(moveElPos<=min){moveElPos=edgeResistance(moveElPos,min)}else if(moveElPos>=max){moveElPos=edgeResistance(moveElPos,max)}if(!tail.noMove){$el.css(getTranslate(moveElPos,dir));if(!moved){moved=true;result.touch||MS_POINTER||$el.addClass(grabbingClass)}(options.onMove||noop).call(el,e,{pos:moveElPos,edge:edge})}}}function onEnd(result){if(tail.noSwipe&&result.moved)return;if(!tracked){startTracking(result.startEvent,true)}result.touch||MS_POINTER||$el.removeClass(grabbingClass);endTime=$.now();var _backTimeIdeal=endTime-TOUCH_TIMEOUT,_backTime,_timeDiff,_timeDiffLast,backTime=null,backCoo,virtualPos,limitPos,newPos,overPos,time=TRANSITION_DURATION,speed,friction=options.friction;for(var _i=moveTrack.length-1;_i>=0;_i--){_backTime=moveTrack[_i][0];_timeDiff=Math.abs(_backTime-_backTimeIdeal);if(backTime===null||_timeDiff<_timeDiffLast){backTime=_backTime;backCoo=moveTrack[_i][1]}else if(backTime===_backTimeIdeal||_timeDiff>_timeDiffLast){break}_timeDiffLast=_timeDiff}newPos=minMaxLimit(moveElPos,min,max);var cooDiff=backCoo-coo,forwardFLAG=cooDiff>=0,timeDiff=endTime-backTime,longTouchFLAG=timeDiff>TOUCH_TIMEOUT,swipeFLAG=!longTouchFLAG&&moveElPos!==startElPos&&newPos===moveElPos;if(snap){newPos=minMaxLimit(Math[swipeFLAG?forwardFLAG?"floor":"ceil":"round"](moveElPos/snap)*snap,min,max);min=max=newPos}if(swipeFLAG&&(snap||newPos===moveElPos)){speed=-(cooDiff/timeDiff);time*=minMaxLimit(Math.abs(speed),options.timeLow,options.timeHigh);virtualPos=Math.round(moveElPos+speed*time/friction);if(!snap){newPos=virtualPos}if(!forwardFLAG&&virtualPos>max||forwardFLAG&&virtualPos<min){limitPos=forwardFLAG?min:max;overPos=virtualPos-limitPos;if(!snap){newPos=limitPos}overPos=minMaxLimit(newPos+overPos*.03,limitPos-50,limitPos+50);time=Math.abs((moveElPos-overPos)/(speed/friction))}}time*=slowFLAG?10:1;(options.onEnd||noop).call(el,$.extend(result,{moved:result.moved||longTouchFLAG&&snap,pos:moveElPos,newPos:newPos,overPos:overPos,time:time,dir:dir}))}tail=$.extend(touch(options.$wrap,$.extend({},options,{onStart:onStart,onMove:onMove,onEnd:onEnd})),tail);return tail}function wheel($el,options){var el=$el[0],lockFLAG,lastDirection,lastNow,tail={prevent:{}};addEvent(el,WHEEL,function(e){var yDelta=e.wheelDeltaY||-1*e.deltaY||0,xDelta=e.wheelDeltaX||-1*e.deltaX||0,xWin=Math.abs(xDelta)&&!Math.abs(yDelta),direction=getDirectionSign(xDelta<0),sameDirection=lastDirection===direction,now=$.now(),tooFast=now-lastNow<TOUCH_TIMEOUT;lastDirection=direction;lastNow=now;if(!xWin||!tail.ok||tail.prevent[direction]&&!lockFLAG){return}else{stopEvent(e,true);if(lockFLAG&&sameDirection&&tooFast){return}}if(options.shift){lockFLAG=true;clearTimeout(tail.t);tail.t=setTimeout(function(){lockFLAG=false},SCROLL_LOCK_TIMEOUT)}(options.onEnd||noop)(e,options.shift?direction:xDelta)});return tail}jQuery.Fotorama=function($fotorama,opts){$HTML=$("html");$BODY=$("body");var that=this,stamp=$.now(),stampClass=_fotoramaClass+stamp,fotorama=$fotorama[0],data,dataFrameCount=1,fotoramaData=$fotorama.data(),size,$style=$("<style></style>"),$anchor=$(div(hiddenClass)),$wrap=$fotorama.find(cls(wrapClass)),$stage=$wrap.find(cls(stageClass)),stage=$stage[0],$stageShaft=$fotorama.find(cls(stageShaftClass)),$stageFrame=$(),$arrPrev=$fotorama.find(cls(arrPrevClass)),$arrNext=$fotorama.find(cls(arrNextClass)),$arrs=$fotorama.find(cls(arrClass)),$navWrap=$fotorama.find(cls(navWrapClass)),$nav=$navWrap.find(cls(navClass)),$navShaft=$nav.find(cls(navShaftClass)),$navFrame,$navDotFrame=$(),$navThumbFrame=$(),stageShaftData=$stageShaft.data(),navShaftData=$navShaft.data(),$thumbBorder=$fotorama.find(cls(thumbBorderClass)),$thumbArrLeft=$fotorama.find(cls(thumbArrLeft)),$thumbArrRight=$fotorama.find(cls(thumbArrRight)),$fullscreenIcon=$fotorama.find(cls(fullscreenIconClass)),fullscreenIcon=$fullscreenIcon[0],$videoPlay=$(div(videoPlayClass)),$videoClose=$fotorama.find(cls(videoCloseClass)),videoClose=$videoClose[0],$spinner=$fotorama.find(cls(fotoramaSpinnerClass)),$videoPlaying,activeIndex=false,activeFrame,activeIndexes,repositionIndex,dirtyIndex,lastActiveIndex,prevIndex,nextIndex,nextAutoplayIndex,startIndex,o_loop,o_nav,o_navThumbs,o_navTop,o_allowFullScreen,o_nativeFullScreen,o_fade,o_thumbSide,o_thumbSide2,o_transitionDuration,o_transition,o_shadows,o_rtl,o_keyboard,lastOptions={},measures={},measuresSetFLAG,stageShaftTouchTail={},stageWheelTail={},navShaftTouchTail={},navWheelTail={},scrollTop,scrollLeft,showedFLAG,pausedAutoplayFLAG,stoppedAutoplayFLAG,toDeactivate={},toDetach={},measuresStash,touchedFLAG,hoverFLAG,navFrameKey,stageLeft=0,fadeStack=[];$wrap[STAGE_FRAME_KEY]=$('<div class="'+stageFrameClass+'"></div>');$wrap[NAV_THUMB_FRAME_KEY]=$($.Fotorama.jst.thumb());$wrap[NAV_DOT_FRAME_KEY]=$($.Fotorama.jst.dots());toDeactivate[STAGE_FRAME_KEY]=[];toDeactivate[NAV_THUMB_FRAME_KEY]=[];toDeactivate[NAV_DOT_FRAME_KEY]=[];toDetach[STAGE_FRAME_KEY]={};$wrap.addClass(CSS3?wrapCss3Class:wrapCss2Class);fotoramaData.fotorama=this;function checkForVideo(){$.each(data,function(i,dataFrame){if(!dataFrame.i){dataFrame.i=dataFrameCount++;var video=findVideoId(dataFrame.video,true);if(video){var thumbs={};dataFrame.video=video;if(!dataFrame.img&&!dataFrame.thumb){thumbs=getVideoThumbs(dataFrame,data,that)}else{dataFrame.thumbsReady=true}updateData(data,{img:thumbs.img,thumb:thumbs.thumb},dataFrame.i,that)}}})}function allowKey(key){return o_keyboard[key]}function setStagePosition(){if($stage!==undefined){if(opts.navdir=="vertical"){var padding=opts.thumbwidth+opts.thumbmargin;$stage.css("left",padding);$arrNext.css("right",padding);$fullscreenIcon.css("right",padding);$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width",$wrap.width()-padding)}else{$stage.css("left","");$arrNext.css("right","");$fullscreenIcon.css("right","");$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width","")}}}function bindGlobalEvents(FLAG){var keydownCommon="keydown."+_fotoramaClass,localStamp=_fotoramaClass+stamp,keydownLocal="keydown."+localStamp,keyupLocal="keyup."+localStamp,resizeLocal="resize."+localStamp+" "+"orientationchange."+localStamp,showParams;if(FLAG){$DOCUMENT.on(keydownLocal,function(e){var catched,index;if($videoPlaying&&e.keyCode===27){catched=true;unloadVideo($videoPlaying,true,true)}else if(that.fullScreen||opts.keyboard&&!that.index){if(e.keyCode===27){catched=true;that.cancelFullScreen()}else if(e.shiftKey&&e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===37&&allowKey("left")||e.keyCode===38&&allowKey("up")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index="<"}else if(e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===39&&allowKey("right")||e.keyCode===40&&allowKey("down")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index=">"}else if(e.keyCode===36&&allowKey("home")){that.longPress.progress();index="<<"}else if(e.keyCode===35&&allowKey("end")){that.longPress.progress();index=">>"}}(catched||index)&&stopEvent(e);showParams={index:index,slow:e.altKey,user:true};index&&(that.longPress.inProgress?that.showWhileLongPress(showParams):that.show(showParams))});if(FLAG){$DOCUMENT.on(keyupLocal,function(e){if(that.longPress.inProgress){that.showEndLongPress({user:true})}that.longPress.reset()})}if(!that.index){$DOCUMENT.off(keydownCommon).on(keydownCommon,"textarea, input, select",function(e){!$BODY.hasClass(_fullscreenClass)&&e.stopPropagation()})}$WINDOW.on(resizeLocal,that.resize)}else{$DOCUMENT.off(keydownLocal);$WINDOW.off(resizeLocal)}}function appendElements(FLAG){if(FLAG===appendElements.f)return;if(FLAG){$fotorama.addClass(_fotoramaClass+" "+stampClass).before($anchor).before($style);addInstance(that)}else{$anchor.detach();$style.detach();$fotorama.html(fotoramaData.urtext).removeClass(stampClass);hideInstance(that)}bindGlobalEvents(FLAG);appendElements.f=FLAG}function setData(){data=that.data=data||clone(opts.data)||getDataFromHtml($fotorama);size=that.size=data.length;ready.ok&&opts.shuffle&&shuffle(data);checkForVideo();activeIndex=limitIndex(activeIndex);size&&appendElements(true)}function stageNoMove(){var _noMove=size<2||$videoPlaying;stageShaftTouchTail.noMove=_noMove||o_fade;stageShaftTouchTail.noSwipe=_noMove||!opts.swipe;!o_transition&&$stageShaft.toggleClass(grabClass,!opts.click&&!stageShaftTouchTail.noMove&&!stageShaftTouchTail.noSwipe);MS_POINTER&&$wrap.toggleClass(wrapPanYClass,!stageShaftTouchTail.noSwipe)}function setAutoplayInterval(interval){if(interval===true)interval="";opts.autoplay=Math.max(+interval||AUTOPLAY_INTERVAL,o_transitionDuration*1.5)}function updateThumbArrow(opt){if(opt.navarrows&&opt.nav==="thumbs"){$thumbArrLeft.show();$thumbArrRight.show()}else{$thumbArrLeft.hide();$thumbArrRight.hide()}}function getThumbsInSlide($el,opts){return Math.floor($wrap.width()/(opts.thumbwidth+opts.thumbmargin))}function setOptions(){if(!opts.nav||opts.nav==="dots"){opts.navdir="horizontal"}that.options=opts=optionsToLowerCase(opts);thumbsPerSlide=getThumbsInSlide($wrap,opts);o_fade=opts.transition==="crossfade"||opts.transition==="dissolve";o_loop=opts.loop&&(size>2||o_fade&&(!o_transition||o_transition!=="slide"));o_transitionDuration=+opts.transitionduration||TRANSITION_DURATION;o_rtl=opts.direction==="rtl";o_keyboard=$.extend({},opts.keyboard&&KEYBOARD_OPTIONS,opts.keyboard);updateThumbArrow(opts);var classes={add:[],remove:[]};function addOrRemoveClass(FLAG,value){classes[FLAG?"add":"remove"].push(value)}if(size>1){o_nav=opts.nav;o_navTop=opts.navposition==="top";classes.remove.push(selectClass);$arrs.toggle(!!opts.arrows)}else{o_nav=false;$arrs.hide()}arrsUpdate();stageWheelUpdate();thumbArrUpdate();if(opts.autoplay)setAutoplayInterval(opts.autoplay);o_thumbSide=numberFromMeasure(opts.thumbwidth)||THUMB_SIZE;o_thumbSide2=numberFromMeasure(opts.thumbheight)||THUMB_SIZE;stageWheelTail.ok=navWheelTail.ok=opts.trackpad&&!SLOW;stageNoMove();extendMeasures(opts,[measures]);o_navThumbs=o_nav==="thumbs";if($navWrap.filter(":hidden")&&!!o_nav){$navWrap.show()}if(o_navThumbs){frameDraw(size,"navThumb");$navFrame=$navThumbFrame;navFrameKey=NAV_THUMB_FRAME_KEY;setStyle($style,$.Fotorama.jst.style({w:o_thumbSide,h:o_thumbSide2,b:opts.thumbborderwidth,m:opts.thumbmargin,s:stamp,q:!COMPAT}));$nav.addClass(navThumbsClass).removeClass(navDotsClass)}else if(o_nav==="dots"){frameDraw(size,"navDot");$navFrame=$navDotFrame;navFrameKey=NAV_DOT_FRAME_KEY;$nav.addClass(navDotsClass).removeClass(navThumbsClass)}else{$navWrap.hide();o_nav=false;$nav.removeClass(navThumbsClass+" "+navDotsClass)}if(o_nav){if(o_navTop){$navWrap.insertBefore($stage)}else{$navWrap.insertAfter($stage)}frameAppend.nav=false;frameAppend($navFrame,$navShaft,"nav")}o_allowFullScreen=opts.allowfullscreen;if(o_allowFullScreen){$fullscreenIcon.prependTo($stage);o_nativeFullScreen=FULLSCREEN&&o_allowFullScreen==="native";stubEvent($fullscreenIcon,"touchend")}else{$fullscreenIcon.detach();o_nativeFullScreen=false}addOrRemoveClass(o_fade,wrapFadeClass);addOrRemoveClass(!o_fade,wrapSlideClass);addOrRemoveClass(!opts.captions,wrapNoCaptionsClass);addOrRemoveClass(o_rtl,wrapRtlClass);addOrRemoveClass(opts.arrows,wrapToggleArrowsClass);o_shadows=opts.shadows&&!SLOW;addOrRemoveClass(!o_shadows,wrapNoShadowsClass);$wrap.addClass(classes.add.join(" ")).removeClass(classes.remove.join(" "));lastOptions=$.extend({},opts);setStagePosition()}function normalizeIndex(index){return index<0?(size+index%size)%size:index>=size?index%size:index}function limitIndex(index){return minMaxLimit(index,0,size-1)}function edgeIndex(index){return o_loop?normalizeIndex(index):limitIndex(index)}function getPrevIndex(index){return index>0||o_loop?index-1:false}function getNextIndex(index){return index<size-1||o_loop?index+1:false}function setStageShaftMinmaxAndSnap(){stageShaftTouchTail.min=o_loop?-Infinity:-getPosByIndex(size-1,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.max=o_loop?Infinity:-getPosByIndex(0,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.snap=measures.w+opts.margin}function setNavShaftMinMax(){var isVerticalDir=opts.navdir==="vertical";var param=isVerticalDir?$navShaft.height():$navShaft.width();var mainParam=isVerticalDir?measures.h:measures.nw;navShaftTouchTail.min=Math.min(0,mainParam-param);navShaftTouchTail.max=0;navShaftTouchTail.direction=opts.navdir;$navShaft.toggleClass(grabClass,!(navShaftTouchTail.noMove=navShaftTouchTail.min===navShaftTouchTail.max))}function eachIndex(indexes,type,fn){if(typeof indexes==="number"){indexes=new Array(indexes);var rangeFLAG=true}return $.each(indexes,function(i,index){if(rangeFLAG)index=i;if(typeof index==="number"){var dataFrame=data[normalizeIndex(index)];if(dataFrame){var key="$"+type+"Frame",$frame=dataFrame[key];fn.call(this,i,index,dataFrame,$frame,key,$frame&&$frame.data())}}})}function setMeasures(width,height,ratio,index){if(!measuresSetFLAG||measuresSetFLAG==="*"&&index===startIndex){width=measureIsValid(opts.width)||measureIsValid(width)||WIDTH;height=measureIsValid(opts.height)||measureIsValid(height)||HEIGHT;that.resize({width:width,ratio:opts.ratio||ratio||width/height},0,index!==startIndex&&"*")}}function loadImg(indexes,type,specialMeasures,again){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var fullFLAG=that.fullScreen&&!frameData.$full&&type==="stage";if(frameData.$img&&!again&&!fullFLAG)return;var img=new Image,$img=$(img),imgData=$img.data();frameData[fullFLAG?"$full":"$img"]=$img;var srcKey=type==="stage"?fullFLAG?"full":"img":"thumb",src=dataFrame[srcKey],dummy=fullFLAG?dataFrame["img"]:dataFrame[type==="stage"?"thumb":"img"];if(type==="navThumb")$frame=frameData.$wrap;function triggerTriggerEvent(event){var _index=normalizeIndex(index);triggerEvent(event,{index:_index,src:src,frame:data[_index]})}function error(){$img.remove();$.Fotorama.cache[src]="error";if((!dataFrame.html||type!=="stage")&&dummy&&dummy!==src){dataFrame[srcKey]=src=dummy;frameData.$full=null;loadImg([index],type,specialMeasures,true)}else{if(src&&!dataFrame.html&&!fullFLAG){$frame.trigger("f:error").removeClass(loadingClass).addClass(errorClass);triggerTriggerEvent("error")}else if(type==="stage"){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass);triggerTriggerEvent("load");setMeasures()}frameData.state="error";if(size>1&&data[index]===dataFrame&&!dataFrame.html&&!dataFrame.deleted&&!dataFrame.video&&!fullFLAG){dataFrame.deleted=true;that.splice(index,1)}}}function loaded(){$.Fotorama.measures[src]=imgData.measures=$.Fotorama.measures[src]||{width:img.width,height:img.height,ratio:img.width/img.height};setMeasures(imgData.measures.width,imgData.measures.height,imgData.measures.ratio,index);$img.off("load error").addClass(""+(fullFLAG?imgFullClass:imgClass)).attr("aria-hidden","false").prependTo($frame);if($frame.hasClass(stageFrameClass)&&!$frame.hasClass(videoContainerClass)){$frame.attr("href",$img.attr("src"))}fit($img,($.isFunction(specialMeasures)?specialMeasures():specialMeasures)||measures);$.Fotorama.cache[src]=frameData.state="loaded";setTimeout(function(){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass+" "+(fullFLAG?loadedFullClass:loadedImgClass));if(type==="stage"){triggerTriggerEvent("load")}else if(dataFrame.thumbratio===AUTO||!dataFrame.thumbratio&&opts.thumbratio===AUTO){dataFrame.thumbratio=imgData.measures.ratio;reset()}},0)}if(!src){error();return}function waitAndLoad(){var _i=10;waitFor(function(){return!touchedFLAG||!_i--&&!SLOW},function(){loaded()})}if(!$.Fotorama.cache[src]){$.Fotorama.cache[src]="*";$img.on("load",waitAndLoad).on("error",error)}else{(function justWait(){if($.Fotorama.cache[src]==="error"){error()}else if($.Fotorama.cache[src]==="loaded"){setTimeout(waitAndLoad,0)}else{setTimeout(justWait,100)}})()}frameData.state="";img.src=src;if(frameData.data.caption){img.alt=frameData.data.caption||""}if(frameData.data.full){$(img).data("original",frameData.data.full)}if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$(img).attr("aria-labelledby",dataFrame.labelledby)}})}function updateFotoramaState(){var $frame=activeFrame[STAGE_FRAME_KEY];if($frame&&!$frame.data().state){$spinner.addClass(spinnerShowClass);$frame.on("f:load f:error",function(){$frame.off("f:load f:error");$spinner.removeClass(spinnerShowClass)})}}function addNavFrameEvents(frame){addEnterUp(frame,onNavFrameClick);addFocus(frame,function(){setTimeout(function(){lockScroll($nav)},0);slideNavShaft({time:o_transitionDuration,guessIndex:$(this).data().eq,minMax:navShaftTouchTail})})}function frameDraw(indexes,type){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if($frame)return;$frame=dataFrame[key]=$wrap[key].clone();frameData=$frame.data();frameData.data=dataFrame;var frame=$frame[0],labelledbyValue="labelledby"+$.now();if(type==="stage"){if(dataFrame.html){$('<div class="'+htmlClass+'"></div>').append(dataFrame._html?$(dataFrame.html).removeAttr("id").html(dataFrame._html):dataFrame.html).appendTo($frame)}if(dataFrame.id){labelledbyValue=dataFrame.id||labelledbyValue}dataFrame.labelledby=labelledbyValue;if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$($.Fotorama.jst.frameCaption({caption:dataFrame.caption,labelledby:labelledbyValue})).appendTo($frame)}dataFrame.video&&$frame.addClass(stageFrameVideoClass).append($videoPlay.clone());addFocus(frame,function(){setTimeout(function(){lockScroll($stage)},0);clickToShow({index:frameData.eq,user:true})});$stageFrame=$stageFrame.add($frame)}else if(type==="navDot"){addNavFrameEvents(frame);$navDotFrame=$navDotFrame.add($frame)}else if(type==="navThumb"){addNavFrameEvents(frame);frameData.$wrap=$frame.children(":first");$navThumbFrame=$navThumbFrame.add($frame);if(dataFrame.video){frameData.$wrap.append($videoPlay.clone())}}})}function callFit($img,measuresToFit){return $img&&$img.length&&fit($img,measuresToFit)}function stageFramePosition(indexes){eachIndex(indexes,"stage",function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var normalizedIndex=normalizeIndex(index);frameData.eq=normalizedIndex;toDetach[STAGE_FRAME_KEY][normalizedIndex]=$frame.css($.extend({left:o_fade?0:getPosByIndex(index,measures.w,opts.margin,repositionIndex)},o_fade&&getDuration(0)));if(isDetached($frame[0])){$frame.appendTo($stageShaft);unloadVideo(dataFrame.$video)}callFit(frameData.$img,measures);callFit(frameData.$full,measures);if($frame.hasClass(stageFrameClass)&&!($frame.attr("aria-hidden")==="false"&&$frame.hasClass(activeClass))){$frame.attr("aria-hidden","true")}})}function thumbsDraw(pos,loadFLAG){var leftLimit,rightLimit,exceedLimit;if(o_nav!=="thumbs"||isNaN(pos))return;leftLimit=-pos;rightLimit=-pos+measures.nw;if(opts.navdir==="vertical"){pos=pos-opts.thumbheight;rightLimit=-pos+measures.h}$navThumbFrame.each(function(){var $this=$(this),thisData=$this.data(),eq=thisData.eq,getSpecialMeasures=function(){return{h:o_thumbSide2,w:thisData.w}},specialMeasures=getSpecialMeasures(),exceedLimit=opts.navdir==="vertical"?thisData.t>rightLimit:thisData.l>rightLimit;specialMeasures.w=thisData.w;if(thisData.l+thisData.w<leftLimit||exceedLimit||callFit(thisData.$img,specialMeasures))return;loadFLAG&&loadImg([eq],"navThumb",getSpecialMeasures)})}function frameAppend($frames,$shaft,type){if(!frameAppend[type]){var thumbsFLAG=type==="nav"&&o_navThumbs,left=0,top=0;$shaft.append($frames.filter(function(){var actual,$this=$(this),frameData=$this.data();for(var _i=0,_l=data.length;_i<_l;_i++){if(frameData.data===data[_i]){actual=true;frameData.eq=_i;break}}return actual||$this.remove()&&false}).sort(function(a,b){return $(a).data().eq-$(b).data().eq}).each(function(){var $this=$(this),frameData=$this.data();UTIL.setThumbAttr($this,frameData.data.caption,"aria-label")}).each(function(){if(!thumbsFLAG)return;var $this=$(this),frameData=$this.data(),thumbwidth=Math.round(o_thumbSide2*frameData.data.thumbratio)||o_thumbSide,thumbheight=Math.round(o_thumbSide/frameData.data.thumbratio)||o_thumbSide2;frameData.t=top;frameData.h=thumbheight;frameData.l=left;frameData.w=thumbwidth;$this.css({width:thumbwidth});top+=thumbheight+opts.thumbmargin;left+=thumbwidth+opts.thumbmargin}));frameAppend[type]=true}}function getDirection(x){return x-stageLeft>measures.w/3}function disableDirrection(i){return!o_loop&&(!(activeIndex+i)||!(activeIndex-size+i))&&!$videoPlaying}function arrsUpdate(){var disablePrev=disableDirrection(0),disableNext=disableDirrection(1);$arrPrev.toggleClass(arrDisabledClass,disablePrev).attr(disableAttr(disablePrev,false));$arrNext.toggleClass(arrDisabledClass,disableNext).attr(disableAttr(disableNext,false))}function thumbArrUpdate(){var isLeftDisable=false,isRightDisable=false;if(opts.navtype==="thumbs"&&!opts.loop){activeIndex==0?isLeftDisable=true:isLeftDisable=false;activeIndex==opts.data.length-1?isRightDisable=true:isRightDisable=false}if(opts.navtype==="slides"){var pos=readPosition($navShaft,opts.navdir);pos>=navShaftTouchTail.max?isLeftDisable=true:isLeftDisable=false;pos<=navShaftTouchTail.min?isRightDisable=true:isRightDisable=false}$thumbArrLeft.toggleClass(arrDisabledClass,isLeftDisable).attr(disableAttr(isLeftDisable,true));$thumbArrRight.toggleClass(arrDisabledClass,isRightDisable).attr(disableAttr(isRightDisable,true))}function stageWheelUpdate(){if(stageWheelTail.ok){stageWheelTail.prevent={"<":disableDirrection(0),">":disableDirrection(1)}}}function getNavFrameBounds($navFrame){var navFrameData=$navFrame.data(),left,top,width,height;if(o_navThumbs){left=navFrameData.l;top=navFrameData.t;width=navFrameData.w;height=navFrameData.h}else{left=$navFrame.position().left;width=$navFrame.width()}var horizontalBounds={c:left+width/2,min:-left+opts.thumbmargin*10,max:-left+measures.w-width-opts.thumbmargin*10};var verticalBounds={c:top+height/2,min:-top+opts.thumbmargin*10,max:-top+measures.h-height-opts.thumbmargin*10};return opts.navdir==="vertical"?verticalBounds:horizontalBounds}function slideThumbBorder(time){var navFrameData=activeFrame[navFrameKey].data();slide($thumbBorder,{time:time*1.2,pos:opts.navdir==="vertical"?navFrameData.t:navFrameData.l,width:navFrameData.w,height:navFrameData.h,direction:opts.navdir})}function slideNavShaft(options){var $guessNavFrame=data[options.guessIndex][navFrameKey],typeOfAnimation=opts.navtype;var overflowFLAG,time,minMax,boundTop,boundLeft,l,pos,x;if($guessNavFrame){if(typeOfAnimation==="thumbs"){overflowFLAG=navShaftTouchTail.min!==navShaftTouchTail.max;minMax=options.minMax||overflowFLAG&&getNavFrameBounds(activeFrame[navFrameKey]);boundTop=overflowFLAG&&(options.keep&&slideNavShaft.t?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));boundLeft=overflowFLAG&&(options.keep&&slideNavShaft.l?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));l=opts.navdir==="vertical"?boundTop:boundLeft;pos=overflowFLAG&&minMaxLimit(l,navShaftTouchTail.min,navShaftTouchTail.max)||0;time=options.time*1.1;slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));slideNavShaft.l=l}else{x=readPosition($navShaft,opts.navdir);time=options.time*1.11;pos=validateSlidePos(opts,navShaftTouchTail,options.guessIndex,x,$guessNavFrame,$navWrap,opts.navdir);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir))}}}function navUpdate(){deactivateFrames(navFrameKey);toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr("data-active",true))}function deactivateFrames(key){var _toDeactivate=toDeactivate[key];while(_toDeactivate.length){_toDeactivate.shift().removeClass(activeClass).attr("data-active",false)}}function detachFrames(key){var _toDetach=toDetach[key];$.each(activeIndexes,function(i,index){delete _toDetach[normalizeIndex(index)]});$.each(_toDetach,function(index,$frame){delete _toDetach[index];$frame.detach()})}function stageShaftReposition(skipOnEnd){repositionIndex=dirtyIndex=activeIndex;var $frame=activeFrame[STAGE_FRAME_KEY];if($frame){deactivateFrames(STAGE_FRAME_KEY);toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr("data-active",true));if($frame.hasClass(stageFrameClass)){$frame.attr("aria-hidden","false")}skipOnEnd||that.showStage.onEnd(true);stop($stageShaft,0,true);detachFrames(STAGE_FRAME_KEY);stageFramePosition(activeIndexes);setStageShaftMinmaxAndSnap();setNavShaftMinMax();addEnterUp($stageShaft[0],function(){if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen();$fullscreenIcon.focus()}})}}function extendMeasures(options,measuresArray){if(!options)return;$.each(measuresArray,function(i,measures){if(!measures)return;$.extend(measures,{width:options.width||measures.width,height:options.height,minwidth:options.minwidth,maxwidth:options.maxwidth,minheight:options.minheight,maxheight:options.maxheight,ratio:getRatio(options.ratio)})})}function triggerEvent(event,extra){$fotorama.trigger(_fotoramaClass+":"+event,[that,extra])}function onTouchStart(){clearTimeout(onTouchEnd.t);touchedFLAG=1;if(opts.stopautoplayontouch){that.stopAutoplay()}else{pausedAutoplayFLAG=true}}function onTouchEnd(){if(!touchedFLAG)return;if(!opts.stopautoplayontouch){releaseAutoplay();changeAutoplay()}onTouchEnd.t=setTimeout(function(){touchedFLAG=0},TRANSITION_DURATION+TOUCH_TIMEOUT)}function releaseAutoplay(){pausedAutoplayFLAG=!!($videoPlaying||stoppedAutoplayFLAG)}function changeAutoplay(){clearTimeout(changeAutoplay.t);waitFor.stop(changeAutoplay.w);if(!opts.autoplay||pausedAutoplayFLAG){if(that.autoplay){that.autoplay=false;triggerEvent("stopautoplay")}return}if(!that.autoplay){that.autoplay=true;triggerEvent("startautoplay")}var _activeIndex=activeIndex;var frameData=activeFrame[STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return frameData.state||_activeIndex!==activeIndex},function(){changeAutoplay.t=setTimeout(function(){if(pausedAutoplayFLAG||_activeIndex!==activeIndex)return;var _nextAutoplayIndex=nextAutoplayIndex,nextFrameData=data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return nextFrameData.state||_nextAutoplayIndex!==nextAutoplayIndex},function(){if(pausedAutoplayFLAG||_nextAutoplayIndex!==nextAutoplayIndex)return;that.show(o_loop?getDirectionSign(!o_rtl):nextAutoplayIndex)})},opts.autoplay)})}that.startAutoplay=function(interval){if(that.autoplay)return this;pausedAutoplayFLAG=stoppedAutoplayFLAG=false;setAutoplayInterval(interval||opts.autoplay);changeAutoplay();return this};that.stopAutoplay=function(){if(that.autoplay){pausedAutoplayFLAG=stoppedAutoplayFLAG=true;changeAutoplay()}return this};that.showSlide=function(slideDir){var currentPosition=readPosition($navShaft,opts.navdir),pos,time=500*1.1,size=opts.navdir==="horizontal"?opts.thumbwidth:opts.thumbheight,onEnd=function(){thumbArrUpdate()};if(slideDir==="next"){pos=currentPosition-(size+opts.margin)*thumbsPerSlide}if(slideDir==="prev"){pos=currentPosition+(size+opts.margin)*thumbsPerSlide}pos=validateRestrictions(pos,navShaftTouchTail);thumbsDraw(pos,true);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:onEnd})};that.showWhileLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showNav(silent,options,time);return this};that.showEndLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;return this};function calcActiveIndex(options){var index;if(typeof options!=="object"){index=options;options={}}else{index=options.index}index=index===">"?dirtyIndex+1:index==="<"?dirtyIndex-1:index==="<<"?0:index===">>"?size-1:index;index=isNaN(index)?undefined:index;index=typeof index==="undefined"?activeIndex||0:index;return index}function calcGlobalIndexes(index){that.activeIndex=activeIndex=edgeIndex(index);prevIndex=getPrevIndex(activeIndex);nextIndex=getNextIndex(activeIndex);nextAutoplayIndex=normalizeIndex(activeIndex+(o_rtl?-1:1));activeIndexes=[activeIndex,prevIndex,nextIndex];dirtyIndex=o_loop?index:activeIndex}function calcTime(options){var diffIndex=Math.abs(lastActiveIndex-dirtyIndex),time=getNumber(options.time,function(){return Math.min(o_transitionDuration*(1+(diffIndex-1)/12),o_transitionDuration*2)});if(options.slow){time*=10}return time}that.showStage=function(silent,options,time){unloadVideo($videoPlaying,activeFrame.i!==data[normalizeIndex(repositionIndex)].i);frameDraw(activeIndexes,"stage");stageFramePosition(SLOW?[dirtyIndex]:[dirtyIndex,getPrevIndex(dirtyIndex),getNextIndex(dirtyIndex)]);updateTouchTails("go",true);silent||triggerEvent("show",{user:options.user,time:time});pausedAutoplayFLAG=true;var overPos=options.overPos;var onEnd=that.showStage.onEnd=function(skipReposition){if(onEnd.ok)return;onEnd.ok=true;skipReposition||stageShaftReposition(true);if(!silent){triggerEvent("showend",{user:options.user})}if(!skipReposition&&o_transition&&o_transition!==opts.transition){that.setOptions({transition:o_transition});o_transition=false;return}updateFotoramaState();loadImg(activeIndexes,"stage");updateTouchTails("go",false);stageWheelUpdate();stageCursor();releaseAutoplay();changeAutoplay();if(that.fullScreen){activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",false);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",true)}else{activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",true);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",false)}};if(!o_fade){slide($stageShaft,{pos:-getPosByIndex(dirtyIndex,measures.w,opts.margin,repositionIndex),overPos:overPos,time:time,onEnd:onEnd})}else{var $activeFrame=activeFrame[STAGE_FRAME_KEY],$prevActiveFrame=data[lastActiveIndex]&&activeIndex!==lastActiveIndex?data[lastActiveIndex][STAGE_FRAME_KEY]:null;fade($activeFrame,$prevActiveFrame,$stageFrame,{time:time,method:opts.transition,onEnd:onEnd},fadeStack)}arrsUpdate()};that.showNav=function(silent,options,time){thumbArrUpdate();if(o_nav){navUpdate();var guessIndex=limitIndex(activeIndex+minMaxLimit(dirtyIndex-lastActiveIndex,-1,1));slideNavShaft({time:time,coo:guessIndex!==activeIndex&&options.coo,guessIndex:typeof options.coo!=="undefined"?guessIndex:activeIndex,keep:silent});if(o_navThumbs)slideThumbBorder(time)}};that.show=function(options){that.longPress.singlePressInProgress=true;var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options);var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);that.showNav(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;that.longPress.singlePressInProgress=false;return this};that.requestFullScreen=function(){if(o_allowFullScreen&&!that.fullScreen){var isVideo=$((that.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(isVideo){return}scrollTop=$WINDOW.scrollTop();scrollLeft=$WINDOW.scrollLeft();lockScroll($WINDOW);updateTouchTails("x",true);measuresStash=$.extend({},measures);$fotorama.addClass(fullscreenClass).appendTo($BODY.addClass(_fullscreenClass));$HTML.addClass(_fullscreenClass);unloadVideo($videoPlaying,true,true);that.fullScreen=true;if(o_nativeFullScreen){fullScreenApi.request(fotorama)}that.resize();loadImg(activeIndexes,"stage");updateFotoramaState();triggerEvent("fullscreenenter");if(!("ontouchstart"in window)){$fullscreenIcon.focus()}}return this};function cancelFullScreen(){if(that.fullScreen){that.fullScreen=false;if(FULLSCREEN){fullScreenApi.cancel(fotorama)}$BODY.removeClass(_fullscreenClass);$HTML.removeClass(_fullscreenClass);$fotorama.removeClass(fullscreenClass).insertAfter($anchor);measures=$.extend({},measuresStash);unloadVideo($videoPlaying,true,true);updateTouchTails("x",false);that.resize();loadImg(activeIndexes,"stage");lockScroll($WINDOW,scrollLeft,scrollTop);triggerEvent("fullscreenexit")}}that.cancelFullScreen=function(){if(o_nativeFullScreen&&fullScreenApi.is()){fullScreenApi.cancel(document)}else{cancelFullScreen()}return this};that.toggleFullScreen=function(){return that[(that.fullScreen?"cancel":"request")+"FullScreen"]()};that.resize=function(options){if(!data)return this;var time=arguments[1]||0,setFLAG=arguments[2];thumbsPerSlide=getThumbsInSlide($wrap,opts);extendMeasures(!that.fullScreen?optionsToLowerCase(options):{width:$(window).width(),maxwidth:null,minwidth:null,height:$(window).height(),maxheight:null,minheight:null},[measures,setFLAG||that.fullScreen||opts]);var width=measures.width,height=measures.height,ratio=measures.ratio,windowHeight=$WINDOW.height()-(o_nav?$nav.height():0);if(measureIsValid(width)){$wrap.css({width:""});$wrap.css({height:""});$stage.css({width:""});$stage.css({height:""});$stageShaft.css({width:""});$stageShaft.css({height:""});$nav.css({width:""});$nav.css({height:""});$wrap.css({minWidth:measures.minwidth||0,maxWidth:measures.maxwidth||MAX_WIDTH});if(o_nav==="dots"){$navWrap.hide()}width=measures.W=measures.w=$wrap.width();measures.nw=o_nav&&numberFromWhatever(opts.navwidth,width)||width;$stageShaft.css({width:measures.w,marginLeft:(measures.W-measures.w)/2});height=numberFromWhatever(height,windowHeight);height=height||ratio&&width/ratio;if(height){width=Math.round(width);height=measures.h=Math.round(minMaxLimit(height,numberFromWhatever(measures.minheight,windowHeight),numberFromWhatever(measures.maxheight,windowHeight)));$stage.css({width:width,height:height});if(opts.navdir==="vertical"&&!that.fullscreen){$nav.width(opts.thumbwidth+opts.thumbmargin*2)}if(opts.navdir==="horizontal"&&!that.fullscreen){$nav.height(opts.thumbheight+opts.thumbmargin*2)}if(o_nav==="dots"){$nav.width(width).height("auto");$navWrap.show()}if(opts.navdir==="vertical"&&that.fullScreen){$stage.css("height",$WINDOW.height())}if(opts.navdir==="horizontal"&&that.fullScreen){$stage.css("height",$WINDOW.height()-$nav.height())}if(o_nav){switch(opts.navdir){case"vertical":$navWrap.removeClass(navShafthorizontalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShaftVerticalClass);$nav.stop().animate({height:measures.h,width:opts.thumbwidth},time);break;case"list":$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShafthorizontalClass);$navWrap.addClass(navShaftListClass);break;default:$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShafthorizontalClass);$nav.stop().animate({width:measures.nw},time);break}stageShaftReposition();slideNavShaft({guessIndex:activeIndex,time:time,keep:true});if(o_navThumbs&&frameAppend.nav)slideThumbBorder(time)}measuresSetFLAG=setFLAG||true;ready.ok=true;ready()}}stageLeft=$stage.offset().left;setStagePosition();return this};that.setOptions=function(options){$.extend(opts,options);reset();return this};that.shuffle=function(){data&&shuffle(data)&&reset();return this};function setShadow($el,edge){if(o_shadows){$el.removeClass(shadowsLeftClass+" "+shadowsRightClass);$el.removeClass(shadowsTopClass+" "+shadowsBottomClass);edge&&!$videoPlaying&&$el.addClass(edge.replace(/^|\s/g," "+shadowsClass+"--"))}}that.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){if(!this.inProgress){this.count++;this.inProgress=this.count>this.threshold}},end:function(){if(this.inProgress){this.isEnded=true}},reset:function(){this.count=0;this.inProgress=false;this.isEnded=false}};that.destroy=function(){that.cancelFullScreen();that.stopAutoplay();data=that.data=null;appendElements();activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=false;return this};that.playVideo=function(){var dataFrame=activeFrame,video=dataFrame.video,_activeIndex=activeIndex;if(typeof video==="object"&&dataFrame.videoReady){o_nativeFullScreen&&that.fullScreen&&that.cancelFullScreen();waitFor(function(){return!fullScreenApi.is()||_activeIndex!==activeIndex},function(){if(_activeIndex===activeIndex){dataFrame.$video=dataFrame.$video||$(div(videoClass)).append(createVideoFrame(video));dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);$wrap.addClass(wrapVideoClass);$videoPlaying=dataFrame.$video;stageNoMove();$arrs.blur();$fullscreenIcon.blur();triggerEvent("loadvideo")}})}return this};that.stopVideo=function(){unloadVideo($videoPlaying,true,true);return this};that.spliceByIndex=function(index,newImgObj){newImgObj.i=index+1;newImgObj.img&&$.ajax({url:newImgObj.img,type:"HEAD",success:function(){data.splice(index,1,newImgObj);reset()}})};function unloadVideo($video,unloadActiveFLAG,releaseAutoplayFLAG){if(unloadActiveFLAG){$wrap.removeClass(wrapVideoClass);$videoPlaying=false;stageNoMove()}if($video&&$video!==$videoPlaying){$video.remove();triggerEvent("unloadvideo")}if(releaseAutoplayFLAG){releaseAutoplay();changeAutoplay()}}function toggleControlsClass(FLAG){$wrap.toggleClass(wrapNoControlsClass,FLAG)}function stageCursor(e){if(stageShaftTouchTail.flow)return;var x=e?e.pageX:stageCursor.x,pointerFLAG=x&&!disableDirrection(getDirection(x))&&opts.click;if(stageCursor.p!==pointerFLAG&&$stage.toggleClass(pointerClass,pointerFLAG)){stageCursor.p=pointerFLAG;stageCursor.x=x}}$stage.on("mousemove",stageCursor);function clickToShow(showOptions){clearTimeout(clickToShow.t);if(opts.clicktransition&&opts.clicktransition!==opts.transition){setTimeout(function(){var _o_transition=opts.transition;that.setOptions({transition:opts.clicktransition});o_transition=_o_transition;clickToShow.t=setTimeout(function(){that.show(showOptions)},10)},0)}else{that.show(showOptions)}}function onStageTap(e,toggleControlsFLAG){var target=e.target,$target=$(target);if($target.hasClass(videoPlayClass)){that.playVideo()}else if(target===fullscreenIcon){that.toggleFullScreen()}else if($videoPlaying){target===videoClose&&unloadVideo($videoPlaying,true,true)}else if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen()}}function updateTouchTails(key,value){stageShaftTouchTail[key]=navShaftTouchTail[key]=value}stageShaftTouchTail=moveOnTouch($stageShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($stage,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){var toggleControlsFLAG;setShadow($stage);toggleControlsFLAG=(MS_POINTER&&!hoverFLAG||result.touch)&&opts.arrows;if((result.moved||toggleControlsFLAG&&result.pos!==result.newPos&&!result.control)&&result.$target[0]!==$fullscreenIcon[0]){var index=getIndexByPos(result.newPos,measures.w,opts.margin,repositionIndex);that.show({index:index,time:o_fade?o_transitionDuration:result.time,overPos:result.overPos,user:true})}else if(!result.aborted&&!result.control){onStageTap(result.startEvent,toggleControlsFLAG)}},timeLow:1,timeHigh:1,friction:2,select:"."+selectClass+", ."+selectClass+" *",$wrap:$stage,direction:"horizontal"});navShaftTouchTail=moveOnTouch($navShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($nav,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){function onEnd(){slideNavShaft.l=result.newPos;releaseAutoplay();changeAutoplay();thumbsDraw(result.newPos,true);thumbArrUpdate()}if(!result.moved){var target=result.$target.closest("."+navFrameClass,$navShaft)[0];target&&onNavFrameClick.call(target,result.startEvent)}else if(result.pos!==result.newPos){pausedAutoplayFLAG=true;slide($navShaft,{time:result.time,pos:result.newPos,overPos:result.overPos,direction:opts.navdir,onEnd:onEnd});thumbsDraw(result.newPos);o_shadows&&setShadow($nav,findShadowEdge(result.newPos,navShaftTouchTail.min,navShaftTouchTail.max,result.dir))}else{onEnd()}},timeLow:.5,timeHigh:2,friction:5,$wrap:$nav,direction:opts.navdir});stageWheelTail=wheel($stage,{shift:true,onEnd:function(e,direction){onTouchStart();onTouchEnd();that.show({index:direction,slow:e.altKey})}});navWheelTail=wheel($nav,{onEnd:function(e,direction){onTouchStart();onTouchEnd();var newPos=stop($navShaft)+direction*.25;$navShaft.css(getTranslate(minMaxLimit(newPos,navShaftTouchTail.min,navShaftTouchTail.max),opts.navdir));o_shadows&&setShadow($nav,findShadowEdge(newPos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));navWheelTail.prevent={"<":newPos>=navShaftTouchTail.max,">":newPos<=navShaftTouchTail.min};clearTimeout(navWheelTail.t);navWheelTail.t=setTimeout(function(){slideNavShaft.l=newPos;thumbsDraw(newPos,true)},TOUCH_TIMEOUT);thumbsDraw(newPos)}});$wrap.hover(function(){setTimeout(function(){if(touchedFLAG)return;toggleControlsClass(!(hoverFLAG=true))},0)},function(){if(!hoverFLAG)return;toggleControlsClass(!(hoverFLAG=false))});function onNavFrameClick(e){var index=$(this).data().eq;if(opts.navtype==="thumbs"){clickToShow({index:index,slow:e.altKey,user:true,coo:e._x-$nav.offset().left})}else{clickToShow({index:index,slow:e.altKey,user:true})}}function onArrClick(e){clickToShow({index:$arrs.index(this)?">":"<",slow:e.altKey,user:true})}smartClick($arrs,function(e){stopEvent(e);onArrClick.call(this,e)},{onStart:function(){onTouchStart();stageShaftTouchTail.control=true},onTouchEnd:onTouchEnd});smartClick($thumbArrLeft,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show("<")}else{that.showSlide("prev")}});smartClick($thumbArrRight,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show(">")}else{that.showSlide("next")}});function addFocusOnControls(el){addFocus(el,function(){setTimeout(function(){lockScroll($stage)},0);toggleControlsClass(false)})}$arrs.each(function(){addEnterUp(this,function(e){onArrClick.call(this,e)});addFocusOnControls(this)});addEnterUp(fullscreenIcon,function(){if($fotorama.hasClass(fullscreenClass)){that.cancelFullScreen();$stageShaft.focus()}else{that.requestFullScreen();$fullscreenIcon.focus()}});addFocusOnControls(fullscreenIcon);function reset(){setData();setOptions();if(!reset.i){reset.i=true;var _startindex=opts.startindex;activeIndex=repositionIndex=dirtyIndex=lastActiveIndex=startIndex=edgeIndex(_startindex)||0}if(size){if(changeToRtl())return;if($videoPlaying){unloadVideo($videoPlaying,true)}activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=true;that.show({index:activeIndex,time:0});that.resize()}else{that.destroy()}}function changeToRtl(){if(!changeToRtl.f===o_rtl){changeToRtl.f=o_rtl;activeIndex=size-1-activeIndex;that.reverse();return true}}$.each("load push pop shift unshift reverse sort splice".split(" "),function(i,method){that[method]=function(){data=data||[];if(method!=="load"){Array.prototype[method].apply(data,arguments)}else if(arguments[0]&&typeof arguments[0]==="object"&&arguments[0].length){data=clone(arguments[0])}reset();return that}});function ready(){if(ready.ok){ready.ok=false;triggerEvent("ready")}}reset()};$.fn.fotorama=function(opts){return this.each(function(){var that=this,$fotorama=$(this),fotoramaData=$fotorama.data(),fotorama=fotoramaData.fotorama;if(!fotorama){waitFor(function(){return!isHidden(that)},function(){fotoramaData.urtext=$fotorama.html();new $.Fotorama($fotorama,$.extend({},OPTIONS,window.fotoramaDefaults,opts,fotoramaData))})}else{fotorama.setOptions(opts,true)}})};$.Fotorama.instances=[];function calculateIndexes(){$.each($.Fotorama.instances,function(index,instance){instance.index=index})}function addInstance(instance){$.Fotorama.instances.push(instance);calculateIndexes()}function hideInstance(instance){$.Fotorama.instances.splice(instance.index,1);calculateIndexes()}$.Fotorama.cache={};$.Fotorama.measures={};$=$||{};$.Fotorama=$.Fotorama||{};$.Fotorama.jst=$.Fotorama.jst||{};$.Fotorama.jst.dots=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__dot"></div>\r\n</div>';return __p};$.Fotorama.jst.frameCaption=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__caption" aria-hidden="true">\r\n <div class="fotorama__caption__wrap" id="'+((__t=v.labelledby)==null?"":__t)+'">'+((__t=v.caption)==null?"":__t)+"</div>\r\n</div>\r\n";return __p};$.Fotorama.jst.style=function(v){var __t,__p="",__e=_.escape;__p+=".fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+((__t=v.m)==null?"":__t)+"px;\r\nheight:"+((__t=v.h)==null?"":__t)+"px}\r\n.fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__thumb-border{\r\nheight:"+((__t=v.h)==null?"":__t)+"px;\r\nborder-width:"+((__t=v.b)==null?"":__t)+"px;\r\nmargin-top:"+((__t=v.m)==null?"":__t)+"px}";return __p};$.Fotorama.jst.thumb=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__thumb">\r\n </div>\r\n</div>';return __p}})(window,document,location,typeof jQuery!=="undefined"&&jQuery); From 8f9a7cdec76e1225e4c46d101d5643d742bf757c Mon Sep 17 00:00:00 2001 From: Stjepan Udovicic <stjepan.udovicic@inchoo.net> Date: Sun, 14 Oct 2018 21:17:28 +0200 Subject: [PATCH 0573/1415] Ensure integer values are not quoted as strings --- .../ProductCategoryCondition.php | 2 +- .../Magento/Catalog/Model/ProductCategoryList.php | 6 +++++- .../Model/ResourceModel/Product/Collection.php | 15 ++++++++++----- lib/internal/Magento/Framework/Mview/View.php | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php index f70bab73d0830..d37f97c38a4f6 100644 --- a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php @@ -104,7 +104,7 @@ private function getCategoryIds(Filter $filter): array } } - return array_unique(array_merge($categoryIds, ...$childCategoryIds)); + return array_map('intval', array_unique(array_merge($categoryIds, ...$childCategoryIds))); } /** diff --git a/app/code/Magento/Catalog/Model/ProductCategoryList.php b/app/code/Magento/Catalog/Model/ProductCategoryList.php index 5bbae772d5c2b..c8b075ffb494e 100644 --- a/app/code/Magento/Catalog/Model/ProductCategoryList.php +++ b/app/code/Magento/Catalog/Model/ProductCategoryList.php @@ -80,7 +80,11 @@ public function getCategoryIds($productId) Select::SQL_UNION_ALL ); - $this->categoryIdList[$productId] = $this->productResource->getConnection()->fetchCol($unionSelect); + $this->categoryIdList[$productId] = array_map( + 'intval', + $this->productResource->getConnection()->fetchCol($unionSelect) + ); + } return $this->categoryIdList[$productId]; diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 0d62d120f80e0..5afac59b25db6 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1809,7 +1809,8 @@ protected function _productLimitationJoinWebsite() } $conditions[] = $this->getConnection()->quoteInto( 'product_website.website_id IN(?)', - $filters['website_ids'] + $filters['website_ids'], + 'int' ); } elseif (isset( $filters['store_id'] @@ -1821,7 +1822,7 @@ protected function _productLimitationJoinWebsite() ) { $joinWebsite = true; $websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId(); - $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId); + $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId, 'int'); } $fromPart = $this->getSelect()->getPart(\Magento\Framework\DB\Select::FROM); @@ -2017,12 +2018,16 @@ protected function _applyProductLimitations() $conditions = [ 'cat_index.product_id=e.entity_id', - $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id']), + $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id'], 'int'), ]; if (isset($filters['visibility']) && !isset($filters['store_table'])) { - $conditions[] = $this->getConnection()->quoteInto('cat_index.visibility IN(?)', $filters['visibility']); + $conditions[] = $this->getConnection()->quoteInto( + 'cat_index.visibility IN(?)', + $filters['visibility'], + 'int' + ); } - $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id=?', $filters['category_id']); + $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id=?', $filters['category_id'], 'int'); if (isset($filters['category_is_anchor'])) { $conditions[] = $this->getConnection()->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']); } diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index a937c62dfc23a..589034886010f 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -283,7 +283,7 @@ public function update() for ($vsFrom = $lastVersionId; $vsFrom < $currentVersionId; $vsFrom += $versionBatchSize) { // Don't go past the current version for atomicy. $versionTo = min($currentVersionId, $vsFrom + $versionBatchSize); - $ids = $this->getChangelog()->getList($vsFrom, $versionTo); + $ids = array_map('intval', $this->getChangelog()->getList($vsFrom, $versionTo)); // We run the actual indexer in batches. // Chunked AFTER loading to avoid duplicates in separate chunks. From 44e89c730a48552eaa170a858486abfb601fd4b5 Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Mon, 15 Oct 2018 09:58:11 +0200 Subject: [PATCH 0574/1415] Added check if array when validating request data --- .../Magento/Braintree/Controller/Paypal/Review.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index ca252aabe54a9..98a33b52f98eb 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -91,11 +91,15 @@ public function execute() } /** - * @param array $requestData - * @return boolean + * @param $requestData + * @return bool */ - private function validateRequestData(array $requestData) + private function validateRequestData($requestData) { - return !empty($requestData['nonce']) && !empty($requestData['details']); + if (is_array($requestData)) { + return !empty($requestData['nonce']) && !empty($requestData['details']); + } else { + return false; + } } } From 43cb06482fe187642722c486c4232edc10bd84ee Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Mon, 15 Oct 2018 11:46:04 +0200 Subject: [PATCH 0575/1415] Simplified validateRequestData to work without an else expression --- app/code/Magento/Braintree/Controller/Paypal/Review.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index 98a33b52f98eb..964b0bde135ae 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -98,8 +98,7 @@ private function validateRequestData($requestData) { if (is_array($requestData)) { return !empty($requestData['nonce']) && !empty($requestData['details']); - } else { - return false; } + return false; } } From 3f9784e3ee8c4b1f1e9df0a47ad91a6e4628024b Mon Sep 17 00:00:00 2001 From: Ian <i.cassidy@ctidigital.com> Date: Mon, 15 Oct 2018 13:38:33 +0100 Subject: [PATCH 0576/1415] 18615 updates structure for last_trans_id to be varchar 255 which is inline with klarna_core_order order_id and amazon_sales_order amazon_order_reference_id. Limit was 32 characters where as a klarna_order reference is 36 characters at present --- app/code/Magento/Sales/etc/db_schema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml index fda6e75cf00c6..452247e545144 100644 --- a/app/code/Magento/Sales/etc/db_schema.xml +++ b/app/code/Magento/Sales/etc/db_schema.xml @@ -663,7 +663,7 @@ <column xsi:type="varchar" name="cc_ss_start_month" nullable="true" length="128" comment="Cc Ss Start Month"/> <column xsi:type="varchar" name="echeck_account_type" nullable="true" length="255" comment="Echeck Account Type"/> - <column xsi:type="varchar" name="last_trans_id" nullable="true" length="32" comment="Last Trans Id"/> + <column xsi:type="varchar" name="last_trans_id" nullable="true" length="255" comment="Last Trans Id"/> <column xsi:type="varchar" name="cc_cid_status" nullable="true" length="32" comment="Cc Cid Status"/> <column xsi:type="varchar" name="cc_owner" nullable="true" length="128" comment="Cc Owner"/> <column xsi:type="varchar" name="cc_type" nullable="true" length="32" comment="Cc Type"/> From cda6aa1bce161845ab03e376ceb03abff90e06a8 Mon Sep 17 00:00:00 2001 From: Zachary Craig <zack@zack6849.com> Date: Mon, 15 Oct 2018 08:57:49 -0400 Subject: [PATCH 0577/1415] Change documentation formatting per @rodrigowebjump --- app/code/Magento/Sales/Api/Data/OrderInterface.php | 2 +- app/code/Magento/Sales/Api/Data/OrderItemInterface.php | 2 +- app/code/Magento/Sales/Model/Order.php | 2 +- app/code/Magento/Sales/Model/Order/Item.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php index e689738fb019b..bdf8cfe5416dd 100644 --- a/app/code/Magento/Sales/Api/Data/OrderInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php @@ -580,8 +580,8 @@ public function getAdjustmentPositive(); /** * Gets the applied rule IDs for the order. - * Rules are comma separated if there are more than one. * + * Rules are comma separated if there are more than one. * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php index fb81fea90053f..4aabd05a0efcc 100644 --- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php @@ -414,8 +414,8 @@ public function getAmountRefunded(); /** * Gets the applied rule IDs for the order item. - * Rules are comma separated if there are more than one. * + * Rules are comma separated if there are more than one. * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index e6605a67a1231..137c8b440813d 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -2112,8 +2112,8 @@ public function getAdjustmentPositive() /** * Returns applied_rule_ids - * Rules are comma separated if there are more than one. * + * Rules are comma separated if there are more than one. * @return string|null */ public function getAppliedRuleIds() diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index 02ba396601c82..1d821ad041e72 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -724,8 +724,8 @@ public function getAmountRefunded() /** * Returns applied_rule_ids - * Rules are comma separated if there are more than one. * + * Rules are comma separated if there are more than one. * @return string|null */ public function getAppliedRuleIds() From 42ecb9c78de2ebb4c1c475b2ef2e286faded0b5f Mon Sep 17 00:00:00 2001 From: Lewis Voncken <lewis@experius.nl> Date: Mon, 15 Oct 2018 15:47:35 +0200 Subject: [PATCH 0578/1415] [BUGFIX] [issue-10205] Always set the entity_type_id for updating product attributes because the route contains the specification products/attributes --- .../Catalog/Model/Product/Attribute/Repository.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index f6d3ca36c1e1e..48ca12321a250 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -106,6 +106,11 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr */ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute) { + $attribute->setEntityTypeId( + $this->eavConfig + ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE) + ->getId() + ); if ($attribute->getAttributeId()) { $existingModel = $this->get($attribute->getAttributeCode()); @@ -144,11 +149,6 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib $attribute->setBackendModel( $this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput()) ); - $attribute->setEntityTypeId( - $this->eavConfig - ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE) - ->getId() - ); $attribute->setIsUserDefined(1); } if (!empty($attribute->getData(AttributeInterface::OPTIONS))) { From 3b1c5a8152e00fc89948b0a9727cde542eda8ffc Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 12 Oct 2018 14:27:24 -0500 Subject: [PATCH 0579/1415] MAGETWO-95549: Adding restriction for controller --- .../Adminhtml/Wysiwyg/Images/DeleteFiles.php | 5 ++-- .../Wysiwyg/Images/DeleteFilesTest.php | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php index 890c9bf5eae52..6f57efad41e75 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php @@ -6,11 +6,12 @@ namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Delete image files. */ -class DeleteFiles extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images +class DeleteFiles extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images implements HttpPostActionInterface { /** * @var \Magento\Framework\Controller\Result\JsonFactory @@ -79,7 +80,7 @@ public function execute() $filesystem = $this->_objectManager->get(\Magento\Framework\Filesystem::class); $dir = $filesystem->getDirectoryRead(DirectoryList::MEDIA); $filePath = $path . '/' . \Magento\Framework\File\Uploader::getCorrectFileName($file); - if ($dir->isFile($dir->getRelativePath($filePath))) { + if ($dir->isFile($dir->getRelativePath($filePath)) && !preg_match('#.htaccess#', $file)) { $this->getStorage()->deleteFile($filePath); } } 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 fa49a7b1f57e1..1fc07d32c77b9 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 @@ -64,6 +64,10 @@ protected function setUp() $filePath = $this->fullDirectoryPath . DIRECTORY_SEPARATOR . $this->fileName; $fixtureDir = realpath(__DIR__ . '/../../../../../Catalog/_files'); copy($fixtureDir . '/' . $this->fileName, $filePath); + $path = $this->fullDirectoryPath . '/.htaccess'; + if (!$this->mediaDirectory->isFile($path)) { + $this->mediaDirectory->writeFile($path, "Order deny,allow\nDeny from all"); + } $this->model = $this->objectManager->get(\Magento\Cms\Controller\Adminhtml\Wysiwyg\Images\DeleteFiles::class); } @@ -87,6 +91,26 @@ public function testExecute() ); } + /** + * Check that htaccess file couldn't be removed via + * \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images\DeleteFiles::execute method + * + * @return void + */ + public function testDeleteHtaccess() + { + $this->model->getRequest()->setMethod('POST') + ->setPostValue('files', [$this->imagesHelper->idEncode('.htaccess')]); + $this->model->getStorage()->getSession()->setCurrentPath($this->fullDirectoryPath); + $this->model->execute(); + + $this->assertTrue( + $this->mediaDirectory->isExist( + $this->mediaDirectory->getRelativePath($this->fullDirectoryPath . '/' . '.htaccess') + ) + ); + } + /** * Execute method with traversal file path to check that there is no ability to remove file which is not * under media directory. From 75cb72f775869c7ffcca12deb20b917eb7bf74b9 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 15 Oct 2018 09:45:05 -0500 Subject: [PATCH 0580/1415] MAGETWO-95234: Change regular expression --- lib/internal/Magento/Framework/Escaper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 603c2b395462f..2fdf17fd2337c 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -373,7 +373,7 @@ private function getLogger() /** * Filter prohibited tags. * - * @param array $allowedTags + * @param string[] $allowedTags * @return array */ private function filterProhibitedTags(array $allowedTags): array From 4f469a06bd217cdee87eeff33d7a3462e2750b80 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 15 Oct 2018 09:49:59 -0500 Subject: [PATCH 0581/1415] MAGETWO-95234: Change regular expression --- lib/internal/Magento/Framework/Escaper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 2fdf17fd2337c..80979c3db0910 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -374,7 +374,7 @@ private function getLogger() * Filter prohibited tags. * * @param string[] $allowedTags - * @return array + * @return string[] */ private function filterProhibitedTags(array $allowedTags): array { From f5b59b8bb89ee6c7440d1ea60d7ae68387445e5d Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 15 Oct 2018 10:13:50 -0500 Subject: [PATCH 0582/1415] MAGETWO-95642: Import error --- .../Test/Unit/Model/Entity/AttributeTest.php | 4 +++ .../ImportExport/Model/Import/Source/Zip.php | 7 ++++ .../Test/Unit/Model/ProblemTest.php | 28 ++++++++++++++++ .../Magento/Framework/Archive/Zip.php | 33 ++++++++++++++----- 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/AttributeTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/AttributeTest.php index b15174960524c..402497a1379c0 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Entity/AttributeTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/AttributeTest.php @@ -5,6 +5,9 @@ */ namespace Magento\Eav\Test\Unit\Model\Entity; +/** + * Class AttributeTest. + */ class AttributeTest extends \PHPUnit\Framework\TestCase { /** @@ -128,6 +131,7 @@ public function testGetFrontendLabels() $attributeId = 1; $storeLabels = ['test_attribute_store1']; $frontendLabelFactory = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\FrontendLabelFactory::class) + ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); $resource = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute::class) diff --git a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php index b7fafc43ca4ed..7c13e47957cda 100644 --- a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php +++ b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php @@ -5,6 +5,8 @@ */ namespace Magento\ImportExport\Model\Import\Source; +use Magento\Framework\Exception\ValidatorException; + /** * Zip import adapter. */ @@ -14,6 +16,8 @@ class Zip extends Csv * @param string $file * @param \Magento\Framework\Filesystem\Directory\Write $directory * @param string $options + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\ValidatorException */ public function __construct( $file, @@ -25,6 +29,9 @@ public function __construct( $directory->getRelativePath($file), $directory->getRelativePath(preg_replace('/\.zip$/i', '.csv', $file)) ); + if (!$file) { + throw new ValidatorException(__('Sorry, but the data is invalid or the file is not uploaded.')); + } parent::__construct($file, $directory, $options); } } diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php index 889fc11d71d7e..8ee6de1e44476 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php @@ -17,6 +17,9 @@ use Magento\Newsletter\Model\Subscriber; use Magento\Newsletter\Model\SubscriberFactory; +/** + * Class ProblemTest + */ class ProblemTest extends \PHPUnit\Framework\TestCase { /** @@ -59,6 +62,9 @@ class ProblemTest extends \PHPUnit\Framework\TestCase */ private $problemModel; + /** + * @inheritdoc + */ protected function setUp() { $this->contextMock = $this->getMockBuilder(Context::class) @@ -68,6 +74,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->subscriberFactoryMock = $this->getMockBuilder(SubscriberFactory::class) + ->disableOriginalConstructor() ->getMock(); $this->subscriberMock = $this->getMockBuilder(Subscriber::class) ->disableOriginalConstructor() @@ -98,6 +105,9 @@ protected function setUp() ); } + /** + * @return void + */ public function testAddSubscriberData() { $subscriberId = 1; @@ -111,6 +121,9 @@ public function testAddSubscriberData() self::assertEquals($subscriberId, $this->problemModel->getSubscriberId()); } + /** + * @return void + */ public function testAddQueueData() { $queueId = 1; @@ -127,6 +140,9 @@ public function testAddQueueData() self::assertEquals($queueId, $this->problemModel->getQueueId()); } + /** + * @return void + */ public function testAddErrorData() { $exceptionMessage = 'Some message'; @@ -140,17 +156,26 @@ public function testAddErrorData() self::assertEquals($exceptionCode, $this->problemModel->getProblemErrorCode()); } + /** + * @return void + */ public function testGetSubscriberWithNoSubscriberId() { self::assertNull($this->problemModel->getSubscriber()); } + /** + * @return void + */ public function testGetSubscriber() { $this->setSubscriber(); self::assertEquals($this->subscriberMock, $this->problemModel->getSubscriber()); } + /** + * @return void + */ public function testUnsubscribeWithNoSubscriber() { $this->subscriberMock->expects($this->never()) @@ -162,6 +187,9 @@ public function testUnsubscribeWithNoSubscriber() self::assertEquals($this->problemModel, $result); } + /** + * @return void + */ public function testUnsubscribe() { $this->setSubscriber(); diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index f33ad8700f056..908b045c15397 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -4,13 +4,11 @@ * See COPYING.txt for license details. */ -/** - * Class to work with zip archives - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Framework\Archive; +/** + * Zip compressed file archive. + */ class Zip extends AbstractArchive implements ArchiveInterface { /** @@ -55,10 +53,29 @@ public function unpack($source, $destination) { $zip = new \ZipArchive(); $zip->open($source); - $filename = $zip->getNameIndex(0); - $zip->extractTo(dirname($destination), $filename); - rename(dirname($destination).'/'.$filename, $destination); + $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); + if ($filename) { + $zip->extractTo(dirname($destination), $filename); + rename(dirname($destination).'/'.$filename, $destination); + } else { + $destination = ''; + } $zip->close(); return $destination; } + + /** + * Filter file names with relative paths. + * + * @param string $path + * @return string + */ + private function filterRelativePaths(string $path): string + { + if ($path && preg_match('#^\s*(../)|(/../)#i', $path)) { + $path = ''; + } + + return $path; + } } From 3f0e9a433b98577376f286e9935f1fd717a92c27 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 15 Oct 2018 17:28:26 +0200 Subject: [PATCH 0583/1415] Fixed incorrect datepicker icon position in admin panel --- .../backend/web/css/source/components/_calendar-temp.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less index 5ba18af6b0547..11b187db3d1e4 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less @@ -43,7 +43,7 @@ height: @action__height; margin-left: -@action__height; overflow: hidden; - position: relative; + position: absolute; vertical-align: top; z-index: 1; From 584eb7d6c876ea8c20e8a032ebddb43f5f8d3553 Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 15 Oct 2018 19:46:32 +0300 Subject: [PATCH 0584/1415] magento/graphql-ce#41: Fixed typos --- .../SalesGraphQl/Model/Resolver/Orders.php | 4 +- app/code/Magento/SalesGraphQl/README.md | 4 +- .../Magento/SalesGraphQl/etc/schema.graphqls | 11 ++-- dev/tests/api-functional/phpunit.xml.dist | 56 ------------------- .../Magento/GraphQl/Sales/OrdersTest.php | 12 ++-- 5 files changed, 13 insertions(+), 74 deletions(-) delete mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index c6c6ac6203789..91078c1580634 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -68,15 +68,13 @@ public function resolve( $orders = $this->collectionFactory->create($customerId); $items = []; - // @TODO Add shipping & billing address in response - // @TODO Add order currency object in response /** @var \Magento\Sales\Model\Order $order */ foreach ($orders as $order) { $items[] = [ 'id' => $order->getId(), 'increment_id' => $order->getIncrementId(), 'created_at' => $order->getCreatedAt(), - 'grant_total' => $order->getGrandTotal(), + 'grand_total' => $order->getGrandTotal(), 'state' => $order->getState(), 'status' => $order->getStatus() ]; diff --git a/app/code/Magento/SalesGraphQl/README.md b/app/code/Magento/SalesGraphQl/README.md index d827613570bad..d5717821b164c 100644 --- a/app/code/Magento/SalesGraphQl/README.md +++ b/app/code/Magento/SalesGraphQl/README.md @@ -1,6 +1,4 @@ # SalesGraphQl **SalesGraphQl** provides type and resolver information for the GraphQl module -to generate sales orders information endpoints. - -Also will provides endpoints for modifying an order. +to generate sales orders information. diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls index c137484cd2f65..44f106532858f 100644 --- a/app/code/Magento/SalesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -2,18 +2,17 @@ # See COPYING.txt for license details. type Query { - customerOrders: Orders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") + customerOrders: CustomerOrders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") } -type Order @doc(description: "Order mapping fields") { +type CustomerOrder @doc(description: "Order mapping fields") { id: Int increment_id: String created_at: String - grant_total: Float - state: String + grand_total: Float status: String } -type Orders { - items: [Order] @doc(description: "Array of orders") +type CustomerOrders { + items: [CustomerOrder] @doc(description: "Array of orders") } diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist deleted file mode 100644 index c869608462d08..0000000000000 --- a/dev/tests/api-functional/phpunit.xml.dist +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/** - * PHPUnit configuration for GraphQL web API functional tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" - colors="true" - columns="max" - beStrictAboutTestsThatDoNotTestAnything="false" - bootstrap="./framework/bootstrap.php" -> - <!-- Test suites definition --> - <testsuites> - <testsuite name="Magento GraphQL web API functional tests"> - <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> - </testsuite> - </testsuites> - - <!-- PHP INI settings and constants definition --> - <php> - <includePath>./testsuite</includePath> - <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> - <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> - <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento.inno"/> - <!-- Webserver API user --> - <const name="TESTS_WEBSERVICE_USER" value="admin"/> - <!-- Webserver API key --> - <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> - <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> - <const name="TESTS_XDEBUG_ENABLED" value="true"/> - <!-- Define XDEBUG_SESSION cookie value--> - <const name="TESTS_XDEBUG_SESSION" value="MEETMAGENTO" /> - - <ini name="date.timezone" value="America/Los_Angeles"/> - - <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> - <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <!-- Whether to cleanup the application before running tests or not --> - <const name="TESTS_CLEANUP" value="enabled"/> - <!--Defines if Magento should be installed before tests execution--> - <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> - <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="default"/> - </php> - - <!-- Test listeners --> - <listeners> - <listener class="Magento\TestFramework\Event\PhpUnit"/> - </listeners> -</phpunit> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index 3a85c044f16a9..ef7ceebc3a053 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -63,31 +63,31 @@ public function testOrdersQuery() 'increment_id' => '100000002', 'state' => \Magento\Sales\Model\Order::STATE_NEW, 'status' => 'processing', - 'grant_total' => 120.00 + 'grand_total' => 120.00 ], [ 'increment_id' => '100000003', 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'processing', - 'grant_total' => 130.00 + 'grand_total' => 130.00 ], [ 'increment_id' => '100000004', 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'closed', - 'grant_total' => 140.00 + 'grand_total' => 140.00 ], [ 'increment_id' => '100000005', 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', - 'grant_total' => 150.00 + 'grand_total' => 150.00 ], [ 'increment_id' => '100000006', 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', - 'grant_total' => 160.00 + 'grand_total' => 160.00 ] ]; @@ -95,7 +95,7 @@ public function testOrdersQuery() foreach ($expectedData as $key => $data) { $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); - $this->assertEquals($data['grant_total'], $actualData[$key]['grant_total']); + $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); $this->assertEquals($data['state'], $actualData[$key]['state']); $this->assertEquals($data['status'], $actualData[$key]['status']); } From 4a31f4f11972bf69fdbbe125fd262f9dfdfed0de Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 15 Oct 2018 19:55:48 +0300 Subject: [PATCH 0585/1415] magento/graphql-ce#41: get user info from resolver context --- .../SalesGraphQl/Model/Resolver/Orders.php | 29 +++++++------------ .../Magento/GraphQl/Sales/OrdersTest.php | 23 +++++---------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index 91078c1580634..05af6829de454 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -15,15 +15,10 @@ use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; /** - * {@inheritdoc} + * Class Orders */ class Orders implements ResolverInterface { - /** - * @var UserContextInterface - */ - private $userContext; - /** * @var CollectionFactoryInterface */ @@ -36,15 +31,13 @@ class Orders implements ResolverInterface /** * Orders constructor. - * @param UserContextInterface $userContext * @param CollectionFactoryInterface $collectionFactory + * @param CheckCustomerAccountInterface $checkCustomerAccount */ public function __construct( - UserContextInterface $userContext, CollectionFactoryInterface $collectionFactory, CheckCustomerAccountInterface $checkCustomerAccount ) { - $this->userContext = $userContext; $this->collectionFactory = $collectionFactory; $this->checkCustomerAccount = $checkCustomerAccount; @@ -55,18 +48,17 @@ public function __construct( */ public function resolve( Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null + $context, + ResolveInfo $info, + array $value = null, + array $args = null ) { + $customerId = $context->getUserId(); - $customerId = $this->userContext->getUserId(); + $this->checkCustomerAccount->execute($customerId, $context->getUserType()); - $this->checkCustomerAccount->execute($customerId, $this->userContext->getUserType()); - - $orders = $this->collectionFactory->create($customerId); $items = []; + $orders = $this->collectionFactory->create($customerId); /** @var \Magento\Sales\Model\Order $order */ foreach ($orders as $order) { @@ -75,11 +67,10 @@ public function resolve( 'increment_id' => $order->getIncrementId(), 'created_at' => $order->getCreatedAt(), 'grand_total' => $order->getGrandTotal(), - 'state' => $order->getState(), 'status' => $order->getStatus() ]; } return ['items' => $items]; } -} \ No newline at end of file +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index ef7ceebc3a053..33620f6e55386 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -40,16 +40,15 @@ public function testOrdersQuery() $query = <<<QUERY query { - customerOrders { - items { - id - increment_id - created_at - grant_total - state - status - } + customerOrders { + items { + id + increment_id + created_at + grand_total + status } + } } QUERY; @@ -61,31 +60,26 @@ public function testOrdersQuery() $expectedData = [ [ 'increment_id' => '100000002', - 'state' => \Magento\Sales\Model\Order::STATE_NEW, 'status' => 'processing', 'grand_total' => 120.00 ], [ 'increment_id' => '100000003', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'processing', 'grand_total' => 130.00 ], [ 'increment_id' => '100000004', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'closed', 'grand_total' => 140.00 ], [ 'increment_id' => '100000005', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', 'grand_total' => 150.00 ], [ 'increment_id' => '100000006', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', 'grand_total' => 160.00 ] @@ -96,7 +90,6 @@ public function testOrdersQuery() foreach ($expectedData as $key => $data) { $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); - $this->assertEquals($data['state'], $actualData[$key]['state']); $this->assertEquals($data['status'], $actualData[$key]['status']); } } From 94f25c3ba8dffb00ab31c3cdc9a6262b42fabee6 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Mon, 15 Oct 2018 12:17:26 -0500 Subject: [PATCH 0586/1415] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Added short class description. --- .../Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php index 83278ca78c738..9d7273fb3f23c 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php @@ -14,6 +14,7 @@ use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; /** + * Updates status for a batch of products. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpPostActionInterface From 0f1f83e66a9b20b4d100fcda84b5a38c21d8c828 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 15 Oct 2018 13:06:43 -0500 Subject: [PATCH 0587/1415] MAGETWO-95505: Broken Swagger markup --- .../Swagger/view/frontend/templates/swagger-ui/index.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml b/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml index 4e1b50723782a..26ef4847a1267 100644 --- a/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml +++ b/app/code/Magento/Swagger/view/frontend/templates/swagger-ui/index.phtml @@ -17,7 +17,7 @@ * @codingStandardsIgnoreFile */ -$schemaUrl = $block->escapeUrl($block->getSchemaUrl()); +$schemaUrl = $block->getSchemaUrl(); ?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0"> @@ -58,7 +58,7 @@ $schemaUrl = $block->escapeUrl($block->getSchemaUrl()); <div class="swagger-ui-wrap"> <a id="logo" href="http://swagger.io">swagger</a> <form id='api_selector'> - <input id="input_baseUrl" type="hidden" value="<?= /* @escapeNotVerified */ $schemaUrl ?>"/> + <input id="input_baseUrl" type="hidden" value="<?= $block->escapeUrl($schemaUrl) ?>"/> <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div> <div class='input'><a id="explore" href="#" data-sw-translate>apply</a></div> </form> From e30a12e6bf954763662f68f5eec87d2cbc2e93dd Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh@Maheshs-MacBook-Air.local> Date: Tue, 16 Oct 2018 00:08:57 +0530 Subject: [PATCH 0588/1415] reference pull request of #18604 for 2.3-develop --- app/code/Magento/Catalog/Pricing/Price/BasePrice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php index 54a13be864db7..77368517a3155 100644 --- a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php +++ b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php @@ -30,7 +30,7 @@ public function getValue() $this->value = false; foreach ($this->priceInfo->getPrices() as $price) { if ($price instanceof BasePriceProviderInterface && $price->getValue() !== false) { - $this->value = min($price->getValue(), $this->value ?: $price->getValue()); + $this->value = min($price->getValue(), $this->value !== false ? $this->value: $price->getValue()); } } } From 56931215d1b2ae9b2a85a0a18e49d9727063a702 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Fri, 12 Oct 2018 15:37:09 -0500 Subject: [PATCH 0589/1415] MAGETWO-95391: Widget Escaping - Convert widget code to heredoc and escape output --- .../Magento/Widget/Block/Adminhtml/Widget.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget.php b/app/code/Magento/Widget/Block/Adminhtml/Widget.php index e4854415d7534..16280a5a061cd 100644 --- a/app/code/Magento/Widget/Block/Adminhtml/Widget.php +++ b/app/code/Magento/Widget/Block/Adminhtml/Widget.php @@ -40,13 +40,17 @@ protected function _construct() $this->buttonList->update('reset', 'label', __('Cancel')); $this->buttonList->update('reset', 'onclick', 'wWidget.closeModal()'); - $this->_formScripts[] = 'require(["mage/adminhtml/wysiwyg/widget"],' - . ' function(){wWidget = new WysiwygWidget.Widget(' - . '"widget_options_form", "select_widget_type", "widget_options", "' - . $this->getUrl( - 'adminhtml/*/loadOptions' - ) . '", "' . $this->getRequest()->getParam( - 'widget_target_id' - ) . '");});'; + $this->_formScripts[] = <<<EOJS +require(['mage/adminhtml/wysiwyg/widget'], function() { + wWidget = new WysiwygWidget.Widget( + 'widget_options_form', + 'select_widget_type', + 'widget_options', + '{$this->getUrl('adminhtml/*/loadOptions')}', + '{$this->escapeJs($this->getRequest()->getParam('widget_target_id'))}' + ); +}); +EOJS; + } } From f722280905f8e5a510e9b0c202e12b37de7e14a2 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Mon, 15 Oct 2018 14:16:39 -0500 Subject: [PATCH 0590/1415] MAGETWO-95391: Widget Escaping - Resolve static test failures --- app/code/Magento/Widget/Block/Adminhtml/Widget.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget.php b/app/code/Magento/Widget/Block/Adminhtml/Widget.php index 16280a5a061cd..dad318f163b4b 100644 --- a/app/code/Magento/Widget/Block/Adminhtml/Widget.php +++ b/app/code/Magento/Widget/Block/Adminhtml/Widget.php @@ -15,7 +15,7 @@ class Widget extends \Magento\Backend\Block\Widget\Form\Container { /** - * @return void + * @inheritdoc */ protected function _construct() { @@ -51,6 +51,5 @@ protected function _construct() ); }); EOJS; - } } From ac457a482c948abc3f99a4803005035a31950dc8 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 15 Oct 2018 15:19:16 -0500 Subject: [PATCH 0591/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 - added functional test to cover the bug fix --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 2 + .../AdminAddImageToCMSPageTinyMCE3Test.xml | 80 +++++++++++++++++++ .../Section/AdminTinymce3FileldsSection.xml | 1 + 3 files changed, 83 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index 75a399720cd6a..ed682a9e20435 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -34,6 +34,7 @@ </section> <section name="MediaGallerySection"> <element name="Browse" type="button" selector=".mce-i-browse"/> + <element name="browseForImage" type="button" selector="//*[@id='srcbrowser']"/> <element name="BrowseUploadImage" type="file" selector=".fileupload" /> <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> <element name="imageOrImageCopy" type="text" selector="//div[contains(@class,'media-gallery-modal')]//img[contains(@alt, '{{arg1}}.{{arg2}}')]|//img[contains(@alt,'{{arg1}}_') and contains(@alt,'.{{arg2}}')]" parameterized="true"/> @@ -43,6 +44,7 @@ <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> + <element name="insertBtn" type="button" selector="#insert"/> <element name="InsertFile" type="text" selector="#insert_files"/> <element name="CreateFolder" type="button" selector="#new_folder" /> <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml new file mode 100644 index 0000000000000..125faa935f369 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminAddImageToCMSPageTinyMCE3Test"> + <annotations> + <features value="Cms"/> + <stories value="Admin should be able to upload images with TinyMCE3 WYSIWYG"/> + <group value="Cms"/> + <title value="Verify that admin is able to upload image to a CMS Page with TinyMCE3 enabled"/> + <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95725"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox1" /> + <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown1" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions1" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig1" /> + </before> + <after> + <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> + <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> + <waitForPageLoad stepKey="waitForConfigPageToReload"/> + <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> + + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown3" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 4" stepKey="switchToVersion4" /> + <checkOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="checkUseSystemValue2"/> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions2" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig2" /> + <actionGroup ref="logout" stepKey="logOut"/> + </after> + <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> + <waitForPageLoad stepKey="wait5"/> + <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle2"/> + <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> + <seeElement selector="{{TinyMCESection.TinyMCE3}}" stepKey="seeTinyMCE3" /> + <comment userInput="Click Insert image button" stepKey="clickImageButton"/> + <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> + <waitForPageLoad stepKey="waitForiFrameToLoad" /> + <comment userInput="switching to iFrame" stepKey="iFramecomment"/> + <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable"/> + <switchToIFrame selector="insert-image" stepKey="switchToIFrame"/> + <click selector="{{MediaGallerySection.browseForImage}}" stepKey="clickBrowse"/> + <switchToIFrame stepKey="switchOutOfIFrame"/> + <waitForPageLoad stepKey="waitForPageToLoad" /> + <actionGroup ref="CreateImageFolder" stepKey="CreateImageFolder"> + <argument name="ImageFolder" value="ImageFolder"/> + </actionGroup> + <actionGroup ref="attachImage" stepKey="attachImage1"> + <argument name="Image" value="ImageUpload"/> + </actionGroup> + <actionGroup ref="saveImage" stepKey="insertImage"/> + <comment userInput="switching back to iFrame" stepKey="switchBackToIFrame"/> + <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable2"/> + <switchToIFrame selector="insert-image" stepKey="switchToIFrame2"/> + <waitForElementVisible selector="{{MediaGallerySection.insertBtn}}" stepKey="waitForInsertBtnOnIFrame" /> + <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <click selector="{{MediaGallerySection.insertBtn}}" stepKey="clickInsertBtn" /> + <waitForPageLoad stepKey="wait3"/> + <click selector="{{CmsNewPagePageActionsSection.expandSplitButton}}" stepKey="expandButtonMenu"/> + <waitForElementVisible selector="{{CmsNewPagePageActionsSection.splitButtonMenu}}" stepKey="waitForSplitButtonMenuVisible"/> + <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> + <see userInput="You saved the page." stepKey="seeSuccessMessage"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml b/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml index 1730996937ca2..76c0a9e1fe797 100644 --- a/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml +++ b/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml @@ -13,6 +13,7 @@ </section> <section name="TinyMCESection"> <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> + <element name="InsertImageBtnTinyMCE3" type="button" selector="#cms_page_form_content_image"/> </section> <section name="NewsletterWYSIWYGSection"> <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> From 954ee4fbecf96d3898bbad21d46f2430d6ebd544 Mon Sep 17 00:00:00 2001 From: Ayaz Mittaqi <ayaz.mittaqi024@webkul.com> Date: Tue, 16 Oct 2018 02:51:20 +0530 Subject: [PATCH 0592/1415] fixed issue regarding referer url of compare page during adding product to wishlist. --- .../Magento/Catalog/Block/Product/Compare/ListCompare.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php index 6c54aa4e171ef..76f5dbd1bea88 100644 --- a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php @@ -122,12 +122,7 @@ public function __construct( */ public function getAddToWishlistParams($product) { - $continueUrl = $this->urlEncoder->encode($this->getUrl('customer/account')); - $urlParamName = Action::PARAM_NAME_URL_ENCODED; - - $continueUrlParams = [$urlParamName => $continueUrl]; - - return $this->_wishlistHelper->getAddParams($product, $continueUrlParams); + return $this->_wishlistHelper->getAddParams($product); } /** From c25ea8170a37bea2707bb311591da84c983ab513 Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Mon, 15 Oct 2018 16:39:09 -0500 Subject: [PATCH 0593/1415] MAGETWO-95210: Unable to place orders as Guest after deleting PHPSESSID cookie value Modify convertCustomerCartToGuest function to get quote Id from getter method. --- app/code/Magento/Persistent/Model/QuoteManager.php | 2 +- .../Test/Unit/Model/QuoteManagerTest.php | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Persistent/Model/QuoteManager.php b/app/code/Magento/Persistent/Model/QuoteManager.php index 8937a4920cb23..cd7ce400a0be1 100644 --- a/app/code/Magento/Persistent/Model/QuoteManager.php +++ b/app/code/Magento/Persistent/Model/QuoteManager.php @@ -109,7 +109,7 @@ public function setGuest($checkQuote = false) public function convertCustomerCartToGuest() { /** @var $quote \Magento\Quote\Model\Quote */ - $quote = $this->quoteRepository->get($this->checkoutSession->getQuote()->getId()); + $quote = $this->quoteRepository->get($this->checkoutSession->getQuoteId()); if ($quote && $quote->getId()) { $this->_setQuotePersistent = false; $quote->setIsActive(true) diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php index 5b96acae1d747..d8c5e4fc8167d 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php @@ -245,8 +245,8 @@ public function testConvertCustomerCartToGuest() $emailArgs = ['email' => null]; $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->exactly(2))->method('getId')->willReturn($quoteId); + ->method('getQuoteId')->willReturn($quoteId); + $this->quoteMock->expects($this->once())->method('getId')->willReturn($quoteId); $this->quoteRepositoryMock->expects($this->once())->method('get')->with($quoteId)->willReturn($this->quoteMock); $this->quoteMock->expects($this->once()) ->method('setIsActive')->with(true)->willReturn($this->quoteMock); @@ -282,25 +282,23 @@ public function testConvertCustomerCartToGuest() $this->model->convertCustomerCartToGuest(); } - +E public function testConvertCustomerCartToGuestWithEmptyQuote() { $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->once())->method('getId')->willReturn(null); + ->method('getQuoteId')->willReturn(null); $this->quoteRepositoryMock->expects($this->once())->method('get')->with(null)->willReturn(null); - $this->model->convertCustomerCartToGuest(); } public function testConvertCustomerCartToGuestWithEmptyQuoteId() { $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->once())->method('getId')->willReturn(1); + ->method('getQuoteId')->willReturn(1); $quoteWithNoId = $this->quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); $quoteWithNoId->expects($this->once())->method('getId')->willReturn(null); $this->quoteRepositoryMock->expects($this->once())->method('get')->with(1)->willReturn($quoteWithNoId); + $this->quoteMock->expects($this->once())->method('getId')->willReturn(1); $this->model->convertCustomerCartToGuest(); } } From 551b89853bdcea5778eaa62e8237b20f1baeb52d Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Mon, 15 Oct 2018 16:48:23 -0500 Subject: [PATCH 0594/1415] MAGETWO-95210: Unable to place orders as Guest after deleting PHPSESSID cookie value Fix typo in test. --- .../Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php index d8c5e4fc8167d..e5de8e7d4aade 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php @@ -282,7 +282,7 @@ public function testConvertCustomerCartToGuest() $this->model->convertCustomerCartToGuest(); } -E + public function testConvertCustomerCartToGuestWithEmptyQuote() { $this->checkoutSessionMock->expects($this->once()) From 6f14ad9d800fe0d0496de6b92fe5be7b8d87fd3a Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 15 Oct 2018 16:53:52 -0500 Subject: [PATCH 0595/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 - modified after CR comments --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 1 + .../AdminAddImageToCMSPageTinyMCE3Test.xml | 27 ++++++------------- .../ActionGroup/ConfigWYSIWYGActionGroup.xml | 9 +++++++ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index ed682a9e20435..92112661846c0 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -41,6 +41,7 @@ <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> + <element name="ImageDescriptionTinyMCE3" type="input" selector="#alt" /> <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 125faa935f369..5ae3f4af2421e 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -21,26 +21,13 @@ <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> - <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> - <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox1" /> - <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> - <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown1" /> - <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions1" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig1" /> + <!-- Choose TinyMCE3 as the default WYSIWYG editor--> + <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> </before> <after> + <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> - <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> - <waitForPageLoad stepKey="waitForConfigPageToReload"/> - <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> - <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> - - <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown3" /> - <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 4" stepKey="switchToVersion4" /> - <checkOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="checkUseSystemValue2"/> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions2" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig2" /> + <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> <actionGroup ref="logout" stepKey="logOut"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> @@ -52,7 +39,8 @@ <comment userInput="Click Insert image button" stepKey="clickImageButton"/> <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> <waitForPageLoad stepKey="waitForiFrameToLoad" /> - <comment userInput="switching to iFrame" stepKey="iFramecomment"/> + <!-- Switch to the Edit/Insert Image iFrame --> + <comment userInput="Switching to iFrame" stepKey="insertImageiFrame"/> <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable"/> <switchToIFrame selector="insert-image" stepKey="switchToIFrame"/> <click selector="{{MediaGallerySection.browseForImage}}" stepKey="clickBrowse"/> @@ -65,11 +53,12 @@ <argument name="Image" value="ImageUpload"/> </actionGroup> <actionGroup ref="saveImage" stepKey="insertImage"/> + <!-- Switching back to the Edit/Insert Image iFrame--> <comment userInput="switching back to iFrame" stepKey="switchBackToIFrame"/> <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable2"/> <switchToIFrame selector="insert-image" stepKey="switchToIFrame2"/> <waitForElementVisible selector="{{MediaGallerySection.insertBtn}}" stepKey="waitForInsertBtnOnIFrame" /> - <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <fillField selector="{{MediaGallerySection.ImageDescriptionTinyMCE3}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> <click selector="{{MediaGallerySection.insertBtn}}" stepKey="clickInsertBtn" /> <waitForPageLoad stepKey="wait3"/> <click selector="{{CmsNewPagePageActionsSection.expandSplitButton}}" stepKey="expandButtonMenu"/> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 3c043b28801e2..836cba95a6d00 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -19,6 +19,15 @@ <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> </actionGroup> + <actionGroup name="SwitchToTinyMCE3"> + <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> + <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown2" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + </actionGroup> <actionGroup name="DisabledWYSIWYG"> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> <waitForPageLoad stepKey="wait3"/> From 7106d24fd8911881874ca2e60e02b3161f680fbf Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 10 Oct 2018 13:02:33 -0500 Subject: [PATCH 0596/1415] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. --- .../Catalog/view/adminhtml/ui_component/category_form.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml index dafea71f872d0..1a54db0d59f0f 100644 --- a/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml +++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml @@ -331,7 +331,6 @@ <item name="type" xsi:type="string">group</item> <item name="config" xsi:type="array"> <item name="breakLine" xsi:type="boolean">true</item> - <item name="required" xsi:type="boolean">true</item> </item> </argument> <field name="filter_price_range" formElement="input"> @@ -341,6 +340,9 @@ </item> </argument> <settings> + <validation> + <rule name="required-entry" xsi:type="boolean">true</rule> + </validation> <additionalClasses> <class name="admin__field-small">true</class> </additionalClasses> From 039c88dfdd6a6ad2cdb6031f52c07a87afeded28 Mon Sep 17 00:00:00 2001 From: speedy008 <kajal10395@gmail.com> Date: Tue, 16 Oct 2018 10:46:40 +0530 Subject: [PATCH 0597/1415] solved calender icon issue in advance pricing in adminpanel --- .../backend/web/css/source/components/_calendar-temp.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less index 5ba18af6b0547..11b187db3d1e4 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less @@ -43,7 +43,7 @@ height: @action__height; margin-left: -@action__height; overflow: hidden; - position: relative; + position: absolute; vertical-align: top; z-index: 1; From a9bc411deaecd93be411a3bc8c8da003b2e31298 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Tue, 16 Oct 2018 10:57:14 +0530 Subject: [PATCH 0598/1415] Fix SKU limit in import new products for 2.3 with backward compatible --- .../CatalogImportExport/Model/Import/Product/Validator.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 2aa2105991883..b184334b179ea 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -7,6 +7,7 @@ use Magento\CatalogImportExport\Model\Import\Product; use Magento\Framework\Validator\AbstractValidator; +use Magento\Catalog\Model\Product\Attribute\Backend\Sku; /** * Class Validator @@ -69,6 +70,8 @@ protected function textValidation($attrCode, $type) $val = $this->string->cleanString($this->_rowData[$attrCode]); if ($type == 'text') { $valid = $this->string->strlen($val) < Product::DB_MAX_TEXT_LENGTH; + } else if ($attrCode == Product::COL_SKU) { + $valid = $this->string->strlen($val) < SKU::SKU_MAX_LENGTH; } else { $valid = $this->string->strlen($val) < Product::DB_MAX_VARCHAR_LENGTH; } From 06237d69db44b491dfe57b29cf50d7c01b5b8c0c Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Tue, 16 Oct 2018 08:53:19 +0200 Subject: [PATCH 0599/1415] Added check for truthy value of $requestData variable in case of null --- .../Magento/Braintree/Controller/Paypal/Review.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index 964b0bde135ae..e6a1dcbc34559 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -60,7 +60,7 @@ public function execute() try { $this->validateQuote($quote); - if ($this->validateRequestData($requestData)) { + if ($requestData && $this->validateRequestData($requestData)) { $this->quoteUpdater->execute( $requestData['nonce'], $requestData['details'], @@ -91,14 +91,11 @@ public function execute() } /** - * @param $requestData - * @return bool + * @param array $requestData + * @return boolean */ - private function validateRequestData($requestData) + private function validateRequestData(array $requestData) { - if (is_array($requestData)) { - return !empty($requestData['nonce']) && !empty($requestData['details']); - } - return false; + return !empty($requestData['nonce']) && !empty($requestData['details']); } } From 12b7e08c2f262d0683e5b61d5fd2487aac19c27d Mon Sep 17 00:00:00 2001 From: Fabian Schmengler <fs@integer-net.de> Date: Tue, 16 Oct 2018 09:21:09 +0200 Subject: [PATCH 0600/1415] Set cache id prefix on installation --- .../Setup/Model/ConfigOptionsList/Cache.php | 23 ++++++ .../Model/ConfigOptionsList/PageCache.php | 23 ++++++ .../Model/ConfigOptionsList/CacheTest.php | 70 +++++++++++++++++- .../Model/ConfigOptionsList/PageCacheTest.php | 71 ++++++++++++++++++- 4 files changed, 181 insertions(+), 6 deletions(-) diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php index 2f19f010c1704..85c0e2c4e9b3b 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php @@ -27,12 +27,14 @@ class Cache implements ConfigOptionsListInterface const INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE = 'cache-backend-redis-db'; const INPUT_KEY_CACHE_BACKEND_REDIS_PORT = 'cache-backend-redis-port'; const INPUT_KEY_CACHE_BACKEND_REDIS_PASSWORD = 'cache-backend-redis-password'; + const INPUT_KEY_CACHE_ID_PREFIX = 'cache-id-prefix'; const CONFIG_PATH_CACHE_BACKEND = 'cache/frontend/default/backend'; const CONFIG_PATH_CACHE_BACKEND_SERVER = 'cache/frontend/default/backend_options/server'; const CONFIG_PATH_CACHE_BACKEND_DATABASE = 'cache/frontend/default/backend_options/database'; const CONFIG_PATH_CACHE_BACKEND_PORT = 'cache/frontend/default/backend_options/port'; const CONFIG_PATH_CACHE_BACKEND_PASSWORD = 'cache/frontend/default/backend_options/password'; + const CONFIG_PATH_CACHE_ID_PREFIX = 'cache/frontend/default/id_prefix'; /** * @var array @@ -112,6 +114,12 @@ public function getOptions() TextConfigOption::FRONTEND_WIZARD_TEXT, self::CONFIG_PATH_CACHE_BACKEND_PASSWORD, 'Redis server password' + ), + new TextConfigOption( + self::INPUT_KEY_CACHE_ID_PREFIX, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::CONFIG_PATH_CACHE_ID_PREFIX, + 'ID prefix for cache keys' ) ]; } @@ -122,6 +130,11 @@ public function getOptions() public function createConfig(array $options, DeploymentConfig $deploymentConfig) { $configData = new ConfigData(ConfigFilePool::APP_ENV); + if (isset($options[self::INPUT_KEY_CACHE_ID_PREFIX])) { + $configData->set(self::CONFIG_PATH_CACHE_ID_PREFIX, $options[self::INPUT_KEY_CACHE_ID_PREFIX]); + } else { + $configData->set(self::CONFIG_PATH_CACHE_ID_PREFIX, $this->generateCachePrefix()); + } if (isset($options[self::INPUT_KEY_CACHE_BACKEND])) { if ($options[self::INPUT_KEY_CACHE_BACKEND] == self::INPUT_VALUE_CACHE_REDIS) { @@ -241,4 +254,14 @@ private function getDefaultConfigValue($inputKey) return ''; } } + + /** + * Generate default cache ID prefix based on installation dir + * + * @return string + */ + private function generateCachePrefix(): string + { + return substr(\md5(dirname(__DIR__, 6)), 0, 3) . '_'; + } } diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php index c288b4dd51d65..35a9955aad506 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php @@ -28,6 +28,7 @@ class PageCache implements ConfigOptionsListInterface const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_PORT = 'page-cache-redis-port'; const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_COMPRESS_DATA = 'page-cache-redis-compress-data'; const INPUT_KEY_PAGE_CACHE_BACKEND_REDIS_PASSWORD = 'page-cache-redis-password'; + const INPUT_KEY_PAGE_CACHE_ID_PREFIX = 'page-cache-id-prefix'; const CONFIG_PATH_PAGE_CACHE_BACKEND = 'cache/frontend/page_cache/backend'; const CONFIG_PATH_PAGE_CACHE_BACKEND_SERVER = 'cache/frontend/page_cache/backend_options/server'; @@ -35,6 +36,7 @@ class PageCache implements ConfigOptionsListInterface const CONFIG_PATH_PAGE_CACHE_BACKEND_PORT = 'cache/frontend/page_cache/backend_options/port'; const CONFIG_PATH_PAGE_CACHE_BACKEND_COMPRESS_DATA = 'cache/frontend/page_cache/backend_options/compress_data'; const CONFIG_PATH_PAGE_CACHE_BACKEND_PASSWORD = 'cache/frontend/page_cache/backend_options/password'; + const CONFIG_PATH_PAGE_CACHE_ID_PREFIX = 'cache/frontend/page_cache/id_prefix'; /** * @var array @@ -122,6 +124,12 @@ public function getOptions() TextConfigOption::FRONTEND_WIZARD_TEXT, self::CONFIG_PATH_PAGE_CACHE_BACKEND_PASSWORD, 'Redis server password' + ), + new TextConfigOption( + self::INPUT_KEY_PAGE_CACHE_ID_PREFIX, + TextConfigOption::FRONTEND_WIZARD_TEXT, + self::CONFIG_PATH_PAGE_CACHE_ID_PREFIX, + 'ID prefix for cache keys' ) ]; } @@ -132,6 +140,11 @@ public function getOptions() public function createConfig(array $options, DeploymentConfig $deploymentConfig) { $configData = new ConfigData(ConfigFilePool::APP_ENV); + if (isset($options[self::INPUT_KEY_PAGE_CACHE_ID_PREFIX])) { + $configData->set(self::CONFIG_PATH_PAGE_CACHE_ID_PREFIX, $options[self::INPUT_KEY_PAGE_CACHE_ID_PREFIX]); + } else { + $configData->set(self::CONFIG_PATH_PAGE_CACHE_ID_PREFIX, $this->generateCachePrefix()); + } if (isset($options[self::INPUT_KEY_PAGE_CACHE_BACKEND])) { if ($options[self::INPUT_KEY_PAGE_CACHE_BACKEND] == self::INPUT_VALUE_PAGE_CACHE_REDIS) { @@ -252,4 +265,14 @@ private function getDefaultConfigValue($inputKey) return ''; } } + + /** + * Generate default cache ID prefix based on installation dir + * + * @return string + */ + private function generateCachePrefix(): string + { + return substr(\md5(dirname(__DIR__, 6)), 0, 3) . '_'; + } } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/CacheTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/CacheTest.php index 1bbd2e671e59a..9c123fcb330dd 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/CacheTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/CacheTest.php @@ -45,7 +45,7 @@ protected function setUp() public function testGetOptions() { $options = $this->configOptionsList->getOptions(); - $this->assertCount(5, $options); + $this->assertCount(6, $options); $this->assertArrayHasKey(0, $options); $this->assertInstanceOf(SelectConfigOption::class, $options[0]); @@ -66,6 +66,10 @@ public function testGetOptions() $this->assertArrayHasKey(4, $options); $this->assertInstanceOf(TextConfigOption::class, $options[4]); $this->assertEquals('cache-backend-redis-password', $options[4]->getName()); + + $this->assertArrayHasKey(5, $options); + $this->assertInstanceOf(TextConfigOption::class, $options[5]); + $this->assertEquals('cache-id-prefix', $options[5]->getName()); } /** @@ -85,7 +89,8 @@ public function testCreateConfigCacheRedis() 'port' => '', 'database' => '', 'password' => '' - ] + ], + 'id_prefix' => $this->expectedIdPrefix(), ] ] ] @@ -111,7 +116,8 @@ public function testCreateConfigWithRedisConfig() 'port' => '1234', 'database' => '5', 'password' => '' - ] + ], + 'id_prefix' => $this->expectedIdPrefix(), ] ] ] @@ -128,6 +134,54 @@ public function testCreateConfigWithRedisConfig() $this->assertEquals($expectedConfigData, $configData->getData()); } + /** + * testCreateConfigCacheRedis + */ + public function testCreateConfigWithFileCache() + { + $this->deploymentConfigMock->method('get')->willReturn(''); + + $expectedConfigData = [ + 'cache' => [ + 'frontend' => [ + 'default' => [ + 'id_prefix' => $this->expectedIdPrefix(), + ] + ] + ] + ]; + + $configData = $this->configOptionsList->createConfig([], $this->deploymentConfigMock); + + $this->assertEquals($expectedConfigData, $configData->getData()); + } + + /** + * testCreateConfigCacheRedis + */ + public function testCreateConfigWithIdPrefix() + { + $this->deploymentConfigMock->method('get')->willReturn(''); + + $explicitPrefix = 'XXX_'; + $expectedConfigData = [ + 'cache' => [ + 'frontend' => [ + 'default' => [ + 'id_prefix' => $explicitPrefix, + ] + ] + ] + ]; + + $configData = $this->configOptionsList->createConfig( + ['cache-id-prefix' => $explicitPrefix], + $this->deploymentConfigMock + ); + + $this->assertEquals($expectedConfigData, $configData->getData()); + } + /** * testValidateWithValidInput */ @@ -160,4 +214,14 @@ public function testValidateWithInvalidInput() $this->assertCount(1, $errors); $this->assertEquals("Invalid cache handler 'clay-tablet'", $errors[0]); } + + /** + * The default ID prefix, based on installation directory + * + * @return string + */ + private function expectedIdPrefix(): string + { + return substr(\md5(dirname(__DIR__, 8)), 0, 3) . '_'; + } } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php index 6f8e97cd5dd8d..d804266096f7b 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php @@ -45,7 +45,7 @@ protected function setUp() public function testGetOptions() { $options = $this->configList->getOptions(); - $this->assertCount(6, $options); + $this->assertCount(7, $options); $this->assertArrayHasKey(0, $options); $this->assertInstanceOf(SelectConfigOption::class, $options[0]); @@ -70,6 +70,10 @@ public function testGetOptions() $this->assertArrayHasKey(5, $options); $this->assertInstanceOf(TextConfigOption::class, $options[5]); $this->assertEquals('page-cache-redis-password', $options[5]->getName()); + + $this->assertArrayHasKey(6, $options); + $this->assertInstanceOf(TextConfigOption::class, $options[6]); + $this->assertEquals('page-cache-id-prefix', $options[6]->getName()); } /** @@ -90,7 +94,8 @@ public function testCreateConfigWithRedis() 'database' => '', 'compress_data' => '', 'password' => '' - ] + ], + 'id_prefix' => $this->expectedIdPrefix(), ] ] ] @@ -117,7 +122,8 @@ public function testCreateConfigWithRedisConfiguration() 'database' => '6', 'compress_data' => '1', 'password' => '' - ] + ], + 'id_prefix' => $this->expectedIdPrefix(), ] ] ] @@ -136,6 +142,55 @@ public function testCreateConfigWithRedisConfiguration() $this->assertEquals($expectedConfigData, $configData->getData()); } + /** + * testCreateConfigWithRedis + */ + public function testCreateConfigWithFileCache() + { + $this->deploymentConfigMock->method('get')->willReturn(''); + + $expectedConfigData = [ + 'cache' => [ + 'frontend' => [ + 'page_cache' => [ + 'id_prefix' => $this->expectedIdPrefix(), + ] + ] + ] + ]; + + $configData = $this->configList->createConfig([], $this->deploymentConfigMock); + + $this->assertEquals($expectedConfigData, $configData->getData()); + } + + + /** + * testCreateConfigCacheRedis + */ + public function testCreateConfigWithIdPrefix() + { + $this->deploymentConfigMock->method('get')->willReturn(''); + + $explicitPrefix = 'XXX_'; + $expectedConfigData = [ + 'cache' => [ + 'frontend' => [ + 'page_cache' => [ + 'id_prefix' => $explicitPrefix, + ] + ] + ] + ]; + + $configData = $this->configList->createConfig( + ['page-cache-id-prefix' => $explicitPrefix], + $this->deploymentConfigMock + ); + + $this->assertEquals($expectedConfigData, $configData->getData()); + } + /** * testValidationWithValidData */ @@ -169,4 +224,14 @@ public function testValidationWithInvalidData() $this->assertCount(1, $errors); $this->assertEquals('Invalid cache handler \'foobar\'', $errors[0]); } + + /** + * The default ID prefix, based on installation directory + * + * @return string + */ + private function expectedIdPrefix(): string + { + return substr(\md5(dirname(__DIR__, 8)), 0, 3) . '_'; + } } From 441cd704f0e467edcef41e281657ca4a8cae53c2 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 16 Oct 2018 11:08:12 +0300 Subject: [PATCH 0601/1415] magento-engcom/magento2ce#2247: Code style fixes --- app/code/Magento/Config/Model/Config.php | 5 ++++- app/code/Magento/Customer/Model/Metadata/Form/Image.php | 5 ++++- .../Developer/Console/Command/SourceThemeDeployCommand.php | 4 ++-- app/code/Magento/Eav/Model/Attribute/Data/Image.php | 1 + .../Magento/OfflineShipping/Model/Carrier/Freeshipping.php | 2 ++ app/code/Magento/Widget/Model/Widget/Instance.php | 5 +++++ .../Magento/Framework/Data/Form/Element/Factory.php | 6 +++--- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php index 7ea979df30a41..535e0bba3885f 100644 --- a/app/code/Magento/Config/Model/Config.php +++ b/app/code/Magento/Config/Model/Config.php @@ -12,6 +12,7 @@ /** * Backend config model + * * Used to save configuration * * @author Magento Core Team <core@magentocommerce.com> @@ -122,6 +123,7 @@ public function __construct( /** * Save config section + * * Require set: section, website, store and groups * * @throws \Exception @@ -505,6 +507,7 @@ public function setDataByPath($path, $value) /** * Get scope name and scopeId + * * @todo refactor to scope resolver * @return void */ @@ -605,4 +608,4 @@ public function getConfigDataValue($path, &$inherit = null, $configData = null) return $data; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Image.php b/app/code/Magento/Customer/Model/Metadata/Form/Image.php index 692d08aae8d78..33bdf827f80fa 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Image.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Image.php @@ -16,6 +16,8 @@ use Magento\Framework\Filesystem; /** + * Metadata for form image field + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Image extends File @@ -32,7 +34,7 @@ class Image extends File * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute * @param \Magento\Framework\Locale\ResolverInterface $localeResolver - * @param null $value + * @param null|string $value * @param string $entityTypeCode * @param bool $isAjax * @param \Magento\Framework\Url\EncoderInterface $urlEncoder @@ -78,6 +80,7 @@ public function __construct( /** * Validate file by attribute validate rules + * * Return array of errors * * @param array $value diff --git a/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php b/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php index a2db0f43061ea..1680aee38dcd4 100644 --- a/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php +++ b/app/code/Magento/Developer/Console/Command/SourceThemeDeployCommand.php @@ -80,7 +80,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { @@ -128,7 +128,7 @@ protected function configure() } /** - * {@inheritdoc} + * @inheritdoc * @throws \InvalidArgumentException */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Image.php b/app/code/Magento/Eav/Model/Attribute/Data/Image.php index 0020256dfb148..24cd0f4fcf61f 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Image.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Image.php @@ -14,6 +14,7 @@ class Image extends \Magento\Eav\Model\Attribute\Data\File { /** * Validate file by attribute validate rules + * * Return array of errors * * @param array $value diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php index 2373b5285ed00..26f3274688977 100644 --- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php +++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php @@ -138,6 +138,8 @@ protected function _updateFreeMethodQuote($request) } /** + * Returns allowed shipping methods + * * @return array */ public function getAllowedMethods() diff --git a/app/code/Magento/Widget/Model/Widget/Instance.php b/app/code/Magento/Widget/Model/Widget/Instance.php index 1ccb75ad6611a..4ca126e659e09 100644 --- a/app/code/Magento/Widget/Model/Widget/Instance.php +++ b/app/code/Magento/Widget/Model/Widget/Instance.php @@ -340,6 +340,7 @@ public function setCode($code) /** * Setter + * * Prepare widget type * * @param string $type @@ -353,6 +354,7 @@ public function setType($type) /** * Getter + * * Prepare widget type * * @return string @@ -364,6 +366,7 @@ public function getType() /** * Getter. + * * If not set return default * * @return string @@ -379,6 +382,7 @@ public function getArea() /** * Getter + * * Explode to array if string setted * * @return array @@ -393,6 +397,7 @@ public function getStoreIds() /** * Getter + * * Unserialize if serialized string setted * * @return array diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php index 25cf8d3fb3b54..582b0c8cf6549 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php @@ -4,13 +4,13 @@ * See COPYING.txt for license details. */ -/** - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Framework\Data\Form\Element; use Magento\Framework\ObjectManagerInterface; +/** + * Form element Factory + */ class Factory { /** From 4d9fab4557a2c704b5f600841abff62778c74ce8 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 10 Oct 2018 16:10:25 +0300 Subject: [PATCH 0602/1415] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Make Gallery management to get product in editable mode. Fix test. --- .../Catalog/Model/Product/Gallery/GalleryManagement.php | 6 +++--- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4d274a071d087..4be4bb09efc98 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -54,7 +54,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) if (!$this->contentValidator->isValid($entryContent)) { throw new InputException(__('The image content is invalid. Verify the content and try again.')); } - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); $existingEntryIds = []; @@ -88,7 +88,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) */ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) { - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException( @@ -129,7 +129,7 @@ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) */ public function remove($sku, $entryId) { - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException( diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 34cebde64d03a..b9993b420f427 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -285,7 +285,6 @@ public function testQueryAllFieldsSimpleProduct() */ public function testQueryMediaGalleryEntryFieldsSimpleProduct() { - $this->markTestSkipped("Skipped until ticket MAGETWO-90021 is resolved."); $productSku = 'simple'; $query = <<<QUERY @@ -453,7 +452,9 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image + small_image { + path + } small_image_label special_from_date special_price From ecb1a7bf306e87eb54a08a7c5a19eac214838ce6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:10:15 +0200 Subject: [PATCH 0603/1415] Another attempt to execute tests --- .travis.yml | 22 ++++---- dev/tests/api-functional/phpunit.xml.dist | 56 ------------------- .../api-functional/phpunit_graphql.xml.dist | 2 +- dev/travis/before_install.sh | 2 +- dev/travis/before_script.sh | 29 ++++++++++ 5 files changed, 43 insertions(+), 68 deletions(-) delete mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/.travis.yml b/.travis.yml index c6077564b923d..930172a9ea6e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: - - TEST_SUITE=unit - - TEST_SUITE=static - - TEST_SUITE=js GRUNT_COMMAND=spec - - TEST_SUITE=js GRUNT_COMMAND=static - - TEST_SUITE=integration INTEGRATION_INDEX=1 - - TEST_SUITE=integration INTEGRATION_INDEX=2 - - TEST_SUITE=integration INTEGRATION_INDEX=3 - - TEST_SUITE=functional +# - TEST_SUITE=unit +# - TEST_SUITE=static +# - TEST_SUITE=js GRUNT_COMMAND=spec +# - TEST_SUITE=js GRUNT_COMMAND=static +# - TEST_SUITE=integration INTEGRATION_INDEX=1 +# - TEST_SUITE=integration INTEGRATION_INDEX=2 +# - TEST_SUITE=integration INTEGRATION_INDEX=3 +# - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: @@ -44,6 +44,8 @@ matrix: env: TEST_SUITE=js GRUNT_COMMAND=static - php: 7.1 env: TEST_SUITE=functional + - php: 7.1 + env: TEST_SUITE=api-functional cache: apt: true directories: @@ -62,6 +64,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - #- if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi + - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/api-functional; fi diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist deleted file mode 100644 index a55531aba87e2..0000000000000 --- a/dev/tests/api-functional/phpunit.xml.dist +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/** - * PHPUnit configuration for GraphQL web API functional tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" - colors="true" - columns="max" - beStrictAboutTestsThatDoNotTestAnything="false" - bootstrap="./framework/bootstrap.php" -> - <!-- Test suites definition --> - <testsuites> - <testsuite name="Magento GraphQL web API functional tests"> - <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> - </testsuite> - </testsuites> - - <!-- PHP INI settings and constants definition --> - <php> - <includePath>./testsuite</includePath> - <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> - <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> - <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento2.travis"/> - <!-- Webserver API user --> - <const name="TESTS_WEBSERVICE_USER" value="admin"/> - <!-- Webserver API key --> - <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> - <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> - <const name="TESTS_XDEBUG_ENABLED" value="false"/> - <!-- Define XDEBUG_SESSION cookie value--> - <const name="TESTS_XDEBUG_SESSION" value="phpstorm" /> - - <ini name="date.timezone" value="America/Los_Angeles"/> - - <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> - <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <!-- Whether to cleanup the application before running tests or not --> - <const name="TESTS_CLEANUP" value="enabled"/> - <!--Defines if Magento should be installed before tests execution--> - <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> - <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="production"/> - </php> - - <!-- Test listeners --> - <listeners> - <listener class="Magento\TestFramework\Event\PhpUnit"/> - </listeners> -</phpunit> diff --git a/dev/tests/api-functional/phpunit_graphql.xml.dist b/dev/tests/api-functional/phpunit_graphql.xml.dist index 955a3a8953fa8..4a57c338ca3a2 100644 --- a/dev/tests/api-functional/phpunit_graphql.xml.dist +++ b/dev/tests/api-functional/phpunit_graphql.xml.dist @@ -27,7 +27,7 @@ <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento2.travis"/> + <const name="TESTS_BASE_URL" value="http://magento.url"/> <!-- Webserver API user --> <const name="TESTS_WEBSERVICE_USER" value="admin"/> <!-- Webserver API key --> diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index c9302f3b6672c..22d6c04dabda4 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" ]; then +if [ $TEST_SUITE = "functional" or $TEST_SUITE = "api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 1dccc310c7a20..c27e65d3897c7 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -132,6 +132,35 @@ case $TEST_SUITE in php -f generate/moduleSequence.php php -f mtf troubleshooting:check-all + cd ../../.. + ;; + + api-functional) + echo "Installing Magento" + mysql -uroot -e 'CREATE DATABASE magento2;' + php bin/magento setup:install -q \ + --language="en_US" \ + --timezone="UTC" \ + --currency="USD" \ + --base-url="http://${MAGENTO_HOST_NAME}/" \ + --admin-firstname="John" \ + --admin-lastname="Doe" \ + --backend-frontname="backend" \ + --admin-email="admin@example.com" \ + --admin-user="admin" \ + --use-rewrites=1 \ + --admin-use-security-key=0 \ + --admin-password="123123q" + + echo "Enabling production mode" + php bin/magento deploy:mode:set production + + echo "Prepare api-functional tests for running" + cd dev/tests/api-functional + + cp ./phpunit_graphql.xml.dist ./phpunit.xml + sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml + cd ../../.. ;; esac From 599cf87a2c7a7eabce65e482557dcfa8f649874c Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:19:47 +0200 Subject: [PATCH 0604/1415] Condition fix for before_install script --- dev/travis/before_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index 22d6c04dabda4..44ba3fd8b74f1 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" or $TEST_SUITE = "api-functional" ]; then +if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi From 09e70057d810aa7004f7760b084d16b4833936b1 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:27:48 +0200 Subject: [PATCH 0605/1415] Test api-functional tests alongside with other tests --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 930172a9ea6e0..f5a25bc63543d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: -# - TEST_SUITE=unit -# - TEST_SUITE=static -# - TEST_SUITE=js GRUNT_COMMAND=spec -# - TEST_SUITE=js GRUNT_COMMAND=static -# - TEST_SUITE=integration INTEGRATION_INDEX=1 -# - TEST_SUITE=integration INTEGRATION_INDEX=2 -# - TEST_SUITE=integration INTEGRATION_INDEX=3 -# - TEST_SUITE=functional + - TEST_SUITE=unit + - TEST_SUITE=static + - TEST_SUITE=js GRUNT_COMMAND=spec + - TEST_SUITE=js GRUNT_COMMAND=static + - TEST_SUITE=integration INTEGRATION_INDEX=1 + - TEST_SUITE=integration INTEGRATION_INDEX=2 + - TEST_SUITE=integration INTEGRATION_INDEX=3 + - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: From 1f05fd8b259b94f272d9c44ae147c5df7910e9ff Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 16 Oct 2018 14:46:29 +0300 Subject: [PATCH 0606/1415] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Delete abandoned tables in full reindex --- .../Catalog/Helper/Product/Flat/Indexer.php | 32 +++++++++++++++++++ .../Indexer/Category/Flat/Action/Full.php | 31 +++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php index 93eaa23b89f16..0366e01ee86ea 100644 --- a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php +++ b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php @@ -466,6 +466,17 @@ public function getFlatTableName($storeId) return sprintf('%s_%s', $this->getTable('catalog_product_flat'), $storeId); } + /** + * Retrieve Catalog Product Flat Table name + * + * @param int $storeId + * @return string + */ + private function getCategoryFlatTableName(int $storeId): string + { + return sprintf('%s_store_%s', $this->getTable('catalog_category_flat'), $storeId); + } + /** * Retrieve loaded attribute by code * @@ -515,4 +526,25 @@ public function deleteAbandonedStoreFlatTables() $connection->dropTable($table); } } + + /** + * Delete all category flat tables for not existing stores + * + * @return void + */ + public function deleteAbandonedStoreCategoryFlatTables() + { + $connection = $this->_resource->getConnection(); + $existentTables = $connection->getTables($connection->getTableName('catalog_category_flat_store_%')); + $actualStoreTables = []; + foreach ($this->_storeManager->getStores() as $store) { + $actualStoreTables[] = $this->getCategoryFlatTableName($store->getId()); + } + + $tablesToDelete = array_diff($existentTables, $actualStoreTables); + + foreach ($tablesToDelete as $table) { + $connection->dropTable($table); + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index 64a8f930d83ee..c1e6decf6afef 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -5,6 +5,11 @@ */ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; +use Magento\Framework\App\ResourceConnection; + +/** + * Class for full reindex flat categories + */ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction { /** @@ -19,6 +24,28 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction */ protected $allowTableChanges = true; + /** + * @var \Magento\Catalog\Helper\Product\Flat\Indexer + */ + private $indexer; + + /** + * @param ResourceConnection $resource + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + * @param \Magento\Catalog\Helper\Product\Flat\Indexer $indexer + */ + public function __construct( + ResourceConnection $resource, + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, + \Magento\Catalog\Helper\Product\Flat\Indexer $indexer = null + ) { + $this->indexer = $indexer ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Catalog\Helper\Product\Flat\Indexer::class); + parent::__construct($resource, $storeManager, $resourceHelper); + } + /** * Add suffix to table name to show it is old * @@ -92,6 +119,7 @@ protected function populateFlatTables(array $stores) /** * Create table and add attributes as fields for specified store. + * * This routine assumes that DDL operations are allowed * * @param int $store @@ -109,6 +137,7 @@ protected function createTable($store) /** * Create category flat tables and add attributes as fields. + * * Tables are created only if DDL operations are allowed * * @param \Magento\Store\Model\Store[] $stores if empty, create tables for all stores of the application @@ -182,7 +211,7 @@ public function reindexAll() $stores = $this->storeManager->getStores(); $this->populateFlatTables($stores); $this->switchTables($stores); - + $this->indexer->deleteAbandonedStoreCategoryFlatTables(); $this->allowTableChanges = true; return $this; From e3fc117bfa5158b51c875e76461539aba5b2b6a7 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 16 Oct 2018 15:33:43 +0300 Subject: [PATCH 0607/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 74661acb8f136..1b0fe4c85f617 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -206,7 +206,7 @@ <label>Images Upload Configuration</label> <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> - <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> + <validate>validate-greater-than-zero validate-digits validate-range required-entry digits-range-1-100</validate> <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> From 11290c5d74cb2a9878735fac7dd4648d1923f71c Mon Sep 17 00:00:00 2001 From: anuj <anuj.gupta701@webkul.com> Date: Tue, 16 Oct 2018 18:42:50 +0530 Subject: [PATCH 0608/1415] issue #18618 fixed --- app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php index bb190260e4776..5059d61eb3f7e 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php @@ -123,7 +123,8 @@ protected function _prepareColumns() 'header' => __('Order Total'), 'index' => 'grand_total', 'type' => 'currency', - 'currency' => 'order_currency_code' + 'currency' => 'order_currency_code', + 'rate' => 1 ] ); From 7691cd09aa475ca1440f3a5ea467d5da556d00c6 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Tue, 16 Oct 2018 17:38:37 +0300 Subject: [PATCH 0609/1415] MAGETWO-94052: CAPTCHA does not appear in "Log in" popup window - Added captcha re-validation mechanism --- .../Model/Customer/Plugin/AjaxLogin.php | 26 +- app/code/Magento/Captcha/etc/di.xml | 2 +- .../view/frontend/web/js/model/captcha.js | 8 +- .../web/js/view/checkout/defaultCaptcha.js | 7 + .../web/js/view/checkout/loginCaptcha.js | 65 ++-- .../web/template/checkout/captcha.html | 6 +- .../Customer/Controller/Ajax/Login.php | 23 +- .../Test/Unit/Controller/Ajax/LoginTest.php | 334 ++++++++++-------- .../view/frontend/web/js/action/login.js | 4 +- 9 files changed, 260 insertions(+), 215 deletions(-) diff --git a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php index 91f3a785df36b..c67211be31659 100644 --- a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php +++ b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php @@ -3,13 +3,19 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Captcha\Model\Customer\Plugin; use Magento\Captcha\Helper\Data as CaptchaHelper; -use Magento\Framework\Session\SessionManagerInterface; +use Magento\Customer\Controller\Ajax\Login; +use Magento\Framework\Controller\Result\Json; use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\Session\SessionManagerInterface; +/** + * The plugin for ajax login controller. + */ class AjaxLogin { /** @@ -61,14 +67,14 @@ public function __construct( } /** - * @param \Magento\Customer\Controller\Ajax\Login $subject + * Validates captcha during request execution. + * + * @param Login $subject * @param \Closure $proceed * @return $this - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function aroundExecute( - \Magento\Customer\Controller\Ajax\Login $subject, + Login $subject, \Closure $proceed ) { $captchaFormIdField = 'captcha_form_id'; @@ -93,24 +99,28 @@ public function aroundExecute( foreach ($this->formIds as $formId) { if ($formId === $loginFormId) { $captchaModel = $this->helper->getCaptcha($formId); + if ($captchaModel->isRequired($username)) { - $captchaModel->logAttempt($username); if (!$captchaModel->isCorrect($captchaString)) { $this->sessionManager->setUsername($username); + $captchaModel->logAttempt($username); return $this->returnJsonError(__('Incorrect CAPTCHA')); } } + + $captchaModel->logAttempt($username); } } return $proceed(); } /** + * Gets Json response. * * @param \Magento\Framework\Phrase $phrase - * @return \Magento\Framework\Controller\Result\Json + * @return Json */ - private function returnJsonError(\Magento\Framework\Phrase $phrase): \Magento\Framework\Controller\Result\Json + private function returnJsonError(\Magento\Framework\Phrase $phrase): Json { $resultJson = $this->resultJsonFactory->create(); return $resultJson->setData(['errors' => true, 'message' => $phrase]); diff --git a/app/code/Magento/Captcha/etc/di.xml b/app/code/Magento/Captcha/etc/di.xml index 3a929f5e6cc00..83c4e8aa1e2c1 100644 --- a/app/code/Magento/Captcha/etc/di.xml +++ b/app/code/Magento/Captcha/etc/di.xml @@ -27,7 +27,7 @@ </arguments> </type> <type name="Magento\Customer\Controller\Ajax\Login"> - <plugin name="configurable_product" type="Magento\Captcha\Model\Customer\Plugin\AjaxLogin" sortOrder="50" /> + <plugin name="captcha_validation" type="Magento\Captcha\Model\Customer\Plugin\AjaxLogin" sortOrder="50" /> </type> <type name="Magento\Captcha\Model\Customer\Plugin\AjaxLogin"> <arguments> diff --git a/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js b/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js index 3a235df73a916..52968e507e6bf 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js @@ -17,7 +17,7 @@ define([ imageSource: ko.observable(captchaData.imageSrc), visibility: ko.observable(false), captchaValue: ko.observable(null), - isRequired: captchaData.isRequired, + isRequired: ko.observable(captchaData.isRequired), isCaseSensitive: captchaData.isCaseSensitive, imageHeight: captchaData.imageHeight, refreshUrl: captchaData.refreshUrl, @@ -41,7 +41,7 @@ define([ * @return {Boolean} */ getIsVisible: function () { - return this.visibility; + return this.visibility(); }, /** @@ -55,14 +55,14 @@ define([ * @return {Boolean} */ getIsRequired: function () { - return this.isRequired; + return this.isRequired(); }, /** * @param {Boolean} flag */ setIsRequired: function (flag) { - this.isRequired = flag; + this.isRequired(flag); }, /** diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js index f80b2ab163ffd..f78b848312702 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js @@ -89,6 +89,13 @@ define([ return this.currentCaptcha !== null ? this.currentCaptcha.getIsRequired() : false; }, + /** + * @param {Boolean} flag + */ + setIsRequired: function (flag) { + this.currentCaptcha.setIsRequired(flag); + }, + /** * @return {Boolean} */ diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js index 7709febea60a3..e017ca6fe274c 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js @@ -4,34 +4,43 @@ */ define([ - 'Magento_Captcha/js/view/checkout/defaultCaptcha', - 'Magento_Captcha/js/model/captchaList', - 'Magento_Customer/js/action/login' -], -function (defaultCaptcha, captchaList, loginAction) { - 'use strict'; - - return defaultCaptcha.extend({ - /** @inheritdoc */ - initialize: function () { - var self = this, - currentCaptcha; - - this._super(); - currentCaptcha = captchaList.getCaptchaByFormId(this.formId); - - if (currentCaptcha != null) { - currentCaptcha.setIsVisible(true); - this.setCurrentCaptcha(currentCaptcha); - - loginAction.registerLoginCallback(function (loginData) { - if (loginData['captcha_form_id'] && - loginData['captcha_form_id'] == self.formId //eslint-disable-line eqeqeq - ) { + 'Magento_Captcha/js/view/checkout/defaultCaptcha', + 'Magento_Captcha/js/model/captchaList', + 'Magento_Customer/js/action/login' + ], + function (defaultCaptcha, captchaList, loginAction) { + 'use strict'; + + return defaultCaptcha.extend({ + /** @inheritdoc */ + initialize: function () { + var self = this, + currentCaptcha; + + this._super(); + currentCaptcha = captchaList.getCaptchaByFormId(this.formId); + + if (currentCaptcha != null) { + currentCaptcha.setIsVisible(true); + this.setCurrentCaptcha(currentCaptcha); + + loginAction.registerLoginCallback(function (loginData, response) { + if (!response.errors) { + return; + } + + if (!loginData['captcha_form_id'] || loginData['captcha_form_id'] !== self.formId) { + return; + } + + // check if captcha should be required after login attempt + if (!self.isRequired() && response.captcha && self.isRequired() !== response.captcha) { + self.setIsRequired(response.captcha); + } + self.refresh(); - } - }); + }); + } } - } + }); }); -}); diff --git a/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html b/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html index 575b3ca6f732e..8923c81bf4bb3 100644 --- a/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html +++ b/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html @@ -4,12 +4,14 @@ * See COPYING.txt for license details. */ --> +<!-- ko if: (getIsVisible())--> +<input name="captcha_form_id" type="hidden" data-bind="value: formId, attr: {'data-scope': dataScope}" /> +<!-- /ko --> <!-- ko if: (isRequired() && getIsVisible())--> <div class="field captcha required" data-bind="blockLoader: getIsLoading()"> <label data-bind="attr: {for: 'captcha_' + formId}" class="label"><span data-bind="i18n: 'Please type the letters and numbers below'"></span></label> <div class="control captcha"> - <input name="captcha_string" type="text" class="input-text required-entry" data-bind="value: captchaValue(), attr: {id: 'captcha_' + formId, 'data-scope': dataScope}" autocomplete="off"/> - <input name="captcha_form_id" type="hidden" data-bind="value: formId, attr: {'data-scope': dataScope}" /> + <input name="captcha_string" type="text" class="input-text required-entry" data-bind="value: captchaValue(), attr: {'data-scope': dataScope}" autocomplete="off"/> <div class="nested"> <div class="field captcha no-label"> <div class="control captcha-image"> diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index 7d1e86c949792..6d0f8c036b290 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -107,7 +107,6 @@ public function __construct( /** * Get account redirect. - * For release backward compatibility. * * @deprecated 100.0.10 * @return AccountRedirect @@ -133,6 +132,8 @@ public function setAccountRedirect($value) } /** + * Initializes config dependency. + * * @deprecated 100.0.10 * @return ScopeConfigInterface */ @@ -145,6 +146,8 @@ protected function getScopeConfig() } /** + * Sets config dependency. + * * @deprecated 100.0.10 * @param ScopeConfigInterface $value * @return void @@ -199,25 +202,17 @@ public function execute() $response['redirectUrl'] = $this->_redirect->success($redirectRoute); $this->getAccountRedirect()->clearRedirectCookie(); } - } catch (EmailNotConfirmedException $e) { - $response = [ - 'errors' => true, - 'message' => $e->getMessage() - ]; - } catch (InvalidEmailOrPasswordException $e) { - $response = [ - 'errors' => true, - 'message' => $e->getMessage() - ]; - } catch (LocalizedException $e) { + } catch (LocalizedException | InvalidEmailOrPasswordException | EmailNotConfirmedException $e) { $response = [ 'errors' => true, - 'message' => $e->getMessage() + 'message' => $e->getMessage(), + 'captcha' => $this->customerSession->getData('user_login_show_captcha') ]; } catch (\Exception $e) { $response = [ 'errors' => true, - 'message' => __('Invalid login or password.') + 'message' => __('Invalid login or password.'), + 'captcha' => $this->customerSession->getData('user_login_show_captcha') ]; } /** @var \Magento\Framework\Controller\Result\Json $resultJson */ diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php index aaaa799a5e26d..628727b202ba7 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Ajax/LoginTest.php @@ -3,13 +3,32 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -/** - * Test customer ajax login controller - */ namespace Magento\Customer\Test\Unit\Controller\Ajax; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Controller\Ajax\Login; +use Magento\Customer\Model\Account\Redirect; +use Magento\Customer\Model\AccountManagement; +use Magento\Customer\Model\Session; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Request\Http; +use Magento\Framework\App\Response\RedirectInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\Controller\Result\Json; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\Controller\Result\Raw; +use Magento\Framework\Controller\Result\RawFactory; use Magento\Framework\Exception\InvalidEmailOrPasswordException; +use Magento\Framework\Json\Helper\Data; +use Magento\Framework\ObjectManager\ObjectManager as FakeObjectManager; +use Magento\Framework\Stdlib\Cookie\CookieMetadata; +use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; +use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -17,223 +36,190 @@ class LoginTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Customer\Controller\Ajax\Login + * @var Login */ - protected $object; + private $controller; /** - * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject + * @var Http|MockObject */ - protected $request; + private $request; /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResponseInterface|MockObject */ - protected $response; + private $response; /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var Session|MockObject */ - protected $customerSession; + private $customerSession; /** - * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FakeObjectManager|MockObject */ - protected $objectManager; + private $objectManager; /** - * @var \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject + * @var AccountManagement|MockObject */ - protected $customerAccountManagementMock; + private $accountManagement; /** - * @var \Magento\Framework\Json\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + * @var Data|MockObject */ - protected $jsonHelperMock; + private $jsonHelper; /** - * @var \Magento\Framework\Controller\Result\Json|\PHPUnit_Framework_MockObject_MockObject + * @var Json|MockObject */ - protected $resultJson; + private $resultJson; /** - * @var \Magento\Framework\Controller\Result\JsonFactory| \PHPUnit_Framework_MockObject_MockObject + * @var JsonFactory|MockObject */ - protected $resultJsonFactory; + private $resultJsonFactory; /** - * @var \Magento\Framework\Controller\Result\Raw| \PHPUnit_Framework_MockObject_MockObject + * @var Raw|MockObject */ - protected $resultRaw; + private $resultRaw; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var RedirectInterface|MockObject */ - protected $redirectMock; + private $redirect; /** - * @var \Magento\Framework\Stdlib\CookieManagerInterface| \PHPUnit_Framework_MockObject_MockObject + * @var CookieManagerInterface|MockObject */ private $cookieManager; /** - * @var \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory| \PHPUnit_Framework_MockObject_MockObject + * @var CookieMetadataFactory|MockObject */ private $cookieMetadataFactory; /** - * @var \Magento\Framework\Stdlib\Cookie\CookieMetadata| \PHPUnit_Framework_MockObject_MockObject + * @inheritdoc */ - private $cookieMetadata; - - protected function setUp() + protected function setUp(): void { - $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) - ->disableOriginalConstructor()->getMock(); + $this->request = $this->getMockBuilder(Http::class) + ->disableOriginalConstructor() + ->getMock(); $this->response = $this->createPartialMock( - \Magento\Framework\App\ResponseInterface::class, + ResponseInterface::class, ['setRedirect', 'sendResponse', 'representJson', 'setHttpResponseCode'] ); $this->customerSession = $this->createPartialMock( - \Magento\Customer\Model\Session::class, + Session::class, [ 'isLoggedIn', 'getLastCustomerId', 'getBeforeAuthUrl', 'setBeforeAuthUrl', 'setCustomerDataAsLoggedIn', - 'regenerateId' + 'regenerateId', + 'getData' ] ); - $this->objectManager = $this->createPartialMock(\Magento\Framework\ObjectManager\ObjectManager::class, ['get']); - $this->customerAccountManagementMock = - $this->createPartialMock(\Magento\Customer\Model\AccountManagement::class, ['authenticate']); + $this->objectManager = $this->createPartialMock(FakeObjectManager::class, ['get']); + $this->accountManagement = $this->createPartialMock(AccountManagement::class, ['authenticate']); - $this->jsonHelperMock = $this->createPartialMock(\Magento\Framework\Json\Helper\Data::class, ['jsonDecode']); + $this->jsonHelper = $this->createPartialMock(Data::class, ['jsonDecode']); - $this->resultJson = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class) + $this->resultJson = $this->getMockBuilder(Json::class) ->disableOriginalConstructor() ->getMock(); - $this->resultJsonFactory = $this->getMockBuilder(\Magento\Framework\Controller\Result\JsonFactory::class) + $this->resultJsonFactory = $this->getMockBuilder(JsonFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $this->cookieManager = $this->getMockBuilder(\Magento\Framework\Stdlib\CookieManagerInterface::class) + $this->cookieManager = $this->getMockBuilder(CookieManagerInterface::class) ->setMethods(['getCookie', 'deleteCookie']) ->getMockForAbstractClass(); - $this->cookieMetadataFactory = $this->getMockBuilder( - \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class - )->disableOriginalConstructor()->getMock(); - $this->cookieMetadata = $this->getMockBuilder(\Magento\Framework\Stdlib\Cookie\CookieMetadata::class) + $this->cookieMetadataFactory = $this->getMockBuilder(CookieMetadataFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->resultRaw = $this->getMockBuilder(\Magento\Framework\Controller\Result\Raw::class) + $this->resultRaw = $this->getMockBuilder(Raw::class) ->disableOriginalConstructor() ->getMock(); - $resultRawFactory = $this->getMockBuilder(\Magento\Framework\Controller\Result\RawFactory::class) + $resultRawFactory = $this->getMockBuilder(RawFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $resultRawFactory->expects($this->atLeastOnce()) - ->method('create') + $resultRawFactory->method('create') ->willReturn($this->resultRaw); - $contextMock = $this->createMock(\Magento\Framework\App\Action\Context::class); - $this->redirectMock = $this->createMock(\Magento\Framework\App\Response\RedirectInterface::class); - $contextMock->expects($this->atLeastOnce())->method('getRedirect')->willReturn($this->redirectMock); - $contextMock->expects($this->atLeastOnce())->method('getRequest')->willReturn($this->request); - - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->object = $objectManager->getObject( - \Magento\Customer\Controller\Ajax\Login::class, + /** @var Context|MockObject $context */ + $context = $this->createMock(Context::class); + $this->redirect = $this->createMock(RedirectInterface::class); + $context->method('getRedirect') + ->willReturn($this->redirect); + $context->method('getRequest') + ->willReturn($this->request); + + $objectManager = new ObjectManager($this); + $this->controller = $objectManager->getObject( + Login::class, [ - 'context' => $contextMock, + 'context' => $context, 'customerSession' => $this->customerSession, - 'helper' => $this->jsonHelperMock, + 'helper' => $this->jsonHelper, 'response' => $this->response, 'resultRawFactory' => $resultRawFactory, 'resultJsonFactory' => $this->resultJsonFactory, 'objectManager' => $this->objectManager, - 'customerAccountManagement' => $this->customerAccountManagementMock, + 'customerAccountManagement' => $this->accountManagement, 'cookieManager' => $this->cookieManager, 'cookieMetadataFactory' => $this->cookieMetadataFactory ] ); } - public function testLogin() + /** + * Checks successful login. + */ + public function testLogin(): void { $jsonRequest = '{"username":"customer@example.com", "password":"password"}'; $loginSuccessResponse = '{"errors": false, "message":"Login successful."}'; + $this->withRequest($jsonRequest); - $this->request - ->expects($this->any()) - ->method('getContent') - ->willReturn($jsonRequest); - - $this->request - ->expects($this->any()) - ->method('getMethod') - ->willReturn('POST'); - - $this->request - ->expects($this->any()) - ->method('isXmlHttpRequest') - ->willReturn(true); - - $this->resultJsonFactory->expects($this->atLeastOnce()) - ->method('create') + $this->resultJsonFactory->method('create') ->willReturn($this->resultJson); - $this->jsonHelperMock - ->expects($this->any()) - ->method('jsonDecode') + $this->jsonHelper->method('jsonDecode') ->with($jsonRequest) ->willReturn(['username' => 'customer@example.com', 'password' => 'password']); - $customerMock = $this->getMockForAbstractClass(\Magento\Customer\Api\Data\CustomerInterface::class); - $this->customerAccountManagementMock - ->expects($this->any()) - ->method('authenticate') + /** @var CustomerInterface|MockObject $customer */ + $customer = $this->getMockForAbstractClass(CustomerInterface::class); + $this->accountManagement->method('authenticate') ->with('customer@example.com', 'password') - ->willReturn($customerMock); + ->willReturn($customer); - $this->customerSession->expects($this->once()) - ->method('setCustomerDataAsLoggedIn') - ->with($customerMock); + $this->customerSession->method('setCustomerDataAsLoggedIn') + ->with($customer); + $this->customerSession->method('regenerateId'); - $this->customerSession->expects($this->once())->method('regenerateId'); + /** @var Redirect|MockObject $redirect */ + $redirect = $this->createMock(Redirect::class); + $this->controller->setAccountRedirect($redirect); + $redirect->method('getRedirectCookie') + ->willReturn('some_url1'); - $redirectMock = $this->createMock(\Magento\Customer\Model\Account\Redirect::class); - $this->object->setAccountRedirect($redirectMock); - $redirectMock->expects($this->once())->method('getRedirectCookie')->willReturn('some_url1'); + $this->withCookieManager(); - $this->cookieManager->expects($this->once()) - ->method('getCookie') - ->with('mage-cache-sessid') - ->willReturn(true); - $this->cookieMetadataFactory->expects($this->once()) - ->method('createCookieMetadata') - ->willReturn($this->cookieMetadata); - $this->cookieMetadata->expects($this->once()) - ->method('setPath') - ->with('/') - ->willReturnSelf(); - $this->cookieManager->expects($this->once()) - ->method('deleteCookie') - ->with('mage-cache-sessid', $this->cookieMetadata) - ->willReturnSelf(); + $this->withScopeConfig(); - $scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $this->object->setScopeConfig($scopeConfigMock); - $scopeConfigMock->expects($this->once())->method('getValue') - ->with('customer/startup/redirect_dashboard') - ->willReturn(0); - - $this->redirectMock->expects($this->once())->method('success')->willReturn('some_url2'); - $this->resultRaw->expects($this->never())->method('setHttpResponseCode'); + $this->redirect->method('success') + ->willReturn('some_url2'); + $this->resultRaw->expects(self::never()) + ->method('setHttpResponseCode'); $result = [ 'errors' => false, @@ -241,67 +227,103 @@ public function testLogin() 'redirectUrl' => 'some_url2', ]; - $this->resultJson - ->expects($this->once()) - ->method('setData') + $this->resultJson->method('setData') ->with($result) ->willReturn($loginSuccessResponse); - $this->assertEquals($loginSuccessResponse, $this->object->execute()); + self::assertEquals($loginSuccessResponse, $this->controller->execute()); } - public function testLoginFailure() + /** + * Checks unsuccessful login. + */ + public function testLoginFailure(): void { $jsonRequest = '{"username":"invalid@example.com", "password":"invalid"}'; $loginFailureResponse = '{"message":"Invalid login or password."}'; + $this->withRequest($jsonRequest); - $this->request - ->expects($this->any()) - ->method('getContent') - ->willReturn($jsonRequest); - - $this->request - ->expects($this->any()) - ->method('getMethod') - ->willReturn('POST'); - - $this->request - ->expects($this->any()) - ->method('isXmlHttpRequest') - ->willReturn(true); - - $this->resultJsonFactory->expects($this->once()) - ->method('create') + $this->resultJsonFactory->method('create') ->willReturn($this->resultJson); - $this->jsonHelperMock - ->expects($this->any()) - ->method('jsonDecode') + $this->jsonHelper->method('jsonDecode') ->with($jsonRequest) ->willReturn(['username' => 'invalid@example.com', 'password' => 'invalid']); - $customerMock = $this->getMockForAbstractClass(\Magento\Customer\Api\Data\CustomerInterface::class); - $this->customerAccountManagementMock - ->expects($this->any()) - ->method('authenticate') + /** @var CustomerInterface|MockObject $customer */ + $customer = $this->getMockForAbstractClass(CustomerInterface::class); + $this->accountManagement->method('authenticate') ->with('invalid@example.com', 'invalid') ->willThrowException(new InvalidEmailOrPasswordException(__('Invalid login or password.'))); - $this->customerSession->expects($this->never()) + $this->customerSession->expects(self::never()) ->method('setCustomerDataAsLoggedIn') - ->with($customerMock); - - $this->customerSession->expects($this->never())->method('regenerateId'); + ->with($customer); + $this->customerSession->expects(self::never()) + ->method('regenerateId'); + $this->customerSession->method('getData') + ->with('user_login_show_captcha') + ->willReturn(false); $result = [ 'errors' => true, - 'message' => __('Invalid login or password.') + 'message' => __('Invalid login or password.'), + 'captcha' => false ]; - $this->resultJson - ->expects($this->once()) - ->method('setData') + $this->resultJson->method('setData') ->with($result) ->willReturn($loginFailureResponse); - $this->assertEquals($loginFailureResponse, $this->object->execute()); + self::assertEquals($loginFailureResponse, $this->controller->execute()); + } + + /** + * Emulates request behavior. + * + * @param string $jsonRequest + */ + private function withRequest(string $jsonRequest): void + { + $this->request->method('getContent') + ->willReturn($jsonRequest); + + $this->request->method('getMethod') + ->willReturn('POST'); + + $this->request->method('isXmlHttpRequest') + ->willReturn(true); + } + + /** + * Emulates cookie manager behavior. + */ + private function withCookieManager(): void + { + $this->cookieManager->method('getCookie') + ->with('mage-cache-sessid') + ->willReturn(true); + $cookieMetadata = $this->getMockBuilder(CookieMetadata::class) + ->disableOriginalConstructor() + ->getMock(); + $this->cookieMetadataFactory->method('createCookieMetadata') + ->willReturn($cookieMetadata); + $cookieMetadata->method('setPath') + ->with('/') + ->willReturnSelf(); + $this->cookieManager->method('deleteCookie') + ->with('mage-cache-sessid', $cookieMetadata) + ->willReturnSelf(); + } + + /** + * Emulates config behavior. + */ + private function withScopeConfig(): void + { + /** @var ScopeConfigInterface|MockObject $scopeConfig */ + $scopeConfig = $this->createMock(ScopeConfigInterface::class); + $this->controller->setScopeConfig($scopeConfig); + $scopeConfig->method('getValue') + ->with('customer/startup/redirect_dashboard') + ->willReturn(0); } } diff --git a/app/code/Magento/Customer/view/frontend/web/js/action/login.js b/app/code/Magento/Customer/view/frontend/web/js/action/login.js index d75b8f70c5346..0015e2732e383 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/action/login.js +++ b/app/code/Magento/Customer/view/frontend/web/js/action/login.js @@ -31,11 +31,11 @@ define([ if (response.errors) { messageContainer.addErrorMessage(response); callbacks.forEach(function (callback) { - callback(loginData); + callback(loginData, response); }); } else { callbacks.forEach(function (callback) { - callback(loginData); + callback(loginData, response); }); customerData.invalidate(['customer']); From 2f9b761f368b925dc6563e3c6e791425005286a3 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Tue, 16 Oct 2018 10:27:21 -0500 Subject: [PATCH 0610/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../Framework/Indexer/IndexStructure.php | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/IndexStructure.php b/lib/internal/Magento/Framework/Indexer/IndexStructure.php index c9376f00b711e..a39de2d5b8a62 100644 --- a/lib/internal/Magento/Framework/Indexer/IndexStructure.php +++ b/lib/internal/Magento/Framework/Indexer/IndexStructure.php @@ -13,6 +13,12 @@ use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver; use Magento\Framework\Search\Request\Dimension; +/** + * Full text search index structure. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class IndexStructure implements IndexStructureInterface { /** @@ -58,9 +64,7 @@ public function __construct( } /** - * @param string $index - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function delete($index, array $dimensions = []) { @@ -69,10 +73,7 @@ public function delete($index, array $dimensions = []) } /** - * @param string $index - * @param array $fields - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function create($index, array $fields, array $dimensions = []) { @@ -83,6 +84,8 @@ public function create($index, array $fields, array $dimensions = []) } /** + * Create full text index. + * * @param string $tableName * @throws \Zend_Db_Exception * @return void @@ -94,6 +97,8 @@ protected function createFulltextIndex($tableName) } /** + * Configure full text index table. + * * @param Table $table * @return Table */ @@ -129,6 +134,8 @@ protected function configureFulltextTable(Table $table) } /** + * Create flat index. + * * @param string $tableName * @param array $fields * @throws \Zend_Db_Exception @@ -160,6 +167,8 @@ protected function createFlatIndex($tableName, array $fields) } /** + * Drop table. + * * @param AdapterInterface $connection * @param string $tableName * @return void From 11b4c70bb1807e1db9703f8b0fa241de9790e512 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 16 Oct 2018 11:10:29 -0500 Subject: [PATCH 0611/1415] MAGETWO-95723: Product Review "Save and Next" and "Save and Previous" not working - Fixed query ordering - Added test coverage --- .../Review/Product/Collection.php | 1 - .../Review/Product/CollectionTest.php | 73 ++++++++++++++++++- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 99c963501a9d4..68dc8d753b5bd 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -406,7 +406,6 @@ public function getResultingIds() $idsSelect->reset(Select::LIMIT_COUNT); $idsSelect->reset(Select::LIMIT_OFFSET); $idsSelect->reset(Select::COLUMNS); - $idsSelect->reset(Select::ORDER); $idsSelect->columns('rt.review_id'); return $this->getConnection()->fetchCol($idsSelect); } diff --git a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php index a7f859b23dfa2..39129dee28c7c 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php @@ -3,20 +3,85 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Review\Model\ResourceModel\Review\Product; class CollectionTest extends \PHPUnit\Framework\TestCase { /** + * @param string $status + * @param int $expectedCount + * @param string $sortAttribute + * @param string $dir + * @param callable $assertion + * @dataProvider sortOrderAssertionsDataProvider * @magentoDataFixture Magento/Review/_files/different_reviews.php */ - public function testGetResultingIds() - { + public function testGetResultingIds( + ?string $status, + int $expectedCount, + string $sortAttribute, + string $dir, + callable $assertion + ) { + /** + * @var $collection \Magento\Review\Model\ResourceModel\Review\Product\Collection + */ $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Review\Model\ResourceModel\Review\Product\Collection::class ); - $collection->addStatusFilter(\Magento\Review\Model\Review::STATUS_APPROVED); + if ($status) { + $collection->addStatusFilter($status); + } + $collection->setOrder($sortAttribute, $dir); $actual = $collection->getResultingIds(); - $this->assertCount(2, $actual); + $this->assertCount($expectedCount, $actual); + $assertion($actual); + } + + /** + * @return array + */ + public function sortOrderAssertionsDataProvider() :array + { + return [ + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'DESC', + function (array $actual) :void { + $this->assertLessThan($actual[0], $actual[1]); + } + ], + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.created_at', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + null, + 3, + 'rt.review_id', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ] + ]; } } From 21fdaddba19cb329b58b6ee2efb74cb2298049ce Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 16 Oct 2018 12:09:57 -0500 Subject: [PATCH 0612/1415] MAGETWO-94962: Unable to set default option for swatch attribute --- .../Catalog/Test/Handler/CatalogProductAttribute/Curl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index 7ecaeb5ea7b82..3d644a2a32274 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -144,6 +144,10 @@ public function persist(FixtureInterface $fixture = null) */ protected function changeStructureOfTheData(array $data): array { + if (!isset($data['options'])) { + return $data; + } + $serializedOptions = $this->getSerializeOptions($data['options']); if ($serializedOptions) { $data['serialized_options'] = $serializedOptions; From a2c993a58a43db0fe0a51bd1d1b482d7a05f1e8f Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 16 Oct 2018 12:24:15 -0500 Subject: [PATCH 0613/1415] MAGETWO-95433: Customer address custom attributes (Multi select, dropdown) display behavior on storefront is not per standards (PFA snap) - make sure multiselect doesn't show background image --- lib/web/css/source/lib/_forms.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/css/source/lib/_forms.less b/lib/web/css/source/lib/_forms.less index b1c7a49da4a7a..531cf3d34ad76 100644 --- a/lib/web/css/source/lib/_forms.less +++ b/lib/web/css/source/lib/_forms.less @@ -288,7 +288,7 @@ .lib-form-element-input(@_type: select); } - select[multiple="multiple"] { + select[multiple] { .lib-css(height, auto); background-image: none; } From 2773aeba9f0b6daeb98c0f2f7326e831d7018cb4 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Tue, 16 Oct 2018 13:13:49 -0500 Subject: [PATCH 0614/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../Model/Search/RequestGenerator/Decimal.php | 7 +++---- .../Model/Search/RequestGenerator/General.php | 7 +++---- .../Search/RequestGenerator/GeneratorInterface.php | 10 ++++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php index ceff0ea2e5d17..b3d39a48fe9fc 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php @@ -11,13 +11,12 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search range request generator. */ class Decimal implements GeneratorInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function getFilterData(Attribute $attribute, $filterName) { @@ -31,7 +30,7 @@ public function getFilterData(Attribute $attribute, $filterName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAggregationData(Attribute $attribute, $bucketName) { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php index 4321105a7e8fd..63b09de7f08d8 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php @@ -11,13 +11,12 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search request generator. */ class General implements GeneratorInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function getFilterData(Attribute $attribute, $filterName) { @@ -30,7 +29,7 @@ public function getFilterData(Attribute $attribute, $filterName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAggregationData(Attribute $attribute, $bucketName) { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php index 863f1fb7466c9..22f829063fbe7 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php @@ -9,15 +9,16 @@ use Magento\Catalog\Model\ResourceModel\Eav\Attribute; /** + * Catalog search reguest generator interface. + * * @api * @since 100.1.6 - * @deprecated - * @see \Magento\ElasticSearch */ interface GeneratorInterface { /** - * Get filter data for specific attribute + * Get filter data for specific attribute. + * * @param Attribute $attribute * @param string $filterName * @return array @@ -26,7 +27,8 @@ interface GeneratorInterface public function getFilterData(Attribute $attribute, $filterName); /** - * Get aggregation data for specific attribute + * Get aggregation data for specific attribute. + * * @param Attribute $attribute * @param string $bucketName * @return array From bd6c51afe863e05111a6b4da8e095a3341d67a12 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 16 Oct 2018 14:42:05 -0500 Subject: [PATCH 0615/1415] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Fixed static error --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index 4f05279350a7c..e7776b3dcbedc 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -15,10 +15,11 @@ class ResetQuoteAddresses { /** + * Clears the quote addresses when all the items are removed from the cart + * * @param Quote $quote * @param Quote $result * @param mixed $itemId - * * @return Quote * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ From 7ca8b43efd55e431feea791f56c9ecd1d8e8d9b2 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Tue, 16 Oct 2018 22:40:54 -0500 Subject: [PATCH 0616/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 - added step to check if config tab for wysiwyg is opened --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 +- .../Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 5ae3f4af2421e..84bc3865a008e 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -19,7 +19,7 @@ <testCaseId value="MAGETWO-95725"/> </annotations> <before> - <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <!-- Choose TinyMCE3 as the default WYSIWYG editor--> <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 836cba95a6d00..2d784842ea46a 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -21,6 +21,7 @@ </actionGroup> <actionGroup name="SwitchToTinyMCE3"> <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <conditionalClick stepKey="expandWYSIWYGOptions1" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown2" /> From d5594fc7dd8e93ded92576925f903bffd3a686ad Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 16 Oct 2018 23:55:26 -0500 Subject: [PATCH 0617/1415] MAGETWO-95645: Custom file attribute works incorrect --- .../Magento/Eav/Model/Attribute/Data/File.php | 17 ++++++++++++--- .../jasmine/tests/lib/mage/validation.test.js | 20 ++++++++++++++++++ .../Framework/Data/Form/Element/Text.php | 1 + lib/web/mage/validation.js | 21 +++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index 5e2e2716e13d2..3d73ffa378232 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -147,7 +147,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (!is_uploaded_file($value['tmp_name'])) { + if (!empty($value['tmp_name']) && !is_uploaded_file($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } @@ -174,12 +174,21 @@ public function validateValue($value) if ($this->getIsAjaxRequest()) { return true; } + $fileData = $value; + + if (is_string($value) && !empty($value)) { + $dir = $this->_directory->getAbsolutePath($this->getAttribute()->getEntityType()->getEntityTypeCode()); + $fileData = [ + 'size' => filesize($dir . $value), + 'name' => $value + ]; + } $errors = []; $attribute = $this->getAttribute(); $toDelete = !empty($value['delete']) ? true : false; - $toUpload = !empty($value['tmp_name']) ? true : false; + $toUpload = !empty($value['tmp_name']) || is_string($value) && !empty($value) ? true : false; if (!$toUpload && !$toDelete && $this->getEntity()->getData($attribute->getAttributeCode())) { return true; @@ -195,11 +204,13 @@ public function validateValue($value) } if ($toUpload) { - $errors = array_merge($errors, $this->_validateByRules($value)); + $errors = array_merge($errors, $this->_validateByRules($fileData)); } if (count($errors) == 0) { return true; + } elseif (is_string($value) && !empty($value)) { + $this->_directory->delete($dir . $value); } return $errors; diff --git a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js index 1e1203d22a1e3..ca9ec877013f8 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js @@ -1142,4 +1142,24 @@ define([ )).toEqual(true); }); }); + + describe('Testing validate-forbidden-extensions', function () { + it('validate-forbidden-extensions', function () { + var el1 = $('<input type="text" value="" ' + + 'class="validate-extensions" data-validation-params="php,phtml">').get(0); + + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'php', el1, null)).toEqual(false); + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'php,phtml', el1, null)).toEqual(false); + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'html', el1, null)).toEqual(true); + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'html,png', el1, null)).toEqual(true); + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'php,html', el1, null)).toEqual(false); + expect($.validator.methods['validate-forbidden-extensions'] + .call($.validator.prototype, 'html,php', el1, null)).toEqual(false); + }); + }); }); diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Text.php b/lib/internal/Magento/Framework/Data/Form/Element/Text.php index eb157c7279a71..b7b084310ed14 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Text.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Text.php @@ -65,6 +65,7 @@ public function getHtmlAttributes() 'placeholder', 'data-form-part', 'data-role', + 'data-validation-params', 'data-action' ]; } diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 86dd5a3b03681..e79cc3cd24d83 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -881,6 +881,27 @@ }, $.mage.__('Please enter a valid number in this field.') ], + 'validate-forbidden-extensions': [ + function (v, elem) { + var forbiddenExtensions = $(elem).attr('data-validation-params'), + forbiddenExtensionsArray = forbiddenExtensions.split(','), + extensionsArray = v.split(','), + result = true; + + this.validateExtensionsMessage = $.mage.__('Forbidden extensions has been used. Avoid usage of ') + + forbiddenExtensions; + + $.each(extensionsArray, function (key, extension) { + if (forbiddenExtensionsArray.indexOf(extension) !== -1) { + result = false; + } + }); + + return result; + }, function () { + return this.validateExtensionsMessage; + } + ], 'validate-digits-range': [ function (v, elm, param) { var numValue, dataAttrRange, classNameRange, result, range, m, classes, ii; From af3de710de5d11d12548b8342f6978cc435ac9c0 Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Wed, 17 Oct 2018 09:01:06 +0300 Subject: [PATCH 0618/1415] MAGETWO-95275: Varnish "Connection reset by peer" error when large catalog is reindexed on schedule --- app/code/Magento/CacheInvalidate/Model/PurgeCache.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php index 57e29d11495a2..727e18280d76f 100644 --- a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php +++ b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php @@ -7,6 +7,9 @@ use Magento\Framework\Cache\InvalidateLogger; +/** + * Class PurgeCache + */ class PurgeCache { const HEADER_X_MAGENTO_TAGS_PATTERN = 'X-Magento-Tags-Pattern'; @@ -56,8 +59,7 @@ public function __construct( } /** - * Send curl purge request - * to invalidate cache by tags pattern + * Send curl purge request to invalidate cache by tags pattern * * @param string $tagsPattern * @return bool Return true if successful; otherwise return false @@ -106,8 +108,7 @@ private function splitTags($tagsPattern) } /** - * Send curl purge request to servers - * to invalidate cache by tags pattern + * Send curl purge request to servers to invalidate cache by tags pattern * * @param \Zend\Http\Client\Adapter\Socket $socketAdapter * @param \Zend\Uri\Uri[] $servers From 85961ca8e08b488d7efd4cfd12bbb540af0dea59 Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Wed, 17 Oct 2018 14:46:54 +0530 Subject: [PATCH 0619/1415] Fixed class name issue in comment --- app/code/Magento/AdminNotification/Block/Window.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Window.php b/app/code/Magento/AdminNotification/Block/Window.php index 9563626ee2577..90a0a1d21d865 100644 --- a/app/code/Magento/AdminNotification/Block/Window.php +++ b/app/code/Magento/AdminNotification/Block/Window.php @@ -40,7 +40,7 @@ class Window extends \Magento\Backend\Block\Template protected $_criticalCollection; /** - * @var \Magento\Adminnotification\Model\Inbox + * @var \Magento\AdminNotification\Model\Inbox */ protected $_latestItem; @@ -92,7 +92,7 @@ protected function _toHtml() /** * Retrieve latest critical item * - * @return bool|\Magento\Adminnotification\Model\Inbox + * @return bool|\Magento\AdminNotification\Model\Inbox */ protected function _getLatestItem() { From 10d4a59cf31fce794b2ac3d2ddd12eea16a1f43e Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Wed, 17 Oct 2018 15:26:34 +0200 Subject: [PATCH 0620/1415] Remove unnecessary class import, see #18117 --- app/code/Magento/Customer/Model/GroupManagement.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/GroupManagement.php b/app/code/Magento/Customer/Model/GroupManagement.php index eb5d90f2fd7ea..48cb5d55061c5 100644 --- a/app/code/Magento/Customer/Model/GroupManagement.php +++ b/app/code/Magento/Customer/Model/GroupManagement.php @@ -15,7 +15,6 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Data\Collection; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\StoreManagerInterface; @@ -170,7 +169,7 @@ public function getLoggedInGroups() ->create(); $groupNameSortOrder = $this->sortOrderBuilder ->setField('customer_group_code') - ->setDirection(Collection::SORT_ORDER_ASC) + ->setAscendingDirection() ->create(); $searchCriteria = $this->searchCriteriaBuilder ->addFilters($notLoggedInFilter) From 1a92f1c1609445c7b6b107a165d387e306f2f779 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 17 Oct 2018 16:43:20 +0300 Subject: [PATCH 0621/1415] magento-engcom/magento2ce#2252: Code style fixes --- .../Product/Attribute/Set/Main/Formgroup.php | 7 ++++ .../Model/Config/Backend/Currency/Cron.php | 4 +++ .../Config/Model/Config/Backend/Log/Cron.php | 2 ++ .../Model/Config/Backend/Product/Alert.php | 5 ++- .../Cron/Model/Config/Backend/Sitemap.php | 5 +++ .../Adminhtml/Edit/Tab/View/PersonalInfo.php | 3 +- app/code/Magento/Customer/Model/Address.php | 11 ++++-- app/code/Magento/Customer/Model/Customer.php | 6 ++++ .../Customer/Model/Renderer/Region.php | 2 ++ .../ResourceModel/CustomerRepository.php | 12 +++---- app/code/Magento/Customer/Model/Visitor.php | 3 ++ app/code/Magento/Directory/Block/Data.php | 16 +++++++++ .../Model/ResourceModel/Entity/Attribute.php | 11 +++--- .../Model/Adapter/Elasticsearch.php | 3 +- .../SearchAdapter/Dynamic/DataProvider.php | 12 ++++--- .../Model/Product/Type/Grouped.php | 16 +++++++-- .../Magento/Paypal/Model/Api/AbstractApi.php | 4 ++- app/code/Magento/Paypal/Model/Express.php | 6 ++++ .../Paypal/Model/Report/Settlement.php | 2 ++ app/code/Magento/Persistent/Helper/Data.php | 2 ++ app/code/Magento/Persistent/Model/Session.php | 1 + .../Review/Block/Rating/Entity/Detailed.php | 2 ++ .../Adminhtml/Product/JsonProductInfo.php | 5 +++ .../Magento/Sales/Api/Data/OrderInterface.php | 1 + .../Sales/Api/Data/OrderItemInterface.php | 1 + app/code/Magento/Sales/Model/Order.php | 1 + app/code/Magento/Sales/Model/Order/Item.php | 1 + .../Tax/Block/Adminhtml/Rate/Toolbar/Save.php | 7 ++++ app/code/Magento/Theme/Block/Html/Pager.php | 34 +++++++++++++++++++ app/code/Magento/User/Block/Buttons.php | 14 ++++++++ app/code/Magento/Wishlist/Helper/Rss.php | 2 ++ 31 files changed, 176 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php index d12b280e2341c..26ffc6e0df3d9 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Set/Main/Formgroup.php @@ -11,6 +11,9 @@ use Magento\Backend\Block\Widget\Form; +/** + * Form group for attribute set + */ class Formgroup extends \Magento\Backend\Block\Widget\Form\Generic { /** @@ -37,6 +40,8 @@ public function __construct( } /** + * Prepare form elements + * * @return void */ protected function _prepareForm() @@ -77,6 +82,8 @@ protected function _prepareForm() } /** + * Returns set id + * * @return int */ protected function _getSetId() diff --git a/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php b/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php index c3ec83d4dd981..f29fa0611efa4 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php +++ b/app/code/Magento/Config/Model/Config/Backend/Currency/Cron.php @@ -10,6 +10,8 @@ namespace Magento\Config\Model\Config\Backend\Currency; /** + * Cron job configuration for currency + * * @api * @since 100.0.2 */ @@ -47,6 +49,8 @@ public function __construct( } /** + * After save handler + * * @return $this * @throws \Exception */ diff --git a/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php b/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php index 7a0eb6652d1ba..cff6f54b3a7a8 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php +++ b/app/code/Magento/Config/Model/Config/Backend/Log/Cron.php @@ -10,6 +10,8 @@ namespace Magento\Config\Model\Config\Backend\Log; /** + * Cron logger configuration + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php b/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php index c5e3323716a1b..eeef291fb6ad1 100644 --- a/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php +++ b/app/code/Magento/Cron/Model/Config/Backend/Product/Alert.php @@ -11,6 +11,9 @@ */ namespace Magento\Cron\Model\Config\Backend\Product; +/** + * Cron job Alert configuration + */ class Alert extends \Magento\Framework\App\Config\Value { /** @@ -61,7 +64,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * * @return $this * @throws \Exception diff --git a/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php b/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php index 31d8ba59ee42d..44ed4c001d23c 100644 --- a/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php +++ b/app/code/Magento/Cron/Model/Config/Backend/Sitemap.php @@ -11,6 +11,9 @@ */ namespace Magento\Cron\Model\Config\Backend; +/** + * Sitemap configuration + */ class Sitemap extends \Magento\Framework\App\Config\Value { /** @@ -61,6 +64,8 @@ public function __construct( } /** + * After save handler + * * @return $this * @throws \Exception */ diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php index c7023d0404f75..a6e0eb0bcbc58 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php @@ -152,13 +152,12 @@ public function __construct( /** * Set customer registry * - * @param \Magento\Framework\Registry $coreRegistry + * @param \Magento\Framework\Registry $customerRegistry * @return void * @deprecated 100.1.0 */ public function setCustomerRegistry(\Magento\Customer\Model\CustomerRegistry $customerRegistry) { - $this->customerRegistry = $customerRegistry; } diff --git a/app/code/Magento/Customer/Model/Address.php b/app/code/Magento/Customer/Model/Address.php index c39420542248e..4976ec546609f 100644 --- a/app/code/Magento/Customer/Model/Address.php +++ b/app/code/Magento/Customer/Model/Address.php @@ -122,6 +122,8 @@ public function __construct( } /** + * Init model + * * @return void */ protected function _construct() @@ -165,7 +167,7 @@ public function updateData(AddressInterface $address) } /** - * {@inheritdoc} + * @inheritdoc */ public function getDataModel($defaultBillingAddressId = null, $defaultShippingAddressId = null) { @@ -258,6 +260,8 @@ public function getDefaultAttributeCodes() } /** + * Clone object handler + * * @return void */ public function __clone() @@ -298,6 +302,8 @@ public function setRegionId($regionId) } /** + * Create customer model + * * @return Customer */ protected function _createCustomer() @@ -353,7 +359,7 @@ public function reindex() } /** - * {@inheritdoc} + * @inheritdoc * @since 100.0.6 */ protected function getCustomAttributesCodes() @@ -363,6 +369,7 @@ protected function getCustomAttributesCodes() /** * Get new AttributeList dependency for application code. + * * @return \Magento\Customer\Model\Address\CustomAttributeListInterface * @deprecated 100.0.6 */ diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index f11322f17eea0..972cb63ed452e 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -1295,6 +1295,8 @@ public function getResetPasswordLinkExpirationPeriod() } /** + * Create address instance + * * @return Address */ protected function _createAddressInstance() @@ -1303,6 +1305,8 @@ protected function _createAddressInstance() } /** + * Create address collection instance + * * @return \Magento\Customer\Model\ResourceModel\Address\Collection */ protected function _createAddressCollection() @@ -1311,6 +1315,8 @@ protected function _createAddressCollection() } /** + * Returns templates types + * * @return array */ protected function getTemplateTypes() diff --git a/app/code/Magento/Customer/Model/Renderer/Region.php b/app/code/Magento/Customer/Model/Renderer/Region.php index ad620e4e4b3f2..a26cfb96fe02a 100644 --- a/app/code/Magento/Customer/Model/Renderer/Region.php +++ b/app/code/Magento/Customer/Model/Renderer/Region.php @@ -54,6 +54,8 @@ public function __construct( } /** + * Render element + * * @param AbstractElement $element * @return string * @SuppressWarnings(PHPMD.CyclomaticComplexity) diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index c0bbd32f938e5..43ae2db0c2163 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -161,7 +161,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -289,7 +289,7 @@ private function populateCustomerWithSecureData($customerModel, $passwordHash = } /** - * {@inheritdoc} + * @inheritdoc */ public function get($email, $websiteId = null) { @@ -298,7 +298,7 @@ public function get($email, $websiteId = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function getById($customerId) { @@ -307,7 +307,7 @@ public function getById($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(SearchCriteriaInterface $searchCriteria) { @@ -347,7 +347,7 @@ public function getList(SearchCriteriaInterface $searchCriteria) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(CustomerInterface $customer) { @@ -355,7 +355,7 @@ public function delete(CustomerInterface $customer) } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($customerId) { diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php index d144b7f6b70ec..9caa2988c5a94 100644 --- a/app/code/Magento/Customer/Model/Visitor.php +++ b/app/code/Magento/Customer/Model/Visitor.php @@ -11,6 +11,7 @@ /** * Class Visitor + * * @package Magento\Customer\Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -86,6 +87,7 @@ class Visitor extends \Magento\Framework\Model\AbstractModel * @param array $ignoredUserAgents * @param array $ignores * @param array $data + * @param RequestSafetyInterface|null $requestSafety * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -277,6 +279,7 @@ public function bindQuoteCreate($observer) /** * Destroy binding of checkout quote + * * @param \Magento\Framework\Event\Observer $observer * @return \Magento\Customer\Model\Visitor */ diff --git a/app/code/Magento/Directory/Block/Data.php b/app/code/Magento/Directory/Block/Data.php index 630c0966bc2f9..333e9e03706b9 100644 --- a/app/code/Magento/Directory/Block/Data.php +++ b/app/code/Magento/Directory/Block/Data.php @@ -6,6 +6,8 @@ namespace Magento\Directory\Block; /** + * Directory data block + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Data extends \Magento\Framework\View\Element\Template @@ -67,6 +69,8 @@ public function __construct( } /** + * Returns load url for regions + * * @return string */ public function getLoadrRegionUrl() @@ -75,6 +79,8 @@ public function getLoadrRegionUrl() } /** + * Returns country collection instance + * * @return \Magento\Directory\Model\ResourceModel\Country\Collection */ public function getCountryCollection() @@ -103,6 +109,8 @@ protected function getTopDestinations() } /** + * Returns country html select + * * @param null|string $defValue * @param string $name * @param string $id @@ -146,6 +154,8 @@ public function getCountryHtmlSelect($defValue = null, $name = 'country_id', $id } /** + * Returns region collection + * * @return \Magento\Directory\Model\ResourceModel\Region\Collection */ public function getRegionCollection() @@ -160,6 +170,8 @@ public function getRegionCollection() } /** + * Returns region html select + * * @return string */ public function getRegionHtmlSelect() @@ -193,6 +205,8 @@ public function getRegionHtmlSelect() } /** + * Returns country id + * * @return string */ public function getCountryId() @@ -205,6 +219,8 @@ public function getCountryId() } /** + * Returns regions js + * * @return string */ public function getRegionsJs() diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 44080ebd13001..0e7a46125d872 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -225,6 +225,8 @@ protected function _afterDelete(\Magento\Framework\Model\AbstractModel $object) } /** + * Returns config instance + * * @return Config * @deprecated 100.0.7 */ @@ -297,10 +299,10 @@ protected function _saveAdditionalAttributeData(AbstractModel $object) * Save in set including * * @param AbstractModel $object - * @param null $attributeEntityId - * @param null $attributeSetId - * @param null $attributeGroupId - * @param null $attributeSortOrder + * @param int|null $attributeEntityId + * @param int|null $attributeSetId + * @param int|null $attributeGroupId + * @param int|null $attributeSortOrder * @return $this * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -636,6 +638,7 @@ public function getAdditionalAttributeTable($entityTypeId) /** * Load additional attribute data. + * * Load label of current active store * * @param EntityAttribute|AbstractModel $object diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 8f606d179563b..2f7065cbd63b7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -279,8 +279,9 @@ protected function getDocsArrayInBulkIndexFormat( * Checks whether Elasticsearch index and alias exists. * * @param int $storeId - * @param bool $checkAlias * @param string $mappedIndexerId + * @param bool $checkAlias + * * @return $this */ public function checkIndex( diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 59dc4db553ebf..a995667954c7d 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -9,6 +9,8 @@ use Magento\Elasticsearch\SearchAdapter\QueryContainer; /** + * Elastic search data provider + * * @api * @since 100.1.0 */ @@ -120,7 +122,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getRange() @@ -129,7 +131,7 @@ public function getRange() } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage $entityStorage) @@ -168,7 +170,7 @@ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getInterval( @@ -191,7 +193,7 @@ public function getInterval( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregation( @@ -225,7 +227,7 @@ public function getAggregation( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function prepareData($range, array $dbRanges) diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index b6a3aede21ad2..80824d45cb6e5 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -10,6 +10,8 @@ use Magento\Catalog\Api\ProductRepositoryInterface; /** + * Grouped product type model + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 @@ -226,6 +228,8 @@ public function getAssociatedProducts($product) } /** + * Flush Associated Products Cache + * * @param \Magento\Catalog\Model\Product $product * @return \Magento\Catalog\Model\Product * @since 100.1.0 @@ -323,6 +327,8 @@ public function getAssociatedProductCollection($product) } /** + * Returns product info + * * @param \Magento\Framework\DataObject $buyRequest * @param \Magento\Catalog\Model\Product $product * @param bool $isStrictProcessMode @@ -350,6 +356,7 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr /** * Prepare product and its configuration to be added to some products list. + * * Perform standard preparation process and add logic specific to Grouped product type. * * @param \Magento\Framework\DataObject $buyRequest @@ -423,6 +430,7 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p /** * Retrieve products divided into groups required to purchase + * * At least one product in each group has to be purchased * * @param \Magento\Catalog\Model\Product $product @@ -436,8 +444,8 @@ public function getProductsToPurchaseByReqGroups($product) /** * Prepare selected qty for grouped product's options * - * @param \Magento\Catalog\Model\Product $product - * @param \Magento\Framework\DataObject $buyRequest + * @param \Magento\Catalog\Model\Product $product + * @param \Magento\Framework\DataObject $buyRequest * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -473,7 +481,7 @@ public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function beforeSave($product) { @@ -486,6 +494,8 @@ public function beforeSave($product) } /** + * Returns msrp for children products + * * @param \Magento\Catalog\Model\Product $product * @return int */ diff --git a/app/code/Magento/Paypal/Model/Api/AbstractApi.php b/app/code/Magento/Paypal/Model/Api/AbstractApi.php index d5cd69d68952c..73a4f69147990 100644 --- a/app/code/Magento/Paypal/Model/Api/AbstractApi.php +++ b/app/code/Magento/Paypal/Model/Api/AbstractApi.php @@ -454,6 +454,7 @@ protected function _exportLineItems(array &$request, $i = 0) /** * Prepare shipping options request + * * Returns false if there are no shipping options * * @param array &$request @@ -520,7 +521,7 @@ protected function _getDataOrConfig($key, $default = null) } /** - * region_id workaround: PayPal requires state code, try to find one in the address + * Region_id workaround: PayPal requires state code, try to find one in the address * * @param \Magento\Framework\DataObject $address * @return string @@ -577,6 +578,7 @@ protected function _buildQuery($request) /** * Filter qty in API calls + * * Paypal note: The value for quantity must be a positive integer. Null, zero, or negative numbers are not allowed. * * @param float|string|int $value diff --git a/app/code/Magento/Paypal/Model/Express.php b/app/code/Magento/Paypal/Model/Express.php index 196e59c6593b9..33fe5ec33002b 100644 --- a/app/code/Magento/Paypal/Model/Express.php +++ b/app/code/Magento/Paypal/Model/Express.php @@ -275,6 +275,7 @@ protected function _setApiProcessableErrors() /** * Store setter + * * Also updates store ID in config object * * @param \Magento\Store\Model\Store|int $store @@ -334,6 +335,7 @@ public function getConfigPaymentAction() /** * Check whether payment method can be used + * * @param \Magento\Quote\Api\Data\CartInterface|Quote|null $quote * @return bool */ @@ -545,6 +547,7 @@ public function cancel(\Magento\Payment\Model\InfoInterface $payment) /** * Whether payment can be reviewed + * * @return bool */ public function canReviewPayment() @@ -601,6 +604,8 @@ public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payme } /** + * Returns api instance + * * @return Api\Nvp */ public function getApi() @@ -717,6 +722,7 @@ protected function _importToPayment($api, $payment) /** * Check void availability + * * @return bool * @throws \Magento\Framework\Exception\LocalizedException * @internal param \Magento\Framework\DataObject $payment diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index 0aa2387e623bc..4fdc4cf8f7afd 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -237,6 +237,7 @@ public function beforeSave() /** * Goes to specified host/path and fetches reports from there. + * * Save reports to database. * * @param \Magento\Framework\Filesystem\Io\Sftp $connection @@ -517,6 +518,7 @@ public function getFieldLabel($field) /** * Iterate through website configurations and collect all SFTP configurations + * * Filter config values if necessary * * @param bool $automaticMode Whether to skip settings with disabled Automatic Fetching or not diff --git a/app/code/Magento/Persistent/Helper/Data.php b/app/code/Magento/Persistent/Helper/Data.php index c963084a1ecb1..9a547c0032492 100644 --- a/app/code/Magento/Persistent/Helper/Data.php +++ b/app/code/Magento/Persistent/Helper/Data.php @@ -13,6 +13,8 @@ use Magento\Store\Model\ScopeInterface; /** + * Helper for persistence + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Persistent/Model/Session.php b/app/code/Magento/Persistent/Model/Session.php index 3aea20a090dd9..701b4fc21d29a 100644 --- a/app/code/Magento/Persistent/Model/Session.php +++ b/app/code/Magento/Persistent/Model/Session.php @@ -197,6 +197,7 @@ public function getExpiredBefore($store = null) /** * Serialize info for Resource Model to save + * * For new model check and set available cookie key * * @return $this diff --git a/app/code/Magento/Review/Block/Rating/Entity/Detailed.php b/app/code/Magento/Review/Block/Rating/Entity/Detailed.php index eccbfe1acee54..d496b3955de7b 100644 --- a/app/code/Magento/Review/Block/Rating/Entity/Detailed.php +++ b/app/code/Magento/Review/Block/Rating/Entity/Detailed.php @@ -37,6 +37,8 @@ public function __construct( } /** + * Returns block html + * * @return string */ protected function _toHtml() diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php index ea19e25ba6855..db336d0c2f563 100644 --- a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php +++ b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php @@ -15,6 +15,9 @@ use Magento\Framework\DataObject; use Magento\Framework\Controller\ResultFactory; +/** + * Represents product info in json + */ class JsonProductInfo extends ProductController implements HttpGetActionInterface { /** @@ -41,6 +44,8 @@ public function __construct( } /** + * Execute controller + * * @return \Magento\Framework\Controller\Result\Json */ public function execute() diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php index bdf8cfe5416dd..b45fddc7d7354 100644 --- a/app/code/Magento/Sales/Api/Data/OrderInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php @@ -582,6 +582,7 @@ public function getAdjustmentPositive(); * Gets the applied rule IDs for the order. * * Rules are comma separated if there are more than one. + * * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php index 4aabd05a0efcc..2aee648ef7c9f 100644 --- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php @@ -416,6 +416,7 @@ public function getAmountRefunded(); * Gets the applied rule IDs for the order item. * * Rules are comma separated if there are more than one. + * * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 472153ba6c58f..03b4f78b14187 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -2153,6 +2153,7 @@ public function getAdjustmentPositive() * Return applied_rule_ids * * Rules are comma separated if there are more than one. + * * @return string|null */ public function getAppliedRuleIds() diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index 0c03b50b366ca..710c85f8773d6 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -726,6 +726,7 @@ public function getAmountRefunded() * Return applied_rule_ids * * Rules are comma separated if there are more than one. + * * @return string|null */ public function getAppliedRuleIds() diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php index 50e7437396b0c..87e9d9e006064 100644 --- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php +++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php @@ -11,6 +11,9 @@ */ namespace Magento\Tax\Block\Adminhtml\Rate\Toolbar; +/** + * Rate toolbar block + */ class Save extends \Magento\Backend\Block\Template implements \Magento\Backend\Block\Widget\ContainerInterface { /** @@ -46,6 +49,8 @@ public function __construct( } /** + * Init model + * * @return void */ protected function _construct() @@ -97,6 +102,8 @@ public function updateButton($buttonId, $key, $data) } /** + * Prepare layout + * * @return $this */ protected function _prepareLayout() diff --git a/app/code/Magento/Theme/Block/Html/Pager.php b/app/code/Magento/Theme/Block/Html/Pager.php index 3d66113ac613d..ad3f4aad676eb 100644 --- a/app/code/Magento/Theme/Block/Html/Pager.php +++ b/app/code/Magento/Theme/Block/Html/Pager.php @@ -184,6 +184,8 @@ public function setCollection($collection) } /** + * Returns data collection + * * @return \Magento\Framework\Data\Collection */ public function getCollection() @@ -192,7 +194,10 @@ public function getCollection() } /** + * Set page variable name + * * @param string $varName + * * @return $this */ public function setPageVarName($varName) @@ -202,6 +207,8 @@ public function setPageVarName($varName) } /** + * Get page variable name + * * @return string */ public function getPageVarName() @@ -210,7 +217,10 @@ public function getPageVarName() } /** + * Set show per page param + * * @param bool $varName + * * @return $this */ public function setShowPerPage($varName) @@ -220,6 +230,8 @@ public function setShowPerPage($varName) } /** + * Is show per page + * * @return bool */ public function isShowPerPage() @@ -234,6 +246,7 @@ public function isShowPerPage() * Set the name for pager limit data * * @param string $varName + * * @return $this */ public function setLimitVarName($varName) @@ -275,6 +288,8 @@ public function getAvailableLimit() } /** + * Get first number + * * @return int */ public function getFirstNum() @@ -284,6 +299,8 @@ public function getFirstNum() } /** + * Get last number + * * @return int */ public function getLastNum() @@ -333,7 +350,10 @@ public function isLastPage() } /** + * Is limit current + * * @param int $limit + * * @return bool */ public function isLimitCurrent($limit) @@ -342,7 +362,10 @@ public function isLimitCurrent($limit) } /** + * Is page current + * * @param int $page + * * @return bool */ public function isPageCurrent($page) @@ -351,6 +374,8 @@ public function isPageCurrent($page) } /** + * Get pages + * * @return array */ public function getPages() @@ -377,6 +402,8 @@ public function getPages() } /** + * Get first page url + * * @return string */ public function getFirstPageUrl() @@ -418,6 +445,7 @@ public function getLastPageUrl() * Retrieve page URL * * @param string $page + * * @return string */ public function getPageUrl($page) @@ -426,7 +454,10 @@ public function getPageUrl($page) } /** + * Get limit url + * * @param int $limit + * * @return string */ public function getLimitUrl($limit) @@ -438,6 +469,7 @@ public function getLimitUrl($limit) * Retrieve page URL by defined parameters * * @param array $params + * * @return string */ public function getPagerUrl($params = []) @@ -453,6 +485,8 @@ public function getPagerUrl($params = []) } /** + * Get path + * * @return string */ protected function getPath() diff --git a/app/code/Magento/User/Block/Buttons.php b/app/code/Magento/User/Block/Buttons.php index bb7375ae83277..f580c5cd72b9b 100644 --- a/app/code/Magento/User/Block/Buttons.php +++ b/app/code/Magento/User/Block/Buttons.php @@ -6,6 +6,8 @@ namespace Magento\User\Block; /** + * Buttons block + * * @api * @since 100.0.2 */ @@ -33,6 +35,8 @@ public function __construct( } /** + * Prepare layout + * * @return $this */ protected function _prepareLayout() @@ -85,6 +89,8 @@ protected function _prepareLayout() } /** + * Get back button html + * * @return string */ public function getBackButtonHtml() @@ -93,6 +99,8 @@ public function getBackButtonHtml() } /** + * Get reset button html + * * @return string */ public function getResetButtonHtml() @@ -101,6 +109,8 @@ public function getResetButtonHtml() } /** + * Get save button html + * * @return string */ public function getSaveButtonHtml() @@ -109,6 +119,8 @@ public function getSaveButtonHtml() } /** + * Get delete button html + * * @return string|void */ public function getDeleteButtonHtml() @@ -120,6 +132,8 @@ public function getDeleteButtonHtml() } /** + * Get user + * * @return mixed */ public function getUser() diff --git a/app/code/Magento/Wishlist/Helper/Rss.php b/app/code/Magento/Wishlist/Helper/Rss.php index bb47aeb319410..b4f761f03dd97 100644 --- a/app/code/Magento/Wishlist/Helper/Rss.php +++ b/app/code/Magento/Wishlist/Helper/Rss.php @@ -7,6 +7,8 @@ namespace Magento\Wishlist\Helper; /** + * Wishlist rss helper + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * * @api From 1c7c6fbf4ca26a5518634ecfec919aba3593e0c6 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 17 Oct 2018 17:09:36 +0300 Subject: [PATCH 0622/1415] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Change code back as there are no changes in 2.3.0 release. --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index b9993b420f427..167ab91b9d01e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -452,9 +452,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image { - path - } + small_image small_image_label special_from_date special_price @@ -485,7 +483,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() QUERY; $response = $this->graphQlQuery($query); - + /** * @var ProductRepositoryInterface $productRepository */ From 84dc7dc461031f5f73a38ec952c59ae4407a9cab Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Wed, 17 Oct 2018 17:49:28 +0300 Subject: [PATCH 0623/1415] MAGETWO-95614: Client side less compilation doesn't work properly (Page UI breaks) - Fixed !important in variable declaration that broke the client side less compilation --- .../blank/Magento_Swatches/web/css/source/_module.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less index b5d604597148a..fb10c175e3c36 100644 --- a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less @@ -26,7 +26,7 @@ @swatch-option-text__background: @swatch-option__background; @swatch-option-text__color: #686868; -@swatch-option-text__selected__background-color: @color-white !important; +@swatch-option-text__selected__background-color: @color-white; // Size and Manufacturer attributes @attr-swatch-option__background: @swatch-option__background; @@ -143,7 +143,7 @@ margin-right: 7px; &.selected { - .lib-css(background-color, @swatch-option-text__selected__background-color); + .lib-css(background-color, @swatch-option-text__selected__background-color) !important; } } From e24d8b96d4c41454bcaccfd6ed4105751905d0a8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:46:41 -0500 Subject: [PATCH 0624/1415] Fix Value model description --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index e6923caa3d28c..7ba4225ce2fb8 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -8,6 +8,10 @@ /** * Config data model * + * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit + * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * and deprecate the mentioned together with the model + * * @method string getScope() * @method \Magento\Framework\App\Config\ValueInterface setScope(string $value) * @method int getScopeId() From 863f772a07a5628d593e971a8df9b3f68b5a7b5a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:49:41 -0500 Subject: [PATCH 0625/1415] Remove API annotiotion --- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index ab6a34c4274bd..37e821f026869 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,10 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * @api + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { From 78454931b700d33b1319a5c689597533a1f22ad8 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 17 Oct 2018 10:49:55 -0500 Subject: [PATCH 0626/1415] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env --- .../view/frontend/web/js/model/error-processor.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js index 848a7daf71e1b..86d6c4dd10580 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js @@ -8,8 +8,9 @@ */ define([ 'mage/url', - 'Magento_Ui/js/model/messageList' -], function (url, globalMessageList) { + 'Magento_Ui/js/model/messageList', + 'mage/translate' +], function (url, globalMessageList, $t) { 'use strict'; return { @@ -25,7 +26,11 @@ define([ if (response.status == 401) { //eslint-disable-line eqeqeq window.location.replace(url.build('customer/account/login/')); } else { - error = JSON.parse(response.responseText); + try { + error = JSON.parse(response.responseText); + } catch (exception) { + error = $t('Something went wrong with your request. Please try again later.') + } messageContainer.addErrorMessage(error); } } From 34e1041c95169e2fff9fdc3a65b21779bc8243c5 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 12:43:37 -0500 Subject: [PATCH 0627/1415] Add Value and ValueInterface to Magento Framework's public API These classes are necessary/useful for creating a backend source for a Magento Configuration field. As such they should be reliable and part of the public API. --- lib/internal/Magento/Framework/App/Config/Value.php | 2 ++ lib/internal/Magento/Framework/App/Config/ValueInterface.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index c85b484d51ce2..e6923caa3d28c 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -17,6 +17,8 @@ * @method string getValue() * @method \Magento\Framework\App\Config\ValueInterface setValue(string $value) * + * @api + * * @SuppressWarnings(PHPMD.NumberOfChildren) */ class Value extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\App\Config\ValueInterface diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 1e0747acc36f2..ab6a34c4274bd 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,7 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * + * @api */ interface ValueInterface { From 918c9c28e6d32ed40f353171d00a608350389b68 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:46:41 -0500 Subject: [PATCH 0628/1415] Fix Value model description --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index e6923caa3d28c..7ba4225ce2fb8 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -8,6 +8,10 @@ /** * Config data model * + * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit + * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * and deprecate the mentioned together with the model + * * @method string getScope() * @method \Magento\Framework\App\Config\ValueInterface setScope(string $value) * @method int getScopeId() From 15d448d79b5ff721cda472a57e34ea791742dc53 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:49:41 -0500 Subject: [PATCH 0629/1415] Remove API annotiotion --- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index ab6a34c4274bd..37e821f026869 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,10 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * @api + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { From de5a0d340123db78d95e72a5c6bf648a707fb454 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 15:23:40 -0500 Subject: [PATCH 0630/1415] Add ReadFactory and WriteFactory to Magento's public API These classes are necessary/useful for creating instances of ReadInterface and WriteInterface using the public API. --- .../Magento/Framework/Filesystem/File/ReadFactory.php | 6 +++++- .../Magento/Framework/Filesystem/File/WriteFactory.php | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php index 38b581da752b7..5d9badf42073f 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading + * @api + */ class ReadFactory { /** @@ -28,7 +32,7 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file + * Create a {@see ReaderInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code diff --git a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php index a45d6a62488f6..af2a43ceaedc3 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading and/or writing + * @api + */ class WriteFactory extends ReadFactory { /** @@ -29,12 +33,12 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file. + * Create a {@see WriterInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code * @param string $mode [optional] - * @return Write + * @return WriteInterface */ public function create($path, $driver, $mode = 'r') { From f67b94f3b424811fe57ef4e280d6724acbce3e90 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 15:30:23 -0500 Subject: [PATCH 0631/1415] Add directory WriteInterface and ReadInterface --- .../Magento/Framework/Filesystem/Directory/ReadInterface.php | 2 +- .../Magento/Framework/Filesystem/Directory/WriteInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php index 5519245ec24b4..61108c64dda44 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\ReadInterface - * + * @api */ interface ReadInterface { diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php index c72651a78dad3..186cbcb81bff2 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\WriteInterface - * + * @api */ interface WriteInterface extends ReadInterface { From f2960de5d130bad5ae78023fc5f20f9187f78fc0 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 15 Oct 2018 15:55:24 -0500 Subject: [PATCH 0632/1415] MAGETWO-95363: Update Magento\Ui\Controller\Adminhtml\Index\Render\Handle controller --- .../Adminhtml/Index/Render/Handle.php | 41 ++++++++++++++++--- .../Adminhtml/Index/Render/HandleTest.php | 8 +++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php index 3b2a81fdac729..6ea14448c4aef 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render/Handle.php @@ -10,12 +10,37 @@ use Magento\Ui\Component\Control\ActionPool; use Magento\Ui\Component\Wrapper\UiComponent; use Magento\Ui\Controller\Adminhtml\AbstractAction; +use Magento\Backend\App\Action\Context; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponent\ContextFactory; +use Magento\Framework\App\ObjectManager; /** * Class Handle + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Handle extends AbstractAction implements HttpGetActionInterface { + /** + * @var ContextFactory + */ + private $contextFactory; + + /** + * @param Context $context + * @param UiComponentFactory $factory + * @param ContextFactory|null $contextFactory + */ + public function __construct( + Context $context, + UiComponentFactory $factory, + ContextFactory $contextFactory = null + ) { + parent::__construct($context, $factory); + $this->contextFactory = $contextFactory + ?: ObjectManager::getInstance()->get(ContextFactory::class); + } + /** * Render UI component by namespace in handle context * @@ -27,17 +52,23 @@ public function execute() $handle = $this->_request->getParam('handle'); $namespace = $this->_request->getParam('namespace'); $buttons = $this->_request->getParam('buttons', false); + $this->_view->loadLayout(['default', $handle], true, true, false); + $layout = $this->_view->getLayout(); + $context = $this->contextFactory->create( + [ + 'namespace' => $namespace, + 'pageLayout' => $layout + ] + ); - $component = $this->factory->create($namespace); + $component = $this->factory->create($namespace, null, ['context' => $context]); if ($this->validateAclResource($component->getContext()->getDataProvider()->getConfigData())) { - $this->_view->loadLayout(['default', $handle], true, true, false); - - $uiComponent = $this->_view->getLayout()->getBlock($namespace); + $uiComponent = $layout->getBlock($namespace); $response = $uiComponent instanceof UiComponent ? $uiComponent->toHtml() : ''; } if ($buttons) { - $actionsToolbar = $this->_view->getLayout()->getBlock(ActionPool::ACTIONS_PAGE_TOOLBAR); + $actionsToolbar = $layout->getBlock(ActionPool::ACTIONS_PAGE_TOOLBAR); $response .= $actionsToolbar instanceof Template ? $actionsToolbar->toHtml() : ''; } diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php index e7752678f0c86..d31537458f213 100644 --- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php +++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/Render/HandleTest.php @@ -8,6 +8,9 @@ use Magento\Ui\Controller\Adminhtml\Index\Render\Handle; use Magento\Framework\View\Element\UiComponent\ContextInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class HandleTest extends \PHPUnit\Framework\TestCase { /** @@ -102,7 +105,8 @@ public function setUp() $this->dataProviderMock->expects($this->once()) ->method('getConfigData') ->willReturn([]); - $this->controller = new Handle($this->contextMock, $this->uiFactoryMock); + $contextMock = $this->createMock(\Magento\Framework\View\Element\UiComponent\ContextFactory::class); + $this->controller = new Handle($this->contextMock, $this->uiFactoryMock, $contextMock); } public function testExecuteNoButtons() @@ -132,7 +136,7 @@ public function testExecute() ->with(['default', $result], true, true, false); $layoutMock = $this->createMock(\Magento\Framework\View\LayoutInterface::class); - $this->viewMock->expects($this->exactly(2))->method('getLayout')->willReturn($layoutMock); + $this->viewMock->expects($this->once())->method('getLayout')->willReturn($layoutMock); $layoutMock->expects($this->exactly(2))->method('getBlock'); From 1fdf2556c386703f597be3921285b45e43789cb1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 17 Oct 2018 12:31:09 -0500 Subject: [PATCH 0633/1415] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env --- .../frontend/web/js/model/error-processor.js | 2 +- .../frontend/js/model/error-processor.test.js | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js index 86d6c4dd10580..42b692ff9dd8d 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js @@ -29,7 +29,7 @@ define([ try { error = JSON.parse(response.responseText); } catch (exception) { - error = $t('Something went wrong with your request. Please try again later.') + error = $t('Something went wrong with your request. Please try again later.'); } messageContainer.addErrorMessage(error); } diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js new file mode 100644 index 0000000000000..3a6cd6d60d38b --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js @@ -0,0 +1,70 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/*eslint max-nested-callbacks: 0*/ +define([ + 'squire' +], function (Squire) { + 'use strict'; + + describe('Magento_Checkout/js/model/error-processor', function () { + var injector = new Squire(), + mocks = { + 'mage/url': { + /** Method stub. */ + build: jasmine.createSpy() + } + }, + model; + + beforeEach(function (done) { + injector.mock(mocks); + injector.require([ + 'Magento_Checkout/js/model/error-processor' + ], function (processor) { + model = processor; + + done(); + }); + }); + + describe('Check process method', function () { + it('check on success response with valid response data', function () { + var messageObject = { + message: 'Valid error message!' + }, + messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 200, + responseText: JSON.stringify(messageObject) + }, messageContainer); + expect(messageContainer.addErrorMessage).toHaveBeenCalledWith(messageObject); + }); + + it('check on success response with invalid response data', function () { + var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 200, + responseText: '' + }, messageContainer); + expect(messageContainer.addErrorMessage) + .toHaveBeenCalledWith('Something went wrong with your request. Please try again later.'); + }); + + it('check on failed status', function () { + var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 401, + responseText: '' + }, messageContainer); + expect(mocks['mage/url'].build) + .toHaveBeenCalled(); + }); + }); + }); +}); From 75ebeaf1c7e8beb7a6ec2ccb34c1f4df6e1fc544 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 17 Oct 2018 13:07:08 -0500 Subject: [PATCH 0634/1415] MAGETWO-95723: Product Review "Save and Next" and "Save and Previous" not working - Added test class description --- .../Model/ResourceModel/Review/Product/CollectionTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php index 39129dee28c7c..559c62e42dec3 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php @@ -7,6 +7,9 @@ namespace Magento\Review\Model\ResourceModel\Review\Product; +/** + * Tests some functionality of the Product Review collection + */ class CollectionTest extends \PHPUnit\Framework\TestCase { /** From dd4cc952ed9de82968deaac2f74c439e0b867bcd Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Wed, 17 Oct 2018 13:12:23 -0500 Subject: [PATCH 0635/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 - fix build failure --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 84bc3865a008e..04115ccdcc480 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -28,7 +28,7 @@ <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> - <actionGroup ref="logout" stepKey="logOut"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> <waitForPageLoad stepKey="wait5"/> From 03f4abc29263fdd9a269d381de8c14c4dc455042 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Wed, 17 Oct 2018 21:04:02 +0300 Subject: [PATCH 0636/1415] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/Product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index a488e306473b2..9f8d1786334f2 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -500,7 +500,7 @@ protected function _getResource() /** * Get a list of custom attribute codes that belongs to product attribute set. * - * If attribute set not specified fors product will return all product attribute codes + * If attribute set not specified for product will return all product attribute codes * * @return string[] */ From 365331a281be8d823fead594addfad777877a8a2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 13:42:28 -0500 Subject: [PATCH 0637/1415] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++-- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 7ba4225ce2fb8..23fe71aa6685e 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -113,7 +113,7 @@ public function getFieldsetDataValue($key) } /** - * {@inheritdoc} + * Processing object after save data * * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * @@ -129,7 +129,7 @@ public function afterSave() } /** - * {@inheritdoc} + * Processing object after delete data * * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 37e821f026869..5468caf4902f3 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,8 +9,8 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * - * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going * to introduce a new iterface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ @@ -23,6 +23,7 @@ interface ValueInterface /** * Check if config data value was changed + * * @todo this method should be make as protected * @return bool */ From cf23c7d1a52bd6a41828722049975cc3671592c3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 14:58:52 -0500 Subject: [PATCH 0638/1415] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- .../Magento/Test/Legacy/_files/obsolete_constants.php | 1 - lib/internal/Magento/Framework/App/Config/Value.php | 2 +- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php index cbf499c8dad38..5bcc712be6f74 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php @@ -712,7 +712,6 @@ 'Magento\Sales\Block\Reorder\Sidebar', '\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT', ], - ['ENTITY', 'Magento\Framework\App\Config\ValueInterface'], ['XML_PATH_ALLOW_CURRENCIES_INSTALLED', 'Magento\Framework\Locale\CurrencyInterface'], [ 'DEFAULT_CURRENCY', diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 23fe71aa6685e..6fde4dded4695 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -9,7 +9,7 @@ * Config data model * * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit - * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * developers' needs of extensibility. In 2.4 we are going to introduce a new interface which should cover all needs * and deprecate the mentioned together with the model * * @method string getScope() diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 5468caf4902f3..0aa600b84dcce 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -11,13 +11,15 @@ * Interface \Magento\Framework\App\Config\ValueInterface * * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going - * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * to introduce a new interface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { /** * Table name + * + * @deprecated since it is not used */ const ENTITY = 'config_data'; From b80b12f4588133656752e32908f8a913b1ceac60 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 17 Oct 2018 14:58:53 -0500 Subject: [PATCH 0639/1415] MAGETWO-95433: Customer address custom attributes (Multi select, dropdown) display behavior on storefront is not per standards (PFA snap) - fix static test failure --- .../Magento/Catalog/_files/category_duplicates_rollback.php | 1 + .../CatalogImportExport/_files/update_category_duplicates.php | 1 + .../_files/update_category_duplicates_rollback.php | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php index a1dc418e15633..ceaad3a00329f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Exception\NoSuchEntityException; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php index 27ca8e7a04413..53d30e834a07d 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates.php'; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php index f3bb3d0415afa..ca0f379a03dc5 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php @@ -3,13 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates_rollback.php'; //Delete products created in CSV import /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); $csvProductSkus = ['simple1', 'simple2', 'simple3']; -foreach($csvProductSkus as $sku) { +foreach ($csvProductSkus as $sku) { try { $product = $productRepository->get($sku, false, null, true); $productRepository->delete($product); From 2f76498e2fe0d67af352c6a319e08e84dc3f2019 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Wed, 17 Oct 2018 15:50:21 -0500 Subject: [PATCH 0640/1415] MQE-1187: Fix MFTF skipped tests - Fixed RestrictedAdminCreateCMSBlockTest - Refactored WYSIWYG enable to a CLI action, way faster and more robust - Moved AdminRole/AdminUser action groups to User module, as it belongs there regardless. --- .../ActionGroup/ConfigWYSIWYGActionGroup.xml | 19 ++----------------- .../Mftf/ActionGroup/AdminRoleActionGroup.xml | 7 +++++-- .../Mftf/ActionGroup/AdminUserActionGroup.xml | 3 +-- 3 files changed, 8 insertions(+), 21 deletions(-) rename app/code/Magento/{Braintree => User}/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml (83%) rename app/code/Magento/{Braintree => User}/Test/Mftf/ActionGroup/AdminUserActionGroup.xml (98%) diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 3c043b28801e2..48eeb79a15ed0 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -9,25 +9,10 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="EnabledWYSIWYG"> - <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> - <waitForPageLoad stepKey="wait1"/> - <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> - <waitForElementVisible selector="{{ContentManagementSection.EnableWYSIWYG}}" stepKey="waitForEnableWYSIWYGDropdown1" /> - <waitForElementVisible selector="{{ContentManagementSection.EnableSystemValue}}" stepKey="waitForUseSystemValueVisible"/> - <uncheckOption selector="{{ContentManagementSection.EnableSystemValue}}" stepKey="uncheckUseSystemValue"/> - <selectOption selector="{{ContentManagementSection.EnableWYSIWYG}}" userInput="Enabled by Default" stepKey="selectOption1"/> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + <magentoCLI stepKey="enableWYSIWYG" command="config:set cms/wysiwyg/enabled enabled"/> </actionGroup> <actionGroup name="DisabledWYSIWYG"> - <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> - <waitForPageLoad stepKey="wait3"/> - <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> - <waitForElementVisible selector="{{ContentManagementSection.EnableWYSIWYG}}" stepKey="waitForEnableWYSIWYGDropdown2" time="30"/> - <uncheckOption selector="{{ContentManagementSection.EnableSystemValue}}" stepKey="uncheckUseSystemValue"/> - <selectOption selector="{{ContentManagementSection.EnableWYSIWYG}}" userInput="Disabled Completely" stepKey="selectOption2"/> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + <magentoCLI stepKey="disableWYSIWYG" command="config:set cms/wysiwyg/enabled disabled"/> </actionGroup> <actionGroup name="UseStaticURLForMediaContentInWYSIWYG"> <arguments> diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml similarity index 83% rename from app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml rename to app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml index e86d5403e11eb..b1ac0820923d9 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml @@ -7,7 +7,6 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToUserRoles"> <click selector="#menu-magento-backend-system" stepKey="clickOnSystemIcon"/> <waitForPageLoad stepKey="waitForSystemsPageToOpen"/> @@ -28,7 +27,11 @@ <fillField stepKey="setPassword" selector="{{AdminCreateRoleSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> <click selector="{{AdminCreateRoleSection.roleResources}}" stepKey="clickToOpenRoleResources"/> <waitForPageLoad stepKey="waitForRoleResourcePage" time="5"/> - <click stepKey="checkSales" selector="//a[text()='Sales']"/> + <click selector="{{AdminCreateRoleSection.roleResource}}" stepKey="clickToExpandResourceAccess"/> + <click selector="{{AdminCreateRoleSection.resourceValue(scope)}}" stepKey="clickToSelectResourceAccess"/> + <click selector="{{AdminCreateRoleSection.roleScope}}" stepKey="clickToExpandScopeAccess"/> + <click selector="{{AdminCreateRoleSection.scopeValue(resource)}}" stepKey="clickToSelectScopeAccess"/> + <click selector="{{AdminCreateRoleSection.website(websites)}}" stepKey="clickToSelectWebsite"/> <click selector="{{AdminCreateRoleSection.save}}" stepKey="clickToSaveRole"/> <waitForPageLoad stepKey="waitForPageLoad" time="10"/> <see userInput="You saved the role." stepKey="seeSuccessMessage" /> diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminUserActionGroup.xml similarity index 98% rename from app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminUserActionGroup.xml rename to app/code/Magento/User/Test/Mftf/ActionGroup/AdminUserActionGroup.xml index 23c322083773c..3e776df9fb97f 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminUserActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminUserActionGroup.xml @@ -42,8 +42,8 @@ <!--Delete User--> <actionGroup name="AdminDeleteUserActionGroup"> - <click stepKey="clickOnUser" selector="{{AdminDeleteUserSection.theUser}}"/> + <waitForPageLoad stepKey="waitForUserPageToLoad"/> <fillField stepKey="TypeCurrentPassword" selector="{{AdminDeleteUserSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> <scrollToTopOfPage stepKey="scrollToTop"/> <click stepKey="clickToDeleteUser" selector="{{AdminDeleteUserSection.delete}}"/> @@ -52,5 +52,4 @@ <waitForPageLoad stepKey="waitForPageLoad" time="10"/> <see userInput="You deleted the user." stepKey="seeSuccessMessage" /> </actionGroup> - </actionGroups> From 2aebcfb64b863e2b15b357ca6b7b1d07299594b4 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Wed, 17 Oct 2018 15:57:10 -0500 Subject: [PATCH 0641/1415] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../CatalogSearch/Block/Advanced/Form.php | 13 +++++++------ .../CatalogSearch/Block/Advanced/Result.php | 16 +++++++++++++++- .../CatalogSearch/Controller/Advanced/Index.php | 5 ++++- .../CatalogSearch/Controller/Advanced/Result.php | 5 ++++- .../CatalogSearch/Controller/Result/Index.php | 3 +++ .../Aggregation/Checker/Query/AdvancedSearch.php | 2 +- .../CatalogSearch/Model/Adapter/Options.php | 4 +++- .../Adminhtml/System/Config/Backend/Engine.php | 3 +++ .../Magento/CatalogSearch/Model/Advanced.php | 3 +++ .../Model/Attribute/SearchWeight.php | 5 +++-- .../Model/Autocomplete/DataProvider.php | 6 +++++- .../Indexer/Fulltext/Action/DataProvider.php | 2 ++ .../Model/Indexer/Fulltext/Plugin/Attribute.php | 3 +++ .../Model/Indexer/Fulltext/Plugin/Category.php | 5 +++++ .../Model/Indexer/Fulltext/Plugin/Product.php | 7 +++++++ .../Model/Indexer/Fulltext/Store.php | 7 +++++++ .../Model/Indexer/IndexStructureFactory.php | 2 ++ .../Model/Indexer/IndexerHandlerFactory.php | 2 ++ .../CatalogSearch/Model/Indexer/Mview/Action.php | 3 +++ .../Layer/Category/ItemCollectionProvider.php | 6 ++++-- .../Model/Layer/Filter/Category.php | 6 ++++-- .../CatalogSearch/Model/Layer/Filter/Price.php | 8 ++++++++ .../Layer/Search/Plugin/CollectionFilter.php | 3 +++ .../Model/Layer/Search/StateKey.php | 6 ++++-- .../CatalogSearch/Model/Price/Interval.php | 11 ++++++++--- .../Model/ResourceModel/Advanced/Collection.php | 8 ++++++++ .../Model/ResourceModel/Fulltext/Collection.php | 16 +++++++++++++++- app/code/Magento/Search/Model/Query.php | 7 +++++-- 28 files changed, 141 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php index 4d1957991d1bf..681b7ecfb02dc 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php @@ -4,11 +4,6 @@ * See COPYING.txt for license details. */ -/** - * Advanced search form - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\CatalogSearch\Block\Advanced; use Magento\CatalogSearch\Model\Advanced; @@ -21,6 +16,8 @@ use Magento\Framework\View\Element\Template\Context; /** + * Advanced search form + * * @api * @since 100.0.2 */ @@ -58,7 +55,7 @@ public function __construct( } /** - * @return AbstractBlock + * @inheritdoc */ public function _prepareLayout() { @@ -286,6 +283,8 @@ public function getAttributeYesNoElement($attribute) } /** + * Get select block. + * * @return BlockInterface */ protected function _getSelectBlock() @@ -299,6 +298,8 @@ protected function _getSelectBlock() } /** + * Get date block. + * * @return BlockInterface|mixed */ protected function _getDateBlock() diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 7c8e65b249139..9f25990594a49 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -63,7 +63,7 @@ public function __construct( } /** - * @return AbstractBlock + * @inheritdoc */ protected function _prepareLayout() { @@ -125,6 +125,8 @@ public function setListModes() } /** + * Initialize list collection. + * * @return void */ public function setListCollection() @@ -133,6 +135,8 @@ public function setListCollection() } /** + * Get product collection. + * * @return Collection */ protected function _getProductCollection() @@ -141,6 +145,8 @@ protected function _getProductCollection() } /** + * Set search model. + * * @return Advanced */ public function getSearchModel() @@ -149,6 +155,8 @@ public function getSearchModel() } /** + * Get result count. + * * @return mixed */ public function getResultCount() @@ -161,6 +169,8 @@ public function getResultCount() } /** + * Get product list HTML. + * * @return string */ public function getProductListHtml() @@ -169,6 +179,8 @@ public function getProductListHtml() } /** + * Get form URL. + * * @return string */ public function getFormUrl() @@ -182,6 +194,8 @@ public function getFormUrl() } /** + * Get search criteria. + * * @return array */ public function getSearchCriterias() diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php index bc60a5c9b106c..4942b36743c12 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php @@ -10,10 +10,13 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; +/** + * Advanced search controller. + */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** - * @return \Magento\Framework\Controller\ResultInterface + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php index 145db146347bc..17d70e38d3b61 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php @@ -12,6 +12,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\UrlFactory; +/** + * Advanced search result. + */ class Result extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** @@ -46,7 +49,7 @@ public function __construct( } /** - * @return \Magento\Framework\Controller\Result\Redirect + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/CatalogSearch/Controller/Result/Index.php b/app/code/Magento/CatalogSearch/Controller/Result/Index.php index df00e4c7106ba..fba4572cf2c10 100644 --- a/app/code/Magento/CatalogSearch/Controller/Result/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Result/Index.php @@ -15,6 +15,9 @@ use Magento\Search\Model\QueryFactory; use Magento\Search\Model\PopularSearchTerms; +/** + * Search result. + */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php index 8f1f3fde14240..cea42347dc3f9 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php @@ -29,7 +29,7 @@ public function __construct($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php index 425e6c0041616..f2e1c3c4c42d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php @@ -10,6 +10,8 @@ use Magento\Store\Model\ScopeInterface; /** + * Catalog search config. + * * @api * @since 100.0.2 */ @@ -33,7 +35,7 @@ public function __construct(ScopeConfigInterface $scopeConfig) } /** - * {@inheritdoc} + * @inheritdoc */ public function get() { diff --git a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php index 5447ff635f992..1f11d2650334d 100644 --- a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php @@ -6,6 +6,8 @@ namespace Magento\CatalogSearch\Model\Adminhtml\System\Config\Backend; /** + * Backend model for catalog search engine system config + * * @api * @since 100.0.2 */ @@ -42,6 +44,7 @@ public function __construct( /** * After save call + * * Invalidate catalog search index if engine was changed * * @return $this diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index 28f67a7829e7e..af0e9ff5528cf 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -22,6 +22,7 @@ /** * Catalog advanced search model + * * @method int getEntityTypeId() * @method \Magento\CatalogSearch\Model\Advanced setEntityTypeId(int $value) * @method int getAttributeSetId() @@ -296,6 +297,8 @@ public function prepareProductCollection($collection) } /** + * Add search criteria. + * * @param EntityAttribute $attribute * @param mixed $value * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php index d6110f4b3b2c9..fa42cadb8a2fa 100644 --- a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php +++ b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php @@ -7,8 +7,9 @@ namespace Magento\CatalogSearch\Model\Attribute; /** - * This plugin is responsible for processing of search_weight property of a product attribute, - * which is used to boost matches by specific attributes. + * This plugin is responsible for processing of search_weight property of a product attribute. + * + * 'search_weight' is used to boost matches by specific attributes. * * This is part of search accuracy customization functionality. */ diff --git a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php index c1c9997bc83ea..f014c6d133187 100644 --- a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php @@ -13,6 +13,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; use Magento\Store\Model\ScopeInterface; +/** + * Catalog search auto-complete data provider. + */ class DataProvider implements DataProviderInterface { /** @@ -44,6 +47,7 @@ class DataProvider implements DataProviderInterface /** * @param QueryFactory $queryFactory * @param ItemFactory $itemFactory + * @param ScopeConfig $scopeConfig */ public function __construct( QueryFactory $queryFactory, @@ -60,7 +64,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getItems() { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index a8d46911193a8..03c3a50d1714b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -12,6 +12,8 @@ use Magento\Store\Model\Store; /** + * Catalog search full test search data provider. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @api diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php index 83ad7acca84dc..86dccf8cfe559 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php @@ -7,6 +7,9 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext; +/** + * Catalog search indexer plugin for catalog attribute. + */ class Attribute extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php index ca701db7d2a93..1218e3da9a783 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; use Magento\Framework\Model\AbstractModel; +/** + * Catalog search indexer plugin for catalog category. + */ class Category extends AbstractPlugin { /** @@ -26,6 +29,8 @@ public function aroundSave(ResourceCategory $resourceCategory, \Closure $proceed } /** + * Reindex catalog search. + * * @param ResourceCategory $resourceCategory * @param \Closure $proceed * @param AbstractModel $category diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php index c8dbd89017b7c..e250d1123937a 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php @@ -9,9 +9,14 @@ use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct; use Magento\Framework\Model\AbstractModel; +/** + * Catalog search indexer plugin for catalog product. + */ class Product extends AbstractPlugin { /** + * Reindex on product save. + * * @param ResourceProduct $productResource * @param \Closure $proceed * @param AbstractModel $product @@ -38,6 +43,8 @@ public function aroundDelete(ResourceProduct $productResource, \Closure $proceed } /** + * Reindex catalog search. + * * @param ResourceProduct $productResource * @param \Closure $proceed * @param AbstractModel $product diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php index e971f59cf10f2..23ab52012f2e5 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php @@ -11,6 +11,9 @@ use Magento\Framework\Indexer\ConfigInterface; use Magento\Framework\Event\ObserverInterface; +/** + * Catalog search indexer plugin for store. + */ class Store implements ObserverInterface { /** @@ -44,6 +47,8 @@ public function __construct( } /** + * Reindex catalog search. + * * @param \Magento\Store\Model\Store $store * @return void */ @@ -59,6 +64,8 @@ private function clearIndex(\Magento\Store\Model\Store $store) } /** + * Reindex catalog search on store modification. + * * @param \Magento\Framework\Event\Observer $observer * @return void */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php index d8b3c19ddb918..d54d6c939cccc 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php @@ -10,6 +10,8 @@ use Magento\Framework\Search\EngineResolverInterface; /** + * Index structure factory + * * @api * @since 100.1.0 */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php index b9b44df6f404f..841ee8708f264 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php @@ -10,6 +10,8 @@ use Magento\Framework\Search\EngineResolverInterface; /** + * Indexer handler factory. + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php index 47a8681a73c60..b6639f760457b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php @@ -9,6 +9,9 @@ use Magento\Framework\Mview\ActionInterface; use Magento\Framework\Indexer\IndexerInterfaceFactory; +/** + * Catalog search materialized view index action. + */ class Action implements ActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php index 4ce286bf15922..c24665f4808d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Layer\ItemCollectionProviderInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +/** + * Catalog search category layer collection provider. + */ class ItemCollectionProvider implements ItemCollectionProviderInterface { /** @@ -25,8 +28,7 @@ public function __construct(CollectionFactory $collectionFactory) } /** - * @param \Magento\Catalog\Model\Category $category - * @return \Magento\Catalog\Model\ResourceModel\Product\Collection + * @inheritdoc */ public function getCollection(\Magento\Catalog\Model\Category $category) { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php index 7c15514f211d2..0998cf7a9b3ac 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php @@ -24,14 +24,16 @@ class Category extends AbstractFilter private $dataProvider; /** + * Category constructor. + * * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\Layer $layer * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder - * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory * @param \Magento\Framework\Escaper $escaper - * @param CategoryManagerFactory $categoryManager + * @param \Magento\Catalog\Model\Layer\Filter\DataProvider\CategoryFactory $categoryDataProviderFactory * @param array $data + * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory, diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 108f1b9f4fd8d..a19f53469ae01 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -86,6 +86,8 @@ public function __construct( } /** + * Get resource model. + * * @return \Magento\Catalog\Model\ResourceModel\Layer\Filter\Price */ public function getResource() @@ -223,6 +225,8 @@ protected function _getItemsData() } /** + * Get 'to' part of the filter. + * * @param float $from * @return float */ @@ -237,6 +241,8 @@ protected function getTo($from) } /** + * Get 'from' part of the filter. + * * @param float $from * @return float */ @@ -251,6 +257,8 @@ protected function getFrom($from) } /** + * Prepare filter data. + * * @param string $key * @param int $count * @return array diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php index 4ffd8ff4ba5ea..eb901498c4ea5 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Category; use Magento\Search\Model\QueryFactory; +/** + * Catalog search plugin for search collection filter in layered navigation. + */ class CollectionFilter { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php index 4f14b7daba1d5..98caccea2ae49 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Layer\StateKeyInterface; +/** + * Catalog search state key for layered navigation. + */ class StateKey extends \Magento\Catalog\Model\Layer\Category\StateKey implements StateKeyInterface { /** @@ -31,8 +34,7 @@ public function __construct( } /** - * @param \Magento\Catalog\Model\Category $category - * @return string|void + * @inheritdoc */ public function toString($category) { diff --git a/app/code/Magento/CatalogSearch/Model/Price/Interval.php b/app/code/Magento/CatalogSearch/Model/Price/Interval.php index db1d550c3724b..ea2d24aeadfd1 100644 --- a/app/code/Magento/CatalogSearch/Model/Price/Interval.php +++ b/app/code/Magento/CatalogSearch/Model/Price/Interval.php @@ -7,6 +7,9 @@ use Magento\Framework\Search\Dynamic\IntervalInterface; +/** + * Catalog search price interval. + */ class Interval implements IntervalInterface { /** @@ -23,7 +26,7 @@ public function __construct(\Magento\Catalog\Model\ResourceModel\Layer\Filter\Pr } /** - * {@inheritdoc} + * @inheritdoc */ public function load($limit, $offset = null, $lower = null, $upper = null) { @@ -32,7 +35,7 @@ public function load($limit, $offset = null, $lower = null, $upper = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadPrevious($data, $index, $lower = null) { @@ -41,7 +44,7 @@ public function loadPrevious($data, $index, $lower = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadNext($data, $rightIndex, $upper = null) { @@ -50,6 +53,8 @@ public function loadNext($data, $rightIndex, $upper = null) } /** + * Convert to float values. + * * @param array $prices * @return array */ diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 948ae70793c6f..b4b15554f6029 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -207,6 +207,8 @@ protected function _renderFiltersBefore() } /** + * Get attribute code. + * * @param string $attributeCode * @return string */ @@ -266,6 +268,8 @@ private function addRangeAttributeToSearch($attributeCode, $attributeValue) } /** + * Get search. + * * @return \Magento\Search\Api\SearchInterface */ private function getSearch() @@ -278,6 +282,8 @@ private function getSearch() } /** + * Get search criteria builder. + * * @return SearchCriteriaBuilder */ private function getSearchCriteriaBuilder() @@ -290,6 +296,8 @@ private function getSearchCriteriaBuilder() } /** + * Get fielter builder. + * * @return FilterBuilder */ private function getFilterBuilder() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 81121b9d21e12..e6cfe8ca112f7 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -201,6 +201,8 @@ public function __construct( } /** + * Get search. + * * @deprecated 100.1.0 * @return \Magento\Search\Api\SearchInterface */ @@ -213,6 +215,8 @@ private function getSearch() } /** + * Test search. + * * @deprecated 100.1.0 * @param \Magento\Search\Api\SearchInterface $object * @return void @@ -224,6 +228,8 @@ public function setSearch(\Magento\Search\Api\SearchInterface $object) } /** + * Set search criteria builder. + * * @deprecated 100.1.0 * @return \Magento\Framework\Api\Search\SearchCriteriaBuilder */ @@ -237,6 +243,8 @@ private function getSearchCriteriaBuilder() } /** + * Set search criteria builder. + * * @deprecated 100.1.0 * @param \Magento\Framework\Api\Search\SearchCriteriaBuilder $object * @return void @@ -248,6 +256,8 @@ public function setSearchCriteriaBuilder(\Magento\Framework\Api\Search\SearchCri } /** + * Get filter builder. + * * @deprecated 100.1.0 * @return \Magento\Framework\Api\FilterBuilder */ @@ -260,6 +270,8 @@ private function getFilterBuilder() } /** + * Set filter builder. + * * @deprecated 100.1.0 * @param \Magento\Framework\Api\FilterBuilder $object * @return void @@ -274,7 +286,7 @@ public function setFilterBuilder(\Magento\Framework\Api\FilterBuilder $object) * Apply attribute filter to facet collection * * @param string $field - * @param null $condition + * @param mixed|null $condition * @return $this */ public function addFieldToFilter($field, $condition = null) @@ -387,6 +399,8 @@ protected function _beforeLoad() } /** + * Render filters. + * * @return $this */ protected function _renderFilters() diff --git a/app/code/Magento/Search/Model/Query.php b/app/code/Magento/Search/Model/Query.php index b104fd0329795..d8c92a4801e8c 100644 --- a/app/code/Magento/Search/Model/Query.php +++ b/app/code/Magento/Search/Model/Query.php @@ -295,8 +295,7 @@ public function getMaxQueryLength() } /** - * @return string - * @codeCoverageIgnore + * @inheritdoc */ public function getQueryText() { @@ -304,6 +303,8 @@ public function getQueryText() } /** + * Check if query maximum length exceeded. + * * @return bool * @codeCoverageIgnore */ @@ -313,6 +314,8 @@ public function isQueryTextExceeded() } /** + * Check if minimum query length reached. + * * @return bool * @codeCoverageIgnore * @since 100.1.0 From e728763d084f12d34a06ccfedb1bc90b651658cd Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel@daniel-ruf.de> Date: Wed, 17 Oct 2018 23:24:35 +0200 Subject: [PATCH 0642/1415] fix: cache count() results for loops --- app/code/Magento/Paypal/Model/Report/Settlement.php | 3 ++- .../Test/TestCase/Product/AddCompareProductsTest.php | 3 ++- .../Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php | 3 ++- .../Test/TestStep/FillShippingInformationStep.php | 3 ++- .../Test/Constraint/AssertProductsQtyAfterOrderCancel.php | 3 ++- .../Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php | 3 ++- .../Magento/Sniffs/Translation/ConstantUsageSniffTest.php | 3 ++- .../testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php | 5 +++-- .../Framework/App/Test/Unit/Language/DictionaryTest.php | 3 ++- lib/internal/Magento/Framework/Archive.php | 7 ++++--- lib/internal/Magento/Framework/Cache/Backend/Memcached.php | 3 ++- lib/internal/Magento/Framework/Filter/Template.php | 3 ++- lib/internal/Magento/Framework/System/Ftp.php | 3 ++- .../src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php | 6 ++++-- setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php | 6 ++++-- 15 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index 5dc51518f0b11..b2ab1627b24d4 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -409,7 +409,8 @@ public function parseCsv($localCsv, $format = 'new') private function getBodyItems(array $line, array $sectionColumns, array $rowMap) { $bodyItem = []; - for ($i = 1, $count = count($line); $i < $count; $i++) { + $lineCount = count($line); + for ($i = 1, $count = $lineCount; $i < $count; $i++) { if (isset($rowMap[$sectionColumns[$i]])) { if (in_array($rowMap[$sectionColumns[$i]], $this->dateTimeColumns)) { $line[$i] = $this->formatDateTimeColumns($line[$i]); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php index c700dbc362cbb..da0aa49d9697b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php @@ -76,7 +76,8 @@ public function tearDown() { $this->cmsIndex->open(); $this->cmsIndex->getLinksBlock()->openLink("Compare Products"); - for ($i = 1; $i <= count($this->products); $i++) { + $productsCount = count($this->products); + for ($i = 1; $i <= $productsCount; $i++) { $this->catalogProductCompare->getCompareProductsBlock()->removeProduct(); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php index bdd54ce3559f9..381c18d3ee686 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php @@ -95,7 +95,8 @@ public function test( $customers = []; $cartFixtures = []; - for ($i = 0; $i < count($checkoutData); $i++) { + $checkoutDataCount = count($checkoutData); + for ($i = 0; $i < $checkoutDataCount; $i++) { $customers[$i] = $this->fixtureFactory->createByCode('customer', ['dataset' => $customerDataset]); $customers[$i]->persist(); diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 67c1826f40a24..248dfc8e16dc9 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,7 +58,8 @@ public function __construct( public function run() { $shippingMethods = []; - for ($i = 0; $i < count($this->customer->getAddress()); $i++) { + $addressCount = $this->customer->getAddress(); + for ($i = 0; $i < $addressCount; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php index 28259c8f6d93b..7d229bc358995 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php @@ -52,7 +52,8 @@ public function processAssert( AssertProductForm $assertProductForm, AssertConfigurableProductForm $assertConfigurableProductForm ) { - for ($i = 0; $i < count($order->getEntityId()['products']); $i++) { + $productsCount = count($order->getEntityId()['products']); + for ($i = 0; $i < $productsCount; $i++) { $product = $order->getEntityId()['products'][$i]; $productData = $product->getData(); if ($product instanceof BundleProduct) { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php index 4b69bcd4615db..87ba4d7c2808c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php @@ -112,7 +112,8 @@ public function testPricesSegmentation($categoryId, array $entityIds, array $int $items = $model->calculateSeparators($interval); $this->assertEquals(array_keys($intervalItems), array_keys($items)); - for ($i = 0; $i < count($intervalItems); ++$i) { + $intervalItemsCount = count($intervalItems); + for ($i = 0; $i < $intervalItemsCount; ++$i) { $this->assertInternalType('array', $items[$i]); $this->assertEquals($intervalItems[$i]['from'], $items[$i]['from']); $this->assertEquals($intervalItems[$i]['to'], $items[$i]['to']); diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php index 39ad80850dd30..06a8a0accc732 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php @@ -67,7 +67,8 @@ private function tokenizeString($fileContent) $lineNumber = 1; $tokens = token_get_all($fileContent); $snifferTokens = []; - for ($i = 0; $i < count($tokens); $i++) { + $tokensCount = count($tokens); + for ($i = 0; $i < $tokensCount; $i++) { $content = is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]; $snifferTokens[$i]['line'] = $lineNumber; $snifferTokens[$i]['content'] = $content; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php index 2a6079d619d4c..0560158a82668 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php @@ -501,8 +501,9 @@ private function _checkConstantWithClasspath($constant, $class, $replacement, $c { $classPathParts = explode('\\', $class); $classPartialPath = ''; - for ($i = count($classPathParts) - 1; $i >= 0; $i--) { - if ($i === (count($classPathParts) - 1)) { + $classPathPartsCount = count($classPathParts); + for ($i = $classPathPartsCount - 1; $i >= 0; $i--) { + if ($i === ($classPathPartsCount - 1)) { $classPartialPath = $classPathParts[$i] . $classPartialPath; } else { $classPartialPath = $classPathParts[$i] . '\\' . $classPartialPath; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php index 472fff4f4f287..67518a6c7d142 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php @@ -52,7 +52,8 @@ public function testDictionaryGetter() } $file = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\File\ReadInterface::class); - for ($i = 0; $i < count($data); $i++) { + $dataCount = count($data); + for ($i = 0; $i < $dataCount; $i++) { $file->expects($this->at($i))->method('readCsv')->will($this->returnValue($data[$i])); } $file->expects($this->at($i))->method('readCsv')->will($this->returnValue(false)); diff --git a/lib/internal/Magento/Framework/Archive.php b/lib/internal/Magento/Framework/Archive.php index d43c976431b51..7c4b6984b3fc4 100644 --- a/lib/internal/Magento/Framework/Archive.php +++ b/lib/internal/Magento/Framework/Archive.php @@ -96,14 +96,15 @@ public function pack($source, $destination = 'packed.tgz', $skipRoot = false) { $archivers = $this->_getArchivers($destination); $interimSource = ''; - for ($i = 0; $i < count($archivers); $i++) { - if ($i == count($archivers) - 1) { + $archiversCount = count($archivers); + for ($i = 0; $i < $archiversCount; $i++) { + if ($i == $archiversCount - 1) { $packed = $destination; } else { $packed = dirname($destination) . '/~tmp-' . microtime(true) . $archivers[$i] . '.' . $archivers[$i]; } $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot); - if ($interimSource && $i < count($archivers)) { + if ($interimSource && $i < $archiversCount) { unlink($interimSource); } $interimSource = $source; diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index c5e7a7e9e7c09..c793714f69153 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -84,7 +84,8 @@ public function save($data, $id, $tags = [], $specificLifetime = false) if (is_string($data) && strlen($data) > $this->_options['slab_size']) { $dataChunks = str_split($data, $this->_options['slab_size']); - for ($i = 0, $cnt = count($dataChunks); $i < $cnt; $i++) { + $dataChunksCount = count($dataChunks); + for ($i = 0, $cnt = $dataChunksCount; $i < $cnt; $i++) { $chunkId = $this->_getChunkId($id, $i); if (!parent::save($dataChunks[$i], $chunkId, $tags, $specificLifetime)) { diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 10b6a17ea57dc..27797d0867924 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -374,7 +374,8 @@ protected function getVariable($value, $default = '{no_value_defined}') $stackVars = $tokenizer->tokenize(); $result = $default; $last = 0; - for ($i = 0; $i < count($stackVars); $i++) { + $stackVarsCount = count($stackVars); + for ($i = 0; $i < $stackVarsCount; $i++) { if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; diff --git a/lib/internal/Magento/Framework/System/Ftp.php b/lib/internal/Magento/Framework/System/Ftp.php index ad0673ff5d7d3..c915d50741dd2 100644 --- a/lib/internal/Magento/Framework/System/Ftp.php +++ b/lib/internal/Magento/Framework/System/Ftp.php @@ -56,7 +56,8 @@ public function mkdirRecursive($path, $mode = 0777) $dir = explode("/", $path); $path = ""; $ret = true; - for ($i = 0; $i < count($dir); $i++) { + $dirCount = count($dir); + for ($i = 0; $i < $dirCount; $i++) { $path .= "/" . $dir[$i]; if (!@ftp_chdir($this->_conn, $path)) { @ftp_chdir($this->_conn, "/"); diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index a4e3063abece4..9112192f6eb27 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -31,7 +31,8 @@ protected function _parse() $results = []; preg_match_all(Filter::CONSTRUCTION_PATTERN, $data, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if ($results[$i][1] === Filter::TRANS_DIRECTIVE_NAME) { $directive = []; if (preg_match(Filter::TRANS_DIRECTIVE_REGEX, $results[$i][2], $directive) !== 1) { @@ -43,7 +44,8 @@ protected function _parse() } preg_match_all(self::HTML_FILTER, $data, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (!empty($results[$i]['value'])) { $this->_addPhrase($results[$i]['value']); } diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 4095b12c9a6c6..0f6a402e2609c 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -22,7 +22,8 @@ protected function _parse() $fileRow = fgets($fileHandle, 4096); $results = []; preg_match_all('/mage\.__\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); @@ -30,7 +31,8 @@ protected function _parse() } preg_match_all('/\\$t\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); From ad91d28d2602bb126834deb4350cdcff2186355b Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 17 Oct 2018 16:55:52 -0500 Subject: [PATCH 0643/1415] MAGETWO-95642: Import error --- .../Controller/Adminhtml/Import/Validate.php | 18 +++++--- .../Magento/ImportExport/Model/Import.php | 42 +++++++++++++++--- .../ImportExport/Model/Import/Source/Zip.php | 11 ++--- .../Adminhtml/Import/ValidateTest.php | 17 ++++++- .../Import/_files/catalog_product.zip | Bin 0 -> 955 bytes .../Magento/Framework/Archive/Zip.php | 16 ++++--- 6 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/catalog_product.zip diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php index 204e9b11085ed..a0992e28bb2cd 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php @@ -13,6 +13,10 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\ImportExport\Model\Import\Adapter as ImportAdapter; +/** + * Import validate controller action. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Validate extends ImportResultController implements HttpPostActionInterface { /** @@ -24,6 +28,7 @@ class Validate extends ImportResultController implements HttpPostActionInterface * Validate uploaded files action * * @return \Magento\Framework\Controller\ResultInterface + * @SuppressWarnings(PHPMD.Superglobals) */ public function execute() { @@ -42,12 +47,7 @@ public function execute() /** @var $import \Magento\ImportExport\Model\Import */ $import = $this->getImport()->setData($data); try { - $source = ImportAdapter::findAdapterFor( - $import->uploadSource(), - $this->_objectManager->create(\Magento\Framework\Filesystem::class) - ->getDirectoryWrite(DirectoryList::ROOT), - $data[$import::FIELD_FIELD_SEPARATOR] - ); + $source = $import->uploadFileAndGetSource(); $this->processValidationResult($import->validateSource($source), $resultBlock); } catch (\Magento\Framework\Exception\LocalizedException $e) { $resultBlock->addError($e->getMessage()); @@ -72,6 +72,7 @@ public function execute() * @param bool $validationResult * @param Result $resultBlock * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ private function processValidationResult($validationResult, $resultBlock) { @@ -109,6 +110,8 @@ private function processValidationResult($validationResult, $resultBlock) } /** + * Provides import model. + * * @return Import * @deprecated 100.1.0 */ @@ -128,6 +131,7 @@ private function getImport() * * @param Result $resultBlock * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ private function addMessageToSkipErrors(Result $resultBlock) { @@ -148,6 +152,7 @@ private function addMessageToSkipErrors(Result $resultBlock) * * @param Result $resultBlock * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ private function addMessageForValidResult(Result $resultBlock) { @@ -166,6 +171,7 @@ private function addMessageForValidResult(Result $resultBlock) * * @param Result $resultBlock * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ private function collectErrors(Result $resultBlock) { diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index b5e8220e0e9b0..f336e0d41e089 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -19,6 +19,7 @@ * @method string getBehavior() getBehavior() * @method \Magento\ImportExport\Model\Import setEntity() setEntity(string $value) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @since 100.0.2 */ class Import extends \Magento\ImportExport\Model\AbstractModel @@ -268,6 +269,7 @@ protected function _getEntityAdapter() * * @param string $sourceFile Full path to source file * @return \Magento\ImportExport\Model\Import\AbstractSource + * @throws \Magento\Framework\Exception\FileSystemException */ protected function _getSourceAdapter($sourceFile) { @@ -283,6 +285,7 @@ protected function _getSourceAdapter($sourceFile) * * @param ProcessingErrorAggregatorInterface $validationResult * @return string[] + * @throws \Magento\Framework\Exception\LocalizedException */ public function getOperationResultMessages(ProcessingErrorAggregatorInterface $validationResult) { @@ -379,6 +382,7 @@ public function getEntity() * Returns number of checked entities. * * @return int + * @throws \Magento\Framework\Exception\LocalizedException */ public function getProcessedEntitiesCount() { @@ -389,6 +393,7 @@ public function getProcessedEntitiesCount() * Returns number of checked rows. * * @return int + * @throws \Magento\Framework\Exception\LocalizedException */ public function getProcessedRowsCount() { @@ -443,6 +448,8 @@ public function importSource() } /** + * Process import. + * * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ @@ -455,6 +462,7 @@ protected function processImport() * Import possibility getter. * * @return bool + * @throws \Magento\Framework\Exception\LocalizedException */ public function isImportAllowed() { @@ -462,6 +470,8 @@ public function isImportAllowed() } /** + * Provides error aggregator. + * * @return ProcessingErrorAggregatorInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -471,7 +481,7 @@ public function getErrorAggregator() } /** - * Move uploaded file and create source adapter instance. + * Move uploaded file. * * @throws \Magento\Framework\Exception\LocalizedException * @return string Source file path @@ -523,14 +533,27 @@ public function uploadSource() } $this->_removeBom($sourceFile); $this->createHistoryReport($sourceFileRelative, $entity, $extension, $result); - // trying to create source adapter for file and catch possible exception to be convinced in its adequacy + return $sourceFile; + } + + /** + * Move uploaded file and provide source instance. + * + * @return Import\AbstractSource + * @throws \Magento\Framework\Exception\FileSystemException + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function uploadFileAndGetSource() + { + $sourceFile = $this->uploadSource(); try { - $this->_getSourceAdapter($sourceFile); + $source = $this->_getSourceAdapter($sourceFile); } catch (\Exception $e) { - $this->_varDirectory->delete($sourceFileRelative); + $this->_varDirectory->delete($this->_varDirectory->getRelativePath($sourceFile)); throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage())); } - return $sourceFile; + + return $source; } /** @@ -538,6 +561,7 @@ public function uploadSource() * * @param string $sourceFile * @return $this + * @throws \Magento\Framework\Exception\FileSystemException */ protected function _removeBom($sourceFile) { @@ -557,6 +581,7 @@ protected function _removeBom($sourceFile) * * @param \Magento\ImportExport\Model\Import\AbstractSource $source * @return bool + * @throws \Magento\Framework\Exception\LocalizedException */ public function validateSource(\Magento\ImportExport\Model\Import\AbstractSource $source) { @@ -595,6 +620,7 @@ public function validateSource(\Magento\ImportExport\Model\Import\AbstractSource * Invalidate indexes by process codes. * * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function invalidateIndex() { @@ -661,6 +687,7 @@ public function getEntityBehaviors() * ) * * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ public function getUniqueEntityBehaviors() { @@ -710,9 +737,9 @@ public function isReportEntityType($entity = null) /** * Create history report * + * @param string $sourceFileRelative * @param string $entity * @param string $extension - * @param string $sourceFileRelative * @param array $result * @return $this * @throws \Magento\Framework\Exception\LocalizedException @@ -751,6 +778,7 @@ protected function createHistoryReport($sourceFileRelative, $entity, $extension * Get count of created items * * @return int + * @throws \Magento\Framework\Exception\LocalizedException */ public function getCreatedItemsCount() { @@ -761,6 +789,7 @@ public function getCreatedItemsCount() * Get count of updated items * * @return int + * @throws \Magento\Framework\Exception\LocalizedException */ public function getUpdatedItemsCount() { @@ -771,6 +800,7 @@ public function getUpdatedItemsCount() * Get count of deleted items * * @return int + * @throws \Magento\Framework\Exception\LocalizedException */ public function getDeletedItemsCount() { diff --git a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php index 7c13e47957cda..6fa87ab5d5c4d 100644 --- a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php +++ b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php @@ -25,13 +25,14 @@ public function __construct( $options ) { $zip = new \Magento\Framework\Archive\Zip(); - $file = $zip->unpack( - $directory->getRelativePath($file), - $directory->getRelativePath(preg_replace('/\.zip$/i', '.csv', $file)) + $csvFile = $zip->unpack( + $file, + preg_replace('/\.zip$/i', '.csv', $file) ); - if (!$file) { + if (!$csvFile) { throw new ValidatorException(__('Sorry, but the data is invalid or the file is not uploaded.')); } - parent::__construct($file, $directory, $options); + $directory->delete($directory->getRelativePath($file)); + parent::__construct($csvFile, $directory, $options); } } diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php index 552a23a0c1fd5..9afce0ed10bcd 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php @@ -17,12 +17,15 @@ class ValidateTest extends \Magento\TestFramework\TestCase\AbstractBackendContro /** * @dataProvider validationDataProvider * @param string $fileName + * @param string $mimeType * @param string $message * @param string $delimiter + * @throws \Magento\Framework\Exception\FileSystemException * @backupGlobals enabled * @magentoDbIsolation enabled + * @SuppressWarnings(PHPMD.Superglobals) */ - public function testValidationReturn($fileName, $message, $delimiter) + public function testValidationReturn(string $fileName, string $mimeType, string $message, string $delimiter) { $validationStrategy = ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_STOP_ON_ERROR; @@ -50,7 +53,7 @@ public function testValidationReturn($fileName, $message, $delimiter) $_FILES = [ 'import_file' => [ 'name' => $fileName, - 'type' => 'text/csv', + 'type' => $mimeType, 'tmp_name' => $target, 'error' => 0, 'size' => filesize($target) @@ -84,24 +87,34 @@ public function validationDataProvider() return [ [ 'file_name' => 'catalog_product.csv', + 'mime-type' => 'text/csv', 'message' => 'File is valid', 'delimiter' => ',', ], [ 'file_name' => 'test.txt', + 'mime-type' => 'text/csv', 'message' => '\'txt\' file extension is not supported', 'delimiter' => ',', ], [ 'file_name' => 'incorrect_catalog_product_comma.csv', + 'mime-type' => 'text/csv', 'message' => 'Download full report', 'delimiter' => ',', ], [ 'file_name' => 'incorrect_catalog_product_semicolon.csv', + 'mime-type' => 'text/csv', 'message' => 'Download full report', 'delimiter' => ';', ], + [ + 'file_name' => 'catalog_product.zip', + 'mime-type' => 'application/zip', + 'message' => 'File is valid', + 'delimiter' => ',', + ], ]; } } diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/catalog_product.zip b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/catalog_product.zip new file mode 100644 index 0000000000000000000000000000000000000000..812beae22b786dc74cf22d914869a811e4be1e8b GIT binary patch literal 955 zcmWIWW@Zs#W?<l8*cck<Yk%>>Cw?IBAqNA4FarZaa$-qhPJViPK~a86X>y5Pa&g(# z(6jF@8}RJ^EOPZ6<67312OKdw3LY{pT2pG>ZKApHvwU^+9JSo<N0+;(E&aIt@8-!D zudguK$iHAqB40%Z&#Z>4A~oXC*J|cDY;8;Yz}Pq?jz!%<U{gU<e(i+05!+r^%-Q<> zYevi)-_wR2l?;U!GL@wQ7xnI9K6EfPco%=&p2Usu64&O`rpPY$i_sL^&ZzG8{z}4{ z)`BqRZ)@BYjF>Y%r(BrT+<L~2)!6q%+x(A9wQ?L~c{A;+Ra+PTIJsMldjppz`-G-D zIrV`F0m>ULihHIW3%8hG^TO!hiIZG&cWhC;=aD$e{H~&J&>}xR@xo*GW(JyBT<qze z_KEwXov>=+-Kyhkb5o2x&#@XzWv=Z$=E?Nve(B2lZ^Li$x(6}7xg#xS@#3VgTKX>r z_s=bMe_V13UBqr~?{IA4PAU1)xIRH)<<(b`N51Z1^b+2Z@g^+d*_2=5S!=f}IrD6H z-de>=H#F^zeSENF<?WRf(*rew)!mso|L!>ETNR(gV^&)D&#$fj6(=Wu2CG*olT6>5 zeJ2BVt-5S3w8ZR-#f#R~DRxX=vwyAQTlQB=nXyrCs`<M&T|KSQ_2GXm*3_@q@?rXk zBxCbv%kwwp8y9AmXnRlAwLR72eRTeZ$-OR<yzQEjgRVbWs&vLY{bKmcJ%-b_h;Mij zWRu7~SIgfwYkM49P~5ty5xbX_NZSNvrH9=(;j8M`U1OW?<i_#z+td}|d;UmpTC&J5 z=e`(oOf}XmLT(A)*-zWfnTo{i<7_>l9Nl3$H+1r)-xCf9CC{wB|ETSt8+YE`&S}M3 z()C}z=eS$=iLLt77XH<5W&cf&)QOWgRRcDao!wXWbx+<r^YyELz1@BN?C$V<m)gkR zOFrG?ets@<>+a{aDJQE=+}*p~C~4|TNvE$TzwZ0>AXjGYiC2IB9gUlItG4Lsbd%2A zmNWNcUHzl<S>{zG=hr=AzCV+Vuko)^GFWK4jN$BQnFU8y9<99fda4fl&$F{-@=M=e zll^cup5gze*uSs(8}fxdd~cLHT9@!g`oZjahPrcq<bFI;{BZVk_<zP9@&VqAO!myU za*zrz4}pL}!;(f2jU_*EF(`m!7#JBO7#et@3JlV&FgA!UYcvDVP=0_nD;q=&BSR{X K;Q-8{3=9Cp%do}( literal 0 HcmV?d00001 diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index 908b045c15397..c41f8b28ce348 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -52,15 +52,19 @@ public function pack($source, $destination) public function unpack($source, $destination) { $zip = new \ZipArchive(); - $zip->open($source); - $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - if ($filename) { - $zip->extractTo(dirname($destination), $filename); - rename(dirname($destination).'/'.$filename, $destination); + if ($zip->open($source) === true) { + $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); + if ($filename) { + $zip->extractTo(dirname($destination), $filename); + rename(dirname($destination).'/'.$filename, $destination); + } else { + $destination = ''; + } + $zip->close(); } else { $destination = ''; } - $zip->close(); + return $destination; } From 7194fc81543fa40633ad0bfdb1ca23502a3330b7 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 17 Oct 2018 17:02:17 -0500 Subject: [PATCH 0644/1415] MAGETWO-71686: File is imported error - Fixed error aggregator not obeying the validation strategy from the UI --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 8896f84ce2471..eb691d011a292 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; +use Magento\ImportExport\Model\Import; class Start extends ImportResultController implements HttpPostActionInterface { @@ -63,6 +64,11 @@ public function execute() $this->importModel->setData($data); $errorAggregator = $this->importModel->getErrorAggregator(); + $errorAggregator->initValidationStrategy( + $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), + $this->importModel->getData(Import::FIELD_NAME_ALLOWED_ERROR_COUNT) + ); + try { $this->importModel->importSource(); } catch (\Exception $e) { From b65b49f1bae762988574a9d23f3892f3f65cc913 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Thu, 18 Oct 2018 12:12:23 +0530 Subject: [PATCH 0645/1415] Fix SKU limit in import new products for 2.3 with backward compatible allow 64 characters for SKU --- .../Model/Import/Product/Validator.php | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index b184334b179ea..793ad935363d3 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -71,7 +71,7 @@ protected function textValidation($attrCode, $type) if ($type == 'text') { $valid = $this->string->strlen($val) < Product::DB_MAX_TEXT_LENGTH; } else if ($attrCode == Product::COL_SKU) { - $valid = $this->string->strlen($val) < SKU::SKU_MAX_LENGTH; + $valid = $this->string->strlen($val) <= SKU::SKU_MAX_LENGTH; } else { $valid = $this->string->strlen($val) < Product::DB_MAX_VARCHAR_LENGTH; } @@ -153,12 +153,7 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra $doCheck = true; } - if ($doCheck === true) { - return isset($rowData[$attrCode]) - && strlen(trim($rowData[$attrCode])) - && trim($rowData[$attrCode]) !== $this->context->getEmptyAttributeValueConstant(); - } - return true; + return $doCheck ? isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode])) : true; } /** @@ -196,11 +191,6 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) if (!strlen(trim($rowData[$attrCode]))) { return true; } - - if ($rowData[$attrCode] === $this->context->getEmptyAttributeValueConstant() && !$attrParams['is_required']) { - return true; - } - switch ($attrParams['type']) { case 'varchar': case 'text': @@ -222,12 +212,6 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) break; } } - - $uniqueValues = array_unique($values); - if (count($uniqueValues) != count($values)) { - $valid = false; - $this->_addMessages([RowValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES]); - } break; case 'datetime': $val = trim($rowData[$attrCode]); From 57902258f066e4802f026f64e12f48663475b0b3 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Thu, 18 Oct 2018 12:31:58 +0530 Subject: [PATCH 0646/1415] Fix SKU limit in import new products for 2.3 with backward compatible allow 64 characters --- .../Model/Import/Product/Validator.php | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 793ad935363d3..21f7f87875e12 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -153,7 +153,12 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra $doCheck = true; } - return $doCheck ? isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode])) : true; + if ($doCheck === true) { + return isset($rowData[$attrCode]) + && strlen(trim($rowData[$attrCode])) + && trim($rowData[$attrCode]) !== $this->context->getEmptyAttributeValueConstant(); + } + return true; } /** @@ -191,6 +196,11 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) if (!strlen(trim($rowData[$attrCode]))) { return true; } + + if ($rowData[$attrCode] === $this->context->getEmptyAttributeValueConstant() && !$attrParams['is_required']) { + return true; + } + switch ($attrParams['type']) { case 'varchar': case 'text': @@ -212,6 +222,12 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) break; } } + + $uniqueValues = array_unique($values); + if (count($uniqueValues) != count($values)) { + $valid = false; + $this->_addMessages([RowValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES]); + } break; case 'datetime': $val = trim($rowData[$attrCode]); @@ -328,4 +344,4 @@ public function init($context) $validator->init($context); } } -} +} \ No newline at end of file From cb2aadc99d86279fcb0f352b6972eedb26ba98de Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 18 Oct 2018 13:25:42 +0300 Subject: [PATCH 0647/1415] MAGETWO-95654: Constraint removal is not treated as destructive operation - Marked 'drop_reference' as destructive operation --- .../Declaration/Schema/Operations/DropReference.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php index 4a5f651a10815..95fc1c42210be 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php @@ -35,18 +35,15 @@ public function __construct(DropElement $dropElement) } /** - * {@inheritdoc} - * We can drop references and this will not cause any issues. - * - * @return bool + * @inheritdoc */ public function isOperationDestructive() { - return false; + return true; } /** - * {@inheritdoc} + * @inheritdoc */ public function getOperationName() { @@ -54,7 +51,7 @@ public function getOperationName() } /** - * {@inheritdoc} + * @inheritdoc */ public function doOperation(ElementHistory $elementHistory) { From 2fc6596cb403a788a0226b1ae03bea00b68bf26d Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Thu, 18 Oct 2018 15:57:24 +0300 Subject: [PATCH 0648/1415] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Delete abandoned tables in full reindex --- .../Catalog/Helper/Product/Flat/Indexer.php | 32 ---------- .../Indexer/Category/Flat/Action/Full.php | 63 +++++++++++-------- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php index 0366e01ee86ea..93eaa23b89f16 100644 --- a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php +++ b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php @@ -466,17 +466,6 @@ public function getFlatTableName($storeId) return sprintf('%s_%s', $this->getTable('catalog_product_flat'), $storeId); } - /** - * Retrieve Catalog Product Flat Table name - * - * @param int $storeId - * @return string - */ - private function getCategoryFlatTableName(int $storeId): string - { - return sprintf('%s_store_%s', $this->getTable('catalog_category_flat'), $storeId); - } - /** * Retrieve loaded attribute by code * @@ -526,25 +515,4 @@ public function deleteAbandonedStoreFlatTables() $connection->dropTable($table); } } - - /** - * Delete all category flat tables for not existing stores - * - * @return void - */ - public function deleteAbandonedStoreCategoryFlatTables() - { - $connection = $this->_resource->getConnection(); - $existentTables = $connection->getTables($connection->getTableName('catalog_category_flat_store_%')); - $actualStoreTables = []; - foreach ($this->_storeManager->getStores() as $store) { - $actualStoreTables[] = $this->getCategoryFlatTableName($store->getId()); - } - - $tablesToDelete = array_diff($existentTables, $actualStoreTables); - - foreach ($tablesToDelete as $table) { - $connection->dropTable($table); - } - } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index c1e6decf6afef..624001b498449 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -5,8 +5,6 @@ */ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; -use Magento\Framework\App\ResourceConnection; - /** * Class for full reindex flat categories */ @@ -24,28 +22,6 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction */ protected $allowTableChanges = true; - /** - * @var \Magento\Catalog\Helper\Product\Flat\Indexer - */ - private $indexer; - - /** - * @param ResourceConnection $resource - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper - * @param \Magento\Catalog\Helper\Product\Flat\Indexer $indexer - */ - public function __construct( - ResourceConnection $resource, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, - \Magento\Catalog\Helper\Product\Flat\Indexer $indexer = null - ) { - $this->indexer = $indexer ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Catalog\Helper\Product\Flat\Indexer::class); - parent::__construct($resource, $storeManager, $resourceHelper); - } - /** * Add suffix to table name to show it is old * @@ -196,6 +172,43 @@ protected function switchTables(array $stores = []) return $this; } + /** + * Retrieve all actual Catalog Product Flat Table names + * + * @return string[] + */ + private function getActualStoreTablesForCategoryFlat(): array + { + $actualStoreTables = []; + foreach ($this->storeManager->getStores() as $store) { + $actualStoreTables[] = sprintf( + '%s_store_%s', + $this->connection->getTableName('catalog_category_flat'), $store->getId() + ); + } + + return $actualStoreTables; + } + + /** + * Delete all category flat tables for not existing stores + * + * @return void + */ + private function deleteAbandonedStoreCategoryFlatTables(): void + { + $existentTables = $this->connection->getTables( + $this->connection->getTableName('catalog_category_flat_store_%') + ); + $actualStoreTables = $this->getActualStoreTablesForCategoryFlat(); + + $tablesToDelete = array_diff($existentTables, $actualStoreTables); + + foreach ($tablesToDelete as $table) { + $this->connection->dropTable($table); + } + } + /** * Transactional rebuild flat data from eav * @@ -211,7 +224,7 @@ public function reindexAll() $stores = $this->storeManager->getStores(); $this->populateFlatTables($stores); $this->switchTables($stores); - $this->indexer->deleteAbandonedStoreCategoryFlatTables(); + $this->deleteAbandonedStoreCategoryFlatTables(); $this->allowTableChanges = true; return $this; From 9170bb529f202a1ad56e64200b7b1c1eccb301fd Mon Sep 17 00:00:00 2001 From: Zachary Craig <zack@zack6849.com> Date: Thu, 18 Oct 2018 09:56:49 -0400 Subject: [PATCH 0649/1415] Add newline to conform to docblock standards --- app/code/Magento/Sales/Api/Data/OrderInterface.php | 1 + app/code/Magento/Sales/Api/Data/OrderItemInterface.php | 1 + app/code/Magento/Sales/Model/Order.php | 1 + app/code/Magento/Sales/Model/Order/Item.php | 1 + 4 files changed, 4 insertions(+) diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php index bdf8cfe5416dd..b45fddc7d7354 100644 --- a/app/code/Magento/Sales/Api/Data/OrderInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php @@ -582,6 +582,7 @@ public function getAdjustmentPositive(); * Gets the applied rule IDs for the order. * * Rules are comma separated if there are more than one. + * * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php index 4aabd05a0efcc..2aee648ef7c9f 100644 --- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php @@ -416,6 +416,7 @@ public function getAmountRefunded(); * Gets the applied rule IDs for the order item. * * Rules are comma separated if there are more than one. + * * @return string|null Applied rule IDs. */ public function getAppliedRuleIds(); diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 137c8b440813d..ccf8b4470d942 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -2114,6 +2114,7 @@ public function getAdjustmentPositive() * Returns applied_rule_ids * * Rules are comma separated if there are more than one. + * * @return string|null */ public function getAppliedRuleIds() diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index 1d821ad041e72..834d1e4694cf9 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -726,6 +726,7 @@ public function getAmountRefunded() * Returns applied_rule_ids * * Rules are comma separated if there are more than one. + * * @return string|null */ public function getAppliedRuleIds() From bb4f60197ea9af573434f838ed61c014e3fbd132 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 18 Oct 2018 17:09:34 +0300 Subject: [PATCH 0650/1415] GraphQL-174: Absolute image paths for Products --- .../Model/Resolver/Product/Image.php | 66 ------------------- .../Model/Resolver/Product/ProductImage.php | 57 +++++++--------- 2 files changed, 22 insertions(+), 101 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php deleted file mode 100644 index 6830aecb78f10..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\ImageFactory; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Returns product's image. If the image is not set, returns a placeholder - */ -class Image implements ResolverInterface -{ - /** - * Product image factory - * - * @var ImageFactory - */ - private $productImageFactory; - - /** - * @param ImageFactory $productImageFactory - */ - public function __construct( - ImageFactory $productImageFactory - ) { - $this->productImageFactory = $productImageFactory; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): array { - if (!isset($value['model'])) { - throw new LocalizedException(__('"model" value should be specified')); - } - /** @var Product $product */ - $product = $value['model']; - $imageType = $field->getName(); - $path = $product->getData($imageType); - - $image = $this->productImageFactory->create(); - $image->setDestinationSubdir($imageType) - ->setBaseFile($path); - $imageUrl = $image->getUrl(); - - return [ - 'url' => $imageUrl, - 'path' => $path, - ]; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 9dc0dd68ee457..3caa79e68c235 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -8,43 +8,34 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; +use Magento\Catalog\Model\Product\ImageFactory; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Store\Model\StoreManagerInterface; /** - * Return product image paths by image type. + * Returns product's image data */ class ProductImage implements ResolverInterface { /** - * @var CatalogImageHelperFactory - */ - private $catalogImageHelperFactory; - - /** - * @var StoreManagerInterface + * Product image factory + * + * @var ImageFactory */ - private $storeManager; + private $productImageFactory; /** - * @param CatalogImageHelperFactory $catalogImageHelperFactory - * @param StoreManagerInterface $storeManager + * @param ImageFactory $productImageFactory */ public function __construct( - CatalogImageHelperFactory $catalogImageHelperFactory, - StoreManagerInterface $storeManager + ImageFactory $productImageFactory ) { - $this->catalogImageHelperFactory = $catalogImageHelperFactory; - $this->storeManager = $storeManager; + $this->productImageFactory = $productImageFactory; } /** - * Get product's image by type. - * * @inheritdoc */ public function resolve( @@ -53,30 +44,26 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ) { + ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ $product = $value['model']; $imageType = $field->getName(); - /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ - $catalogImageHelper = $this->catalogImageHelperFactory->create(); + $imagePath = $product->getData($imageType); + $imageLabel = $product->getData($imageType . '_' . 'label') ?? $product->getName(); - /** @var \Magento\Catalog\Helper\Image $image */ - $image = $catalogImageHelper->init( - $product, - 'product_' . $imageType, - ['type' => $imageType] - ); + $image = $this->productImageFactory->create(); + $image->setDestinationSubdir($imageType) + ->setBaseFile($imagePath); + $imageUrl = $image->getUrl(); - $imageData = [ - 'url' => $image->getUrl(), - 'path' => $product->getData($imageType), - 'label' => $image->getLabel() + return [ + 'url' => $imageUrl, + 'path' => $imagePath, + 'label' => $imageLabel, ]; - - return $imageData; } } From eaa459f90b25bc5777f889a0fc3c3c447aea9711 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 18 Oct 2018 09:11:46 -0500 Subject: [PATCH 0651/1415] MAGETWO-95642: Import error --- app/code/Magento/ImportExport/Model/Import.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index f336e0d41e089..410a4e6fee990 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\HTTP\Adapter\FileTransferFactory; +use Magento\Framework\Stdlib\DateTime\DateTime; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingError; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; @@ -168,6 +169,16 @@ class Import extends \Magento\ImportExport\Model\AbstractModel */ protected $_filesystem; + /** + * @var History + */ + private $importHistoryModel; + + /** + * @var DateTime + */ + private $localeDate; + /** * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Filesystem $filesystem @@ -182,7 +193,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel * @param Source\Import\Behavior\Factory $behaviorFactory * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry * @param History $importHistoryModel - * @param \Magento\Framework\Stdlib\DateTime\DateTime + * @param DateTime $localeDate * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -200,7 +211,7 @@ public function __construct( \Magento\ImportExport\Model\Source\Import\Behavior\Factory $behaviorFactory, \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, \Magento\ImportExport\Model\History $importHistoryModel, - \Magento\Framework\Stdlib\DateTime\DateTime $localeDate, + DateTime $localeDate, array $data = [] ) { $this->_importExportData = $importExportData; From dc76327173dca206638feff496363757c6509693 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 09:15:47 -0500 Subject: [PATCH 0652/1415] MAGETWO-71686: File is imported error - Fixed static issue --- .../Magento/ImportExport/Controller/Adminhtml/Import/Start.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index eb691d011a292..8f64d023c19f9 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -10,6 +10,9 @@ use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; +/** + * Controller responsible for initiating the import process + */ class Start extends ImportResultController implements HttpPostActionInterface { /** From 0fc8a1f405b4b63c81715f3549a08e63b4ea196b Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Wed, 17 Oct 2018 16:27:14 -0500 Subject: [PATCH 0653/1415] MAGETWO-95620: Path Validation in Templates - Resolve real directory of template file before validating path in allowed directories - Update unit test to mock this new dependency --- .../View/Element/Template/File/Validator.php | 14 +++++-- .../Element/Template/File/ValidatorTest.php | 39 +++++++++++-------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php b/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php index 4b4e7e1bad467..5f18c78e3a0ad 100644 --- a/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php +++ b/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php @@ -7,10 +7,10 @@ use \Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Component\ComponentRegistrar; +use \Magento\Framework\Filesystem\Driver\File as FileDriver; /** * Class Validator - * @package Magento\Framework\View\Element\Template\File */ class Validator { @@ -68,6 +68,11 @@ class Validator */ protected $_compiledDir; + /** + * @var FileDriver + */ + private $fileDriver; + /** * Class constructor * @@ -75,12 +80,14 @@ class Validator * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface * @param ComponentRegistrar $componentRegistrar * @param string|null $scope + * @param FileDriver|null $fileDriver */ public function __construct( \Magento\Framework\Filesystem $filesystem, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface, ComponentRegistrar $componentRegistrar, - $scope = null + $scope = null, + ?FileDriver $fileDriver = null ) { $this->_filesystem = $filesystem; $this->_isAllowSymlinks = $scopeConfigInterface->getValue(self::XML_PATH_TEMPLATE_ALLOW_SYMLINK, $scope); @@ -88,6 +95,7 @@ public function __construct( $this->moduleDirs = $componentRegistrar->getPaths(ComponentRegistrar::MODULE); $this->_compiledDir = $this->_filesystem->getDirectoryRead(DirectoryList::TMP_MATERIALIZATION_DIR) ->getAbsolutePath(); + $this->fileDriver = $fileDriver ?: \Magento\Framework\App\ObjectManager::getInstance()->get(FileDriver::class); } /** @@ -128,7 +136,7 @@ protected function isPathInDirectories($path, $directories) $directories = (array)$directories; } foreach ($directories as $directory) { - if (0 === strpos($path, $directory)) { + if (0 === strpos($this->fileDriver->getRealPath($path), $directory)) { return true; } } diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/Template/File/ValidatorTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/Template/File/ValidatorTest.php index 28d58f4685e80..7a3578993f375 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Element/Template/File/ValidatorTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/Template/File/ValidatorTest.php @@ -20,21 +20,21 @@ class ValidatorTest extends \PHPUnit\Framework\TestCase * * @var \Magento\Framework\View\Element\Template\File\Validator */ - private $_validator; + private $validator; /** * Mock for view file system * * @var \Magento\Framework\FileSystem|\PHPUnit_Framework_MockObject_MockObject */ - private $_fileSystemMock; + private $fileSystemMock; /** * Mock for scope config * * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $_scopeConfigMock; + private $scopeConfigMock; /** * Mock for root directory reader @@ -62,12 +62,12 @@ class ValidatorTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->_fileSystemMock = $this->createMock(\Magento\Framework\Filesystem::class); - $this->_scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); + $this->fileSystemMock = $this->createMock(\Magento\Framework\Filesystem::class); + $this->scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $this->rootDirectoryMock = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadInterface::class); $this->compiledDirectoryMock = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadInterface::class); - $this->_fileSystemMock->expects($this->any()) + $this->fileSystemMock->expects($this->any()) ->method('getDirectoryRead') ->will($this->returnValueMap( [ @@ -91,10 +91,18 @@ protected function setUp() ] ) ); - $this->_validator = new \Magento\Framework\View\Element\Template\File\Validator( - $this->_fileSystemMock, - $this->_scopeConfigMock, - $this->componentRegistrar + + $fileDriverMock = $this->createMock(\Magento\Framework\Filesystem\Driver\File::class); + $fileDriverMock->expects($this->any()) + ->method('getRealPath') + ->willReturnArgument(0); + + $this->validator = new \Magento\Framework\View\Element\Template\File\Validator( + $this->fileSystemMock, + $this->scopeConfigMock, + $this->componentRegistrar, + null, + $fileDriverMock ); } @@ -103,23 +111,22 @@ protected function setUp() * * @param string $file * @param bool $expectedResult - * - * @dataProvider testIsValidDataProvider - * * @return void + * + * @dataProvider isValidDataProvider */ public function testIsValid($file, $expectedResult) { $this->rootDirectoryMock->expects($this->any())->method('isFile')->will($this->returnValue(true)); - $this->assertEquals($expectedResult, $this->_validator->isValid($file)); + $this->assertEquals($expectedResult, $this->validator->isValid($file)); } /** * Data provider for testIsValid * - * @return [] + * @return array */ - public function testIsValidDataProvider() + public function isValidDataProvider() { return [ 'empty' => ['', false], From c02a00a171d4a9aaae6afc43205717718d026038 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 10:55:03 -0500 Subject: [PATCH 0654/1415] MAGETWO-95471: [Forwardport] Layered navigation price step issue with Elasticsearch 2+ - Applied existing fix - Added test coverage --- .../Elasticsearch/SearchAdapter/Dynamic/DataProvider.php | 2 +- .../Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 0add517ba94ad..527260699e161 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -209,7 +209,7 @@ public function getAggregation( 'prices' => [ 'histogram' => [ 'field' => $fieldName, - 'interval' => $range, + 'interval' => (float)$range, ], ], ]; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php index 41be237efe532..a7914ceec12d7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php @@ -320,6 +320,10 @@ public function testGetAggregation() $this->clientMock->expects($this->once()) ->method('query') + ->with($this->callback(function($query) { + // Assert the interval is queried as a float. See MAGETWO-95471 + return $query['body']['aggregations']['prices']['histogram']['interval'] === 10.0; + })) ->willReturn([ 'aggregations' => [ 'prices' => [ From daa937c48c06a476baa8a02d896d94e414334cfd Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 11:00:35 -0500 Subject: [PATCH 0655/1415] MAGETWO-95471: [Forwardport] Layered navigation price step issue with Elasticsearch 2+ - Static fixes --- .../SearchAdapter/Dynamic/DataProvider.php | 12 +++++++----- .../Unit/SearchAdapter/Dynamic/DataProviderTest.php | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 527260699e161..e99da34533475 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -9,6 +9,8 @@ use Magento\Elasticsearch\SearchAdapter\QueryContainer; /** + * Provides data for search using ElasticSearch + * * @api * @since 100.1.0 */ @@ -120,7 +122,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getRange() @@ -129,7 +131,7 @@ public function getRange() } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage $entityStorage) @@ -168,7 +170,7 @@ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getInterval( @@ -191,7 +193,7 @@ public function getInterval( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregation( @@ -225,7 +227,7 @@ public function getAggregation( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function prepareData($range, array $dbRanges) diff --git a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php index a7914ceec12d7..9c717ea240a5d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php @@ -320,7 +320,7 @@ public function testGetAggregation() $this->clientMock->expects($this->once()) ->method('query') - ->with($this->callback(function($query) { + ->with($this->callback(function ($query) { // Assert the interval is queried as a float. See MAGETWO-95471 return $query['body']['aggregations']['prices']['histogram']['interval'] === 10.0; })) From 7a326128f10815e5ef05c94bef26ba1ab4f9087b Mon Sep 17 00:00:00 2001 From: Igor Miniailo <igor.minyaylo@gmail.com> Date: Thu, 18 Oct 2018 19:38:32 +0300 Subject: [PATCH 0656/1415] MSI-1735: Add @deprecated PHP DocBlock to all public interfaces and extension points of module CatalogInventory --- .../CatalogInventory/Api/Data/StockCollectionInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/Data/StockInterface.php | 5 +++-- .../Api/Data/StockItemCollectionInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/Data/StockItemInterface.php | 5 +++-- .../Api/Data/StockStatusCollectionInterface.php | 5 +++-- .../CatalogInventory/Api/Data/StockStatusInterface.php | 5 +++-- .../CatalogInventory/Api/RegisterProductSaleInterface.php | 5 +++-- .../CatalogInventory/Api/RevertProductSaleInterface.php | 5 +++-- .../CatalogInventory/Api/StockConfigurationInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockCriteriaInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockIndexInterface.php | 5 +++-- .../CatalogInventory/Api/StockItemCriteriaInterface.php | 5 +++-- .../CatalogInventory/Api/StockItemRepositoryInterface.php | 5 +++-- .../CatalogInventory/Api/StockManagementInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockRegistryInterface.php | 5 +++-- .../CatalogInventory/Api/StockRepositoryInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockStateInterface.php | 5 +++-- .../CatalogInventory/Api/StockStatusCriteriaInterface.php | 5 +++-- .../CatalogInventory/Api/StockStatusRepositoryInterface.php | 5 +++-- .../Block/Adminhtml/Form/Field/Minsaleqty.php | 5 +++-- .../CatalogInventory/Block/Adminhtml/Form/Field/Stock.php | 5 +++-- app/code/Magento/CatalogInventory/Block/Qtyincrements.php | 5 +++-- .../CatalogInventory/Block/Stockqty/DefaultStockqty.php | 5 +++-- app/code/Magento/CatalogInventory/Helper/Stock.php | 5 +++-- .../Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php | 5 +++-- .../CatalogInventory/Model/Quote/Item/QuantityValidator.php | 5 +++-- .../Model/ResourceModel/Indexer/Stock/DefaultStock.php | 5 +++-- .../ResourceModel/Indexer/Stock/QueryProcessorInterface.php | 5 +++-- .../Model/ResourceModel/Indexer/Stock/StockInterface.php | 5 +++-- .../Model/ResourceModel/Indexer/StockFactory.php | 5 +++-- .../CatalogInventory/Model/ResourceModel/Stock/Status.php | 5 +++-- .../Magento/CatalogInventory/Model/Source/Backorders.php | 5 +++-- app/code/Magento/CatalogInventory/Model/Source/Stock.php | 5 +++-- 33 files changed, 99 insertions(+), 66 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php index a0f06cd406b14..9ae22e5e1a364 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php @@ -16,8 +16,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php index 2bc9b474ff298..087fae6e6568a 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php index dbb8602678d80..59a1f58b74c2c 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php @@ -16,8 +16,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php index 2daebf96c6c02..e2e8a744c4bcd 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php index 35959017606ad..1cc045745a0c1 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php index 397048cb04628..66b639fb088d1 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php index 2f2b97bf1fa93..6fd1e7466970d 100644 --- a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php @@ -13,8 +13,9 @@ /** * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface RegisterProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php index 0f441ee6268a1..552e30da89235 100644 --- a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php @@ -10,8 +10,9 @@ /** * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface RevertProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php index be815c3145607..5019e86b7af40 100644 --- a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockConfigurationInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php index d92d2931867bc..eb6fb2e812f2e 100644 --- a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php index 5a4c4b7ef52a1..18bab6571c209 100644 --- a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockIndexInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php index 5d129c199fc8a..1d2cabbb48a11 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php index 90f7d993e3607..eecf6cbe07632 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php index dcd611a148398..8796953e32fd0 100644 --- a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockManagementInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php index 7e3ee63d33aee..5478f90fb7d9f 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockRegistryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php index 2b0c40582932d..3cfdf45506340 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php index 49cc746e79d39..8be7f5be79f27 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStateInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php index f57db6b2cef0a..99ad7005d9da4 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php index 8be61afbbce11..d29171f557f05 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php index 38d3c33a9a1f8..d3c165bbde1a8 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php @@ -11,8 +11,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Minsaleqty extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php index 74e062b7e07ca..5378801b6c24b 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php @@ -15,8 +15,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock extends \Magento\Framework\Data\Form\Element\Select { diff --git a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php index 9551e06264c1b..a12b72cd0a971 100644 --- a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php +++ b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php @@ -15,8 +15,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Qtyincrements extends Template implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php index cb8741c88b09d..5a3a3ca6ee983 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class DefaultStockqty extends AbstractStockqty implements \Magento\Framework\DataObject\IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index eb76dd5fce057..798ac4074c188 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -19,8 +19,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock { diff --git a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php index 29f7aa61ab8b1..145b0d1454ae2 100644 --- a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php @@ -21,8 +21,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Item extends \Magento\CatalogInventory\Model\Stock\Item implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index c13a2560c6ac2..502d9532e8a05 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -26,8 +26,9 @@ * @since 100.0.2 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class QuantityValidator { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index ef43010826523..ba3b62f554767 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -19,8 +19,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class DefaultStock extends AbstractIndexer implements StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php index a24a10d7433c2..115002b237645 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.1.0 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface QueryProcessorInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php index 3f0523e8fba6c..24ed496372817 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php index fae1ee72ac34f..0ee162e429f40 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php @@ -13,8 +13,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class StockFactory { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php index 1e826ef229f13..402ce5f2f611e 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php @@ -14,8 +14,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php index b13f7e570d859..0bffb9a9888cd 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Backorders implements \Magento\Framework\Option\ArrayInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Stock.php b/app/code/Magento/CatalogInventory/Model/Source/Stock.php index 992709419fa25..7d44ab782de61 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Stock.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock extends AbstractSource { From 09c47a1b36d905c01a3084f3bd48d21923228356 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 18 Oct 2018 12:38:34 -0500 Subject: [PATCH 0657/1415] MQE-1187: Fix MFTF skipped tests - Heavy Refactor work on CreateAnAdminOrderUsingBraintreePaymentTest1, test was redefining existing action-groups for no good reason. --- .../ActionGroup/CreateNewOrderActionGroup.xml | 29 +------------ .../Test/Mftf/Data/BraintreeData.xml | 2 +- ...AnAdminOrderUsingBraintreePaymentTest1.xml | 43 +++++++++++++------ 3 files changed, 31 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/CreateNewOrderActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/CreateNewOrderActionGroup.xml index ee7158c2b63f7..17d634c009b3e 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/CreateNewOrderActionGroup.xml +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/CreateNewOrderActionGroup.xml @@ -8,28 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CreateNewOrderActionGroup"> - <click stepKey="createNewOrder" selector="{{NewOrderSection.createNewOrder}}"/> - <waitForPageLoad stepKey="waitForCustomersList" time="3"/> - <click stepKey="chooseCustomer" selector="{{NewOrderSection.customer}}"/> - <waitForPageLoad stepKey="waitForOrderPage" time="3"/> - <click stepKey="addProducts" selector="{{NewOrderSection.addProducts}}"/> - <waitForPageLoad stepKey="waitForProducts" time="3"/> - <click stepKey="chooseProducts" selector="{{NewOrderSection.chooseProduct}}"/> - <waitForPageLoad stepKey="waitForProductChoose" time="3"/> - <click stepKey="addSelectedProduct" selector="{{NewOrderSection.addSelectedProduct}}"/> - <waitForAjaxLoad stepKey="waitForChoose" time="3"/> - <click stepKey="openAddresses" selector="{{NewOrderSection.openAddresses}}"/> - <click stepKey="chooseAddress" selector="{{NewOrderSection.chooseAddress}}"/> - <fillField stepKey="fillState" selector="{{NewOrderSection.state}}" userInput="Yerevan"/> - <scrollTo stepKey="scrollTo" selector="#order-methods"/> - <waitForPageLoad stepKey="waitForMethods" time="3"/> - <click stepKey="startJSMethodExecution" selector="{{NewOrderSection.openShippingMethods}}"/> - <waitForPageLoad stepKey="waitForJSMethodExecution" time="3"/> - <click stepKey="openShippingMethods" selector="{{NewOrderSection.openShippingMethods}}"/> - <waitForPageLoad stepKey="waitForShippingMethods" time="3"/> - <click stepKey="chooseShippingMethods" selector="{{NewOrderSection.shippingMethod}}"/> - <waitForPageLoad stepKey="waitForShippingMethodChoose" time="4"/> + <actionGroup name="useBraintreeForMasterCard"> <click stepKey="chooseBraintree" selector="{{NewOrderSection.creditCardBraintree}}"/> <waitForPageLoad stepKey="waitForBraintreeConfigs" time="5"/> <click stepKey="openCardTypes" selector="{{NewOrderSection.openCardTypes}}"/> @@ -56,11 +35,5 @@ <fillField stepKey="fillCVV" selector="{{NewOrderSection.cvv}}" userInput="{{PaymentAndShippingInfo.cvv}}"/> <wait stepKey="waitForFillCVV" time="1"/> <switchToIFrame stepKey="switchBackFromCVV"/> - - <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> - <waitForPageLoad stepKey="waitForSaveConfig" time="5"/> - <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="1"/> - </actionGroup> - </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml index 8f2588a6effa5..61be90076539e 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml @@ -128,7 +128,7 @@ <data key="firstName">John</data> <data key="lastName">Smith</data> <data key="password">admin123</data> - <data key="email">mail@mail.com</data> + <data key="email" unique="prefix">mail@mail.com</data> </entity> <entity name="PaymentAndShippingInfo" type="data"> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml index df2e98816f0d3..35829071407e0 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-93677"/> <group value="braintree"/> - <skip> - <issueId value="MQE-1187" /> - </skip> </annotations> @@ -28,11 +25,13 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--CreateNewProduct--> - <actionGroup ref="CreateNewProductActionGroup" stepKey="CreateNewProduct"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> <!--Create New Customer--> - <actionGroup ref="CreateCustomerActionGroup" stepKey="CreateCustomer"/> - + <createData stepKey="createCustomer" entity="Simple_US_Customer"/> </before> @@ -48,15 +47,35 @@ <actionGroup ref="AdminCreateUserAction" stepKey="AdminCreateNewUser"/> <!--SignOut--> - <actionGroup ref="SignOut" stepKey="signOutFromAdmin"/> + <actionGroup ref="logout" stepKey="signOutFromAdmin"/> <!--SignIn New User--> <actionGroup ref="LoginNewUser" stepKey="signInNewUser"/> <waitForPageLoad stepKey="waitForLogin" time="3"/> <!--Create New Order--> - <actionGroup ref="CreateNewOrderActionGroup" stepKey="createNewOrder"/> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrder"> + <argument name="customer" value="Simple_US_Customer"/> + </actionGroup> + + <actionGroup ref="addSimpleProductToOrder" stepKey="addProduct"> + <argument name="product" value="_defaultProduct"/> + </actionGroup> + + <actionGroup ref="fillOrderCustomerInformation" stepKey="fillCustomerAddress"> + <argument name="customer" value="Simple_US_Customer"/> + <argument name="address" value="US_Address_TX"/> + </actionGroup> + + <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping"/> + + <waitForPageLoad stepKey="waitForShippingToFinish"/> + + <actionGroup ref="useBraintreeForMasterCard" stepKey="selectCardWithBraintree"/> + <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> + <waitForPageLoad stepKey="waitForSaveConfig" time="5"/> + <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="1"/> <after> <!--SignOut--> @@ -64,14 +83,10 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Delete Product--> - <actionGroup ref="DeleteProductActionGroup" stepKey="DeleteAllProducts"> - <argument name="productName" value="NewProductData.ProductName"/> - </actionGroup> + <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <!--Delete Customer--> - <actionGroup ref="DeleteCustomerActionGroup" stepKey="DeleteCustomer"> - <argument name="lastName" value="NewCustomerData.LastName"/> - </actionGroup> + <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> <!--Delete User --> <actionGroup ref="GoToAllUsers" stepKey="GoBackToAllUsers"/> From f87301a5e6b77078db23eac82efc9338ee63859d Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 13:13:21 -0500 Subject: [PATCH 0658/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php index 7e60039e86880..ee9087e082a56 100644 --- a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php +++ b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php @@ -22,6 +22,7 @@ class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase * @return void * * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter + * @magentoAppIsolation enabled */ public function testTestModuleEnabledModuleIsAbleToModifyConfig() { From e058daaa665d8b3b98b652178adb89b0ef4a7155 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 13:16:34 -0500 Subject: [PATCH 0659/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Wysiwyg/CompositeConfigProviderTest.php | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php deleted file mode 100644 index ee9087e082a56..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - - -namespace Magento\Tinymce3\Model\Wysiwyg; - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\AuthorizationInterface; - -/** - * @magentoAppArea adminhtml - */ -class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase -{ - /** - * Test enabled module is able to modify WYSIWYG config - * - * @return void - * - * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter - * @magentoAppIsolation enabled - */ - public function testTestModuleEnabledModuleIsAbleToModifyConfig() - { - $objectManager = Bootstrap::getObjectManager(); - $objectManager->configure([ - 'preferences' => [ - AuthorizationInterface::class => \Magento\Backend\Model\Search\AuthorizationMock::class - ] - ]); - $compositeConfigProvider = $objectManager->create(\Magento\Cms\Model\Wysiwyg\CompositeConfigProvider::class); - $model = $objectManager->create( - \Magento\Cms\Model\Wysiwyg\Config::class, - ['configProvider' => $compositeConfigProvider] - ); - $config = $model->getConfig(); - $this->assertArrayHasKey('add_images', $config); - $this->assertArrayHasKey('files_browser_window_url', $config); - $this->assertTrue($config['add_images']); - } -} From 4870075a69904028141b9c02b53aeacf95c1c22c Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 18 Oct 2018 13:19:46 -0500 Subject: [PATCH 0660/1415] MAGETWO-95645: Custom file attribute works incorrect - fix tests --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 6 +++--- lib/internal/Magento/Framework/Data/Form/Element/Text.php | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index 3d73ffa378232..1b2cac32598e1 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -120,8 +120,7 @@ public function extractValue(RequestInterface $request) } /** - * Validate file by attribute validate rules - * Return array of errors + * Validate file by attribute validate rules and return array of errors * * @param array $value * @return string[] @@ -180,7 +179,8 @@ public function validateValue($value) $dir = $this->_directory->getAbsolutePath($this->getAttribute()->getEntityType()->getEntityTypeCode()); $fileData = [ 'size' => filesize($dir . $value), - 'name' => $value + 'name' => $value, + 'tmp_name' => $dir . $value ]; } diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Text.php b/lib/internal/Magento/Framework/Data/Form/Element/Text.php index b7b084310ed14..2f001eb10307b 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Text.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Text.php @@ -4,15 +4,13 @@ * See COPYING.txt for license details. */ -/** - * Form text element - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Framework\Data\Form\Element; use Magento\Framework\Escaper; +/** + * Form text element + */ class Text extends AbstractElement { /** From d5e5c27b47506ebe455e672b74de20f6e93d1234 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 18 Oct 2018 13:58:32 -0500 Subject: [PATCH 0661/1415] MQE-1187: Fix MFTF skipped tests - Unskipping NewProductsListWidgetDownloadableProductTest --- .../Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml index 1a9ad271d62c7..4864d11c884bc 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml @@ -18,9 +18,6 @@ <testCaseId value="MC-124"/> <group value="Downloadable"/> <group value="WYSIWYGDisabled"/> - <skip> - <issueId value="MQE-1187"/> - </skip> </annotations> <!-- A Cms page containing the New Products Widget gets created here via extends --> From 41b1834c12f0529cc171ee5eca7d304afddc13c2 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Thu, 18 Oct 2018 14:19:26 -0500 Subject: [PATCH 0662/1415] Update Product type switching test --- .../Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml index 460cc29b183e0..8fbb64f4579b1 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml @@ -33,6 +33,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="ProductTypeSwitchingOnCreationTestVariation4"> + <data name="issue" xsi:type="string">MSI-1624</data> <data name="createProduct" xsi:type="string">configurable</data> <data name="product" xsi:type="string">catalogProductVirtual::required_fields</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> From ee7f0c6f86f701e608c4f3a61ca4a4c9a0e4f864 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Thu, 18 Oct 2018 17:14:54 -0500 Subject: [PATCH 0663/1415] MAGETWO-95636: Upload Extension Validation - Add validation to file extension before retrieving it from remote server - Clean up some code to remove cyclomatic complexity - Account for changes in unit test --- .../Model/Import/Uploader.php | 36 ++++++++++--------- .../Test/Unit/Model/Import/UploaderTest.php | 13 +++++-- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index e7ffe408cc732..cca31b97e6b6d 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -101,7 +101,7 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\Filesystem\File\ReadFactory $readFactory - * @param null $filePath + * @param string|null $filePath * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( @@ -146,20 +146,25 @@ public function init() * @param string $fileName * @param bool $renameFileOff * @return array + * + * @throws \Magento\Framework\Exception\LocalizedException */ public function move($fileName, $renameFileOff = false) { if ($renameFileOff) { $this->setAllowRenameFiles(false); } + + if ($this->getTmpDir()) { + $filePath = $this->getTmpDir() . '/'; + } else { + $filePath = ''; + } + if (preg_match('/\bhttps?:\/\//i', $fileName, $matches)) { $url = str_replace($matches[0], '', $fileName); - - if ($matches[0] === $this->httpScheme) { - $read = $this->_readFactory->create($url, DriverPool::HTTP); - } else { - $read = $this->_readFactory->create($url, DriverPool::HTTPS); - } + $driver = $matches[0] === $this->httpScheme ? DriverPool::HTTP : DriverPool::HTTPS; + $read = $this->_readFactory->create($url, $driver); //only use filename (for URI with query parameters) $parsedUrlPath = parse_url($url, PHP_URL_PATH); @@ -170,11 +175,13 @@ public function move($fileName, $renameFileOff = false) } } - if ($this->getTmpDir()) { - $filePath = $this->getTmpDir() . '/'; - } else { - $filePath = ''; + $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION); + if ($fileExtension && !$this->checkAllowedExtension($fileExtension)) { + throw new \Magento\Framework\Exception\LocalizedException( + __('File extension \'%1\' is not a supported upload type', $fileExtension) + ); } + $fileName = preg_replace('/[^a-z0-9\._-]+/i', '', $fileName); $filePath = $this->_directory->getRelativePath($filePath . $fileName); $this->_directory->writeFile( @@ -183,11 +190,6 @@ public function move($fileName, $renameFileOff = false) ); } - if ($this->getTmpDir()) { - $filePath = $this->getTmpDir() . '/'; - } else { - $filePath = ''; - } $filePath = $this->_directory->getRelativePath($filePath . $fileName); $this->_setUploadFile($filePath); $destDir = $this->_directory->getAbsolutePath($this->getDestDir()); @@ -353,7 +355,7 @@ protected function _moveFile($tmpPath, $destPath) } /** - * {@inheritdoc} + * @inheritdoc */ protected function chmod($file) { diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php index 262593377aa2c..f734596de014b 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php @@ -93,14 +93,14 @@ protected function setUp() $this->filesystem, $this->readFactory, ]) - ->setMethods(['_setUploadFile', 'save', 'getTmpDir']) + ->setMethods(['_setUploadFile', 'save', 'getTmpDir', 'checkAllowedExtension']) ->getMock(); } /** * @dataProvider moveFileUrlDataProvider */ - public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName) + public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName, $checkAllowedExtension) { $destDir = 'var/dest/dir'; $expectedRelativeFilePath = $expectedFileName; @@ -128,6 +128,9 @@ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName) $this->uploader->expects($this->once())->method('_setUploadFile')->will($this->returnSelf()); $this->uploader->expects($this->once())->method('save')->with($destDir . '/' . $expectedFileName) ->willReturn(['name' => $expectedFileName, 'path' => 'absPath']); + $this->uploader->expects($this->exactly($checkAllowedExtension)) + ->method('checkAllowedExtension') + ->willReturn(true); $this->uploader->setDestDir($destDir); $result = $this->uploader->move($fileUrl); @@ -224,31 +227,37 @@ public function moveFileUrlDataProvider() '$fileUrl' => 'http://test_uploader_file', '$expectedHost' => 'test_uploader_file', '$expectedFileName' => 'test_uploader_file', + '$checkAllowedExtension' => 0 ], [ '$fileUrl' => 'https://!:^&`;file', '$expectedHost' => '!:^&`;file', '$expectedFileName' => 'file', + '$checkAllowedExtension' => 0 ], [ '$fileUrl' => 'https://www.google.com/image.jpg', '$expectedHost' => 'www.google.com/image.jpg', '$expectedFileName' => 'image.jpg', + '$checkAllowedExtension' => 1 ], [ '$fileUrl' => 'https://www.google.com/image.jpg?param=1', '$expectedHost' => 'www.google.com/image.jpg?param=1', '$expectedFileName' => 'image.jpg', + '$checkAllowedExtension' => 1 ], [ '$fileUrl' => 'https://www.google.com/image.jpg?param=1¶m=2', '$expectedHost' => 'www.google.com/image.jpg?param=1¶m=2', '$expectedFileName' => 'image.jpg', + '$checkAllowedExtension' => 1 ], [ '$fileUrl' => 'http://www.google.com/image.jpg?param=1¶m=2', '$expectedHost' => 'www.google.com/image.jpg?param=1¶m=2', '$expectedFileName' => 'image.jpg', + '$checkAllowedExtension' => 1 ], ]; } From 2e426e872ace021a6fcc86a523b297ae713fe5fd Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 19 Oct 2018 09:48:08 +0300 Subject: [PATCH 0664/1415] MAGETWO-92182: JS Templates Limitations --- .../Checkout/view/frontend/web/js/view/form/element/email.js | 3 +++ app/code/Magento/Ui/view/base/web/js/form/element/abstract.js | 3 +++ app/code/Magento/Ui/view/base/web/js/grid/editing/record.js | 3 +++ 3 files changed, 9 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 4a25778e754c7..9e18d4fca6dab 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -33,6 +33,9 @@ define([ listens: { email: 'emailHasChanged', emailFocused: 'validateEmail' + }, + ignoreTmpls: { + email: true } }, checkDelay: 2000, diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 8f1a75d2be0d4..3b98d2c93c7a9 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -57,6 +57,9 @@ define([ '${ $.provider }:${ $.customScope ? $.customScope + "." : ""}data.validate': 'validate', 'isUseDefault': 'toggleUseDefault' }, + ignoreTmpls: { + value: true + }, links: { value: '${ $.provider }:${ $.dataScope }' diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js index 18b3836113141..390aedf193b91 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js @@ -50,6 +50,9 @@ define([ } } }, + ignoreTmpls: { + data: true + }, listens: { elems: 'updateFields', data: 'updateState' From c83a1caa6b1eb7182f235310938c22cfea7826f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 19 Oct 2018 11:58:59 +0300 Subject: [PATCH 0665/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 1b0fe4c85f617..7478fa2226454 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -206,7 +206,7 @@ <label>Images Upload Configuration</label> <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> - <validate>validate-greater-than-zero validate-digits validate-range required-entry digits-range-1-100</validate> + <validate>validate-digits validate-digits-range digits-range-1-100 required-entry</validate> <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> From 8433083f3c6a0c33500d7ad1ce7ead82c59a9cfe Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 11:55:18 +0200 Subject: [PATCH 0666/1415] Restructure estimate-service.js --- .../web/js/model/cart/estimate-service.js | 101 ++++++++++-------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index 76e3d911e7d3f..f1da0ed7916e7 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -14,55 +14,70 @@ define([ 'use strict'; var rateProcessors = [], - totalsProcessors = []; + totalsProcessors = [], - quote.shippingAddress.subscribe(function () { - var type = quote.shippingAddress().getType(); + /** + * Estimate totals for shipping address and update shipping rates. + */ + estimateTotalsAndUpdateRates = function() { + var type = quote.shippingAddress().getType(); - if ( - quote.isVirtual() || - window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0 - ) { - // update totals block when estimated address was set - totalsProcessors['default'] = totalsDefaultProvider; - totalsProcessors[type] ? - totalsProcessors[type].estimateTotals(quote.shippingAddress()) : - totalsProcessors['default'].estimateTotals(quote.shippingAddress()); - } else { - // check if user data not changed -> load rates from cache - if (!cartCache.isChanged('address', quote.shippingAddress()) && - !cartCache.isChanged('cartVersion', customerData.get('cart')()['data_id']) && - cartCache.get('rates') + if ( + quote.isVirtual() || + window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0 ) { - shippingService.setShippingRates(cartCache.get('rates')); + // update totals block when estimated address was set + totalsProcessors['default'] = totalsDefaultProvider; + totalsProcessors[type] ? + totalsProcessors[type].estimateTotals(quote.shippingAddress()) : + totalsProcessors['default'].estimateTotals(quote.shippingAddress()); + } else { + // check if user data not changed -> load rates from cache + if (!cartCache.isChanged('address', quote.shippingAddress()) && + !cartCache.isChanged('cartVersion', customerData.get('cart')()['data_id']) && + cartCache.get('rates') + ) { + shippingService.setShippingRates(cartCache.get('rates')); - return; + return; + } + + // update rates list when estimated address was set + rateProcessors['default'] = defaultProcessor; + rateProcessors[type] ? + rateProcessors[type].getRates(quote.shippingAddress()) : + rateProcessors['default'].getRates(quote.shippingAddress()); + + // save rates to cache after load + shippingService.getShippingRates().subscribe(function (rates) { + cartCache.set('rates', rates); + }); } + }, - // update rates list when estimated address was set - rateProcessors['default'] = defaultProcessor; - rateProcessors[type] ? - rateProcessors[type].getRates(quote.shippingAddress()) : - rateProcessors['default'].getRates(quote.shippingAddress()); + /** + * Estimate totals for shipping address. + */ + estimateTotalsShipping = function() { + totalsDefaultProvider.estimateTotals(quote.shippingAddress()); + }, - // save rates to cache after load - shippingService.getShippingRates().subscribe(function (rates) { - cartCache.set('rates', rates); - }); - } - }); - quote.shippingMethod.subscribe(function () { - totalsDefaultProvider.estimateTotals(quote.shippingAddress()); - }); - quote.billingAddress.subscribe(function () { - var type = quote.billingAddress().getType(); + /** + * Estimate totals for billing address. + */ + estimateTotalsBilling = function() { + var type = quote.billingAddress().getType(); + + if (quote.isVirtual()) { + // update totals block when estimated address was set + totalsProcessors['default'] = totalsDefaultProvider; + totalsProcessors[type] ? + totalsProcessors[type].estimateTotals(quote.billingAddress()) : + totalsProcessors['default'].estimateTotals(quote.billingAddress()); + } + }; - if (quote.isVirtual()) { - // update totals block when estimated address was set - totalsProcessors['default'] = totalsDefaultProvider; - totalsProcessors[type] ? - totalsProcessors[type].estimateTotals(quote.billingAddress()) : - totalsProcessors['default'].estimateTotals(quote.billingAddress()); - } - }); + quote.shippingAddress.subscribe(estimateTotalsAndUpdateRates); + quote.shippingMethod.subscribe(estimateTotalsShipping); + quote.billingAddress.subscribe(estimateTotalsBilling); }); From 4fd6a03fe5367032b30c0c828246756d8f1db24c Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 11:55:55 +0200 Subject: [PATCH 0667/1415] Estimate totals when cart data changes --- .../Checkout/view/frontend/web/js/model/cart/estimate-service.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index f1da0ed7916e7..f85a1385e0815 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -80,4 +80,5 @@ define([ quote.shippingAddress.subscribe(estimateTotalsAndUpdateRates); quote.shippingMethod.subscribe(estimateTotalsShipping); quote.billingAddress.subscribe(estimateTotalsBilling); + customerData.get('cart').subscribe(estimateTotalsShipping); }); From 031d8ec39d2350054b6aa2f0cabe338c0b35bb00 Mon Sep 17 00:00:00 2001 From: Graham Wharton <graham@gwharton.me.uk> Date: Fri, 19 Oct 2018 11:39:21 +0100 Subject: [PATCH 0668/1415] Forwardport of MAGETWO-93818: Magnifier function does not disappear after mouse-off the image from the bottom Added onMouseLeave events --- lib/web/magnifier/magnifier.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index 150c8adf0b22b..b48ffa6f50b18 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -554,6 +554,15 @@ thumbObj.src = thumb.src; } + /** + * Hide magnifier when mouse exceeds image bounds. + */ + function onMouseLeave() { + onThumbLeave(); + isOverThumb = false; + $magnifierPreview.addClass(MagnifyCls.magnifyHidden); + } + function onMousemove(e) { pos.x = e.clientX; pos.y = e.clientY; @@ -564,15 +573,9 @@ isOverThumb = inBounds; } - if (inBounds && isOverThumb) { - if(gMode === 'outside'){ - $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); - } + if (inBounds && isOverThumb && gMode === 'outside') { + $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); move(); - } else { - onThumbLeave(); - isOverThumb = false; - $magnifierPreview.addClass(MagnifyCls.magnifyHidden); } } @@ -589,6 +592,8 @@ }); $box.on('mousemove', onMousemove); + $box.on('mouseleave', onMouseLeave); + _init($box, customUserOptions); } }(jQuery)); From 9688034346f5b322b9767ab6af5c8163e67b28ac Mon Sep 17 00:00:00 2001 From: Jakub Idziak <j.idziak@macopedia.pl> Date: Thu, 18 Oct 2018 16:13:36 +0200 Subject: [PATCH 0669/1415] ISSUE-5021 - fixed place order for custom shipping methods with underscore in carrier code --- .../Magento/Checkout/Model/PaymentInformationManagement.php | 5 ++--- .../Test/Unit/Model/PaymentInformationManagementTest.php | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 164109177d4e9..947f7b896f67a 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -115,9 +115,8 @@ public function savePaymentInformation( $quote->setDataChanges(true); $shippingAddress = $quote->getShippingAddress(); if ($shippingAddress && $shippingAddress->getShippingMethod()) { - $shippingDataArray = explode('_', $shippingAddress->getShippingMethod()); - $shippingCarrier = array_shift($shippingDataArray); - $shippingAddress->setLimitCarrier($shippingCarrier); + $shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod()); + $shippingAddress->setLimitCarrier($shippingRate->getCarrier()); } } $this->paymentMethodManagement->set($cartId, $paymentMethod); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php index 77c15fccfa8ae..ea841e86586ba 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php @@ -172,9 +172,11 @@ private function getMockForAssignBillingAddress($cartId, $billingAddressMock) $billingAddressId = 1; $quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); $quoteBillingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $shippingRate = $this->createPartialMock(\Magento\Quote\Model\Quote\Address\Rate::class, []); + $shippingRate->setCarrier('flatrate'); $quoteShippingAddress = $this->createPartialMock( \Magento\Quote\Model\Quote\Address::class, - ['setLimitCarrier', 'getShippingMethod'] + ['setLimitCarrier', 'getShippingMethod', 'getShippingRateByCode'] ); $this->cartRepositoryMock->expects($this->any())->method('getActive')->with($cartId)->willReturn($quoteMock); $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($quoteBillingAddress); @@ -183,6 +185,7 @@ private function getMockForAssignBillingAddress($cartId, $billingAddressMock) $quoteMock->expects($this->once())->method('removeAddress')->with($billingAddressId); $quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddressMock); $quoteMock->expects($this->once())->method('setDataChanges')->willReturnSelf(); + $quoteShippingAddress->expects($this->any())->method('getShippingRateByCode')->willReturn($shippingRate); $quoteShippingAddress->expects($this->any())->method('getShippingMethod')->willReturn('flatrate_flatrate'); $quoteShippingAddress->expects($this->once())->method('setLimitCarrier')->with('flatrate')->willReturnSelf(); } From 6c1d07e06eb442a4108db0fe3007f95da2c409e2 Mon Sep 17 00:00:00 2001 From: Henryk Tews <h.tews@macopedia.pl> Date: Fri, 19 Oct 2018 13:14:10 +0200 Subject: [PATCH 0670/1415] Changed get product way in blocks with related products --- .../Magento/Catalog/Block/Product/ProductList/Crosssell.php | 2 +- app/code/Magento/Catalog/Block/Product/ProductList/Related.php | 2 +- app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php index 0c547f81c85d6..043704a9f2bca 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php @@ -25,7 +25,7 @@ class Crosssell extends \Magento\Catalog\Block\Product\AbstractProduct */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getCrossSellProductCollection()->addAttributeToSelect( diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 219922f9e46d5..91e4161ce53b1 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -81,7 +81,7 @@ public function __construct( */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect( diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index 0d64ecc9bff90..ef38693a5454c 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -95,7 +95,7 @@ public function __construct( */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getUpSellProductCollection()->setPositionOrder()->addStoreFilter(); if ($this->moduleManager->isEnabled('Magento_Checkout')) { From 4b76ffdc54c19f0fe642761540120744b8d0fc43 Mon Sep 17 00:00:00 2001 From: Graham Wharton <graham@gwharton.me.uk> Date: Fri, 19 Oct 2018 12:17:36 +0100 Subject: [PATCH 0671/1415] Fixed whitespace issue --- lib/web/magnifier/magnifier.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index b48ffa6f50b18..0807a4c394995 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -593,7 +593,7 @@ $box.on('mousemove', onMousemove); $box.on('mouseleave', onMouseLeave); - + _init($box, customUserOptions); } }(jQuery)); From 7584f715e27ec3fb6d7dcf6511999f27466e35ae Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 19 Oct 2018 08:01:01 -0400 Subject: [PATCH 0672/1415] Allow set billing information via API with existing address Not setting the customerId with an existing address caused a `NoSuchEntityException` to be thrown during address validation https://github.com/magento/magento2/blob/56af1e73ce21867b770a7458ab6e109f4a1eface/app/code/Magento/Quote/Model/QuoteAddressValidator.php#L84 Fixes #17485 --- app/code/Magento/Quote/Model/BillingAddressManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index 70a8c94fefad0..e8af185b8c2f0 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -77,6 +77,7 @@ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $addres { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); + $address->setCustomerId($quote->getCustomerId()); $quote->removeAddress($quote->getBillingAddress()->getId()); $quote->setBillingAddress($address); try { From 9a249e97c4a645f513a1f0aaaeed5957689c8e7f Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 14:02:15 +0200 Subject: [PATCH 0673/1415] Fix js static error --- .../view/frontend/web/js/model/cart/estimate-service.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index f85a1385e0815..54e496131972e 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -19,7 +19,7 @@ define([ /** * Estimate totals for shipping address and update shipping rates. */ - estimateTotalsAndUpdateRates = function() { + estimateTotalsAndUpdateRates = function () { var type = quote.shippingAddress().getType(); if ( @@ -58,14 +58,14 @@ define([ /** * Estimate totals for shipping address. */ - estimateTotalsShipping = function() { + estimateTotalsShipping = function () { totalsDefaultProvider.estimateTotals(quote.shippingAddress()); }, /** * Estimate totals for billing address. */ - estimateTotalsBilling = function() { + estimateTotalsBilling = function () { var type = quote.billingAddress().getType(); if (quote.isVirtual()) { From c3e4b0414e703d04934584792daf948d844305ba Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 14:16:39 +0200 Subject: [PATCH 0674/1415] Add test for cart data mutations/estimation call --- .../Checkout/frontend/js/model/cart/estimate-service.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 3d8325a3ecd54..31009555bd9f9 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -150,5 +150,10 @@ define([ }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); + + it('test subscribe when cart data was changed', function () { + mocks['Magento_Customer/js/customer-data'].get('cart')({ data_id: 2 }); + expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); + }); }); }); From c60761e9b7a4bb4b18c18929446f1c78f8a65a93 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Fri, 19 Oct 2018 15:42:04 +0300 Subject: [PATCH 0675/1415] MAGETWO-95539: [2.3] Moving Category generate duplicate url_rewrite when 4th level category exist and is translated - Fixed url rewrites regeneration after category moving --- .../CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php index 8a70af213c612..fcdc21bedc5f8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php @@ -64,15 +64,19 @@ public function afterChangeParent( Category $newParent, $afterCategoryId ) { + + $categoryStoreId = $category->getStoreId(); foreach ($category->getStoreIds() as $storeId) { $category->setStoreId($storeId); if (!$this->isGlobalScope($storeId)) { $this->updateCategoryUrlKeyForStore($category); + $category->unsUrlPath(); $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); $category->getResource()->saveAttribute($category, 'url_path'); $this->updateUrlPathForChildren($category); } } + $category->setStoreId($categoryStoreId); return $result; } From 0afc6c64ccb4af80b658c8c266a9f573e30ae8d5 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 08:59:39 -0500 Subject: [PATCH 0676/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../AdminNotification/etc/db_schema.xml | 10 +- .../Magento/AdvancedSearch/etc/db_schema.xml | 6 +- .../AsynchronousOperations/etc/db_schema.xml | 18 +- .../Magento/Authorization/etc/db_schema.xml | 14 +- app/code/Magento/Bundle/etc/db_schema.xml | 56 +- app/code/Magento/Captcha/etc/db_schema.xml | 2 +- app/code/Magento/Catalog/etc/db_schema.xml | 532 +++++++++--------- .../CatalogInventory/etc/db_schema.xml | 44 +- .../Magento/CatalogRule/etc/db_schema.xml | 80 +-- .../CatalogUrlRewrite/etc/db_schema.xml | 8 +- .../CheckoutAgreements/etc/db_schema.xml | 8 +- app/code/Magento/Cms/etc/db_schema.xml | 26 +- app/code/Magento/Config/etc/db_schema.xml | 4 +- .../ConfigurableProduct/etc/db_schema.xml | 26 +- app/code/Magento/Cron/etc/db_schema.xml | 6 +- app/code/Magento/Customer/etc/db_schema.xml | 168 +++--- app/code/Magento/Directory/etc/db_schema.xml | 20 +- .../Magento/Downloadable/etc/db_schema.xml | 70 +-- app/code/Magento/Eav/etc/db_schema.xml | 212 +++---- app/code/Magento/Email/etc/db_schema.xml | 8 +- .../Magento/GiftMessage/etc/db_schema.xml | 2 +- .../Magento/GoogleOptimizer/etc/db_schema.xml | 6 +- .../Magento/ImportExport/etc/db_schema.xml | 4 +- app/code/Magento/Indexer/etc/db_schema.xml | 10 +- .../Magento/Integration/etc/db_schema.xml | 40 +- .../Magento/MessageQueue/etc/db_schema.xml | 4 +- app/code/Magento/MysqlMq/etc/db_schema.xml | 16 +- .../NewRelicReporting/etc/db_schema.xml | 10 +- app/code/Magento/Newsletter/etc/db_schema.xml | 52 +- .../Magento/OfflineShipping/etc/db_schema.xml | 4 +- app/code/Magento/Paypal/etc/db_schema.xml | 38 +- app/code/Magento/Persistent/etc/db_schema.xml | 12 +- .../Magento/ProductAlert/etc/db_schema.xml | 28 +- .../Magento/ProductVideo/etc/db_schema.xml | 6 +- app/code/Magento/Quote/etc/db_schema.xml | 70 +-- .../ReleaseNotification/etc/db_schema.xml | 6 +- app/code/Magento/Reports/etc/db_schema.xml | 90 +-- app/code/Magento/Review/etc/db_schema.xml | 96 ++-- app/code/Magento/Sales/etc/db_schema.xml | 426 +++++++------- app/code/Magento/SalesRule/etc/db_schema.xml | 104 ++-- .../Magento/SalesSequence/etc/db_schema.xml | 10 +- app/code/Magento/Search/etc/db_schema.xml | 24 +- app/code/Magento/Security/etc/db_schema.xml | 14 +- app/code/Magento/SendFriend/etc/db_schema.xml | 6 +- app/code/Magento/Signifyd/etc/db_schema.xml | 8 +- app/code/Magento/Sitemap/etc/db_schema.xml | 6 +- app/code/Magento/Store/etc/db_schema.xml | 32 +- app/code/Magento/Swatches/etc/db_schema.xml | 10 +- app/code/Magento/Tax/etc/db_schema.xml | 60 +- app/code/Magento/Theme/etc/db_schema.xml | 12 +- .../Magento/Translation/etc/db_schema.xml | 6 +- app/code/Magento/Ui/etc/db_schema.xml | 6 +- app/code/Magento/UrlRewrite/etc/db_schema.xml | 8 +- app/code/Magento/User/etc/db_schema.xml | 10 +- app/code/Magento/Variable/etc/db_schema.xml | 14 +- app/code/Magento/Vault/etc/db_schema.xml | 14 +- app/code/Magento/Weee/etc/db_schema.xml | 18 +- app/code/Magento/Widget/etc/db_schema.xml | 38 +- app/code/Magento/Wishlist/etc/db_schema.xml | 26 +- app/etc/db_schema.xml | 2 +- app/etc/di.xml | 21 + .../Declaration/Schema/Config/Converter.php | 51 +- .../Schema/Config/SchemaLocator.php | 60 -- .../Schema/Declaration/SchemaBuilder.php | 62 +- .../Schema/FileSystem/XmlReader.php | 63 --- .../Schema/etc/constraints/constraint.xsd | 2 +- .../Setup/Declaration/Schema/etc/index.xsd | 2 +- .../Setup/Declaration/Schema/etc/name.xsd | 14 + .../Setup/Declaration/Schema/etc/schema.xsd | 2 +- 69 files changed, 1441 insertions(+), 1502 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php delete mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php diff --git a/app/code/Magento/AdminNotification/etc/db_schema.xml b/app/code/Magento/AdminNotification/etc/db_schema.xml index 35e6045b607d1..29d928ced2084 100644 --- a/app/code/Magento/AdminNotification/etc/db_schema.xml +++ b/app/code/Magento/AdminNotification/etc/db_schema.xml @@ -21,16 +21,16 @@ default="0" comment="Flag if notification read"/> <column xsi:type="smallint" name="is_remove" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Flag if notification might be removed"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="notification_id"/> </constraint> - <index name="ADMINNOTIFICATION_INBOX_SEVERITY" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_SEVERITY" indexType="btree"> <column name="severity"/> </index> - <index name="ADMINNOTIFICATION_INBOX_IS_READ" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_IS_READ" indexType="btree"> <column name="is_read"/> </index> - <index name="ADMINNOTIFICATION_INBOX_IS_REMOVE" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_IS_REMOVE" indexType="btree"> <column name="is_remove"/> </index> </table> @@ -40,7 +40,7 @@ default="0" comment="Problem type"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Create date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="identity"/> </constraint> </table> diff --git a/app/code/Magento/AdvancedSearch/etc/db_schema.xml b/app/code/Magento/AdvancedSearch/etc/db_schema.xml index 9fae40411098c..2dd8c68e2d5fd 100644 --- a/app/code/Magento/AdvancedSearch/etc/db_schema.xml +++ b/app/code/Magento/AdvancedSearch/etc/db_schema.xml @@ -14,13 +14,13 @@ default="0" comment="Query Id"/> <column xsi:type="int" name="relation_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Relation Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGSEARCH_RECOMMENDATIONS_QUERY_ID_SEARCH_QUERY_QUERY_ID" + <constraint xsi:type="foreign" referenceId="CATALOGSEARCH_RECOMMENDATIONS_QUERY_ID_SEARCH_QUERY_QUERY_ID" table="catalogsearch_recommendations" column="query_id" referenceTable="search_query" referenceColumn="query_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOGSEARCH_RECOMMENDATIONS_RELATION_ID_SEARCH_QUERY_QUERY_ID" + <constraint xsi:type="foreign" referenceId="CATALOGSEARCH_RECOMMENDATIONS_RELATION_ID_SEARCH_QUERY_QUERY_ID" table="catalogsearch_recommendations" column="relation_id" referenceTable="search_query" referenceColumn="query_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 342326e6666f1..5cd55408838fe 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -21,13 +21,13 @@ comment="Total number of operations scheduled within this bulk"/> <column xsi:type="timestamp" name="start_time" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Bulk start time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="MAGENTO_BULK_UUID"> + <constraint xsi:type="unique" referenceId="MAGENTO_BULK_UUID"> <column name="uuid"/> </constraint> - <index name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> + <index referenceId="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> @@ -47,12 +47,12 @@ comment="Code of the error that appeared during operation execution (used to aggregate related failed operations)"/> <column xsi:type="varchar" name="result_message" nullable="true" length="255" comment="Operation result message"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID" table="magento_operation" + <constraint xsi:type="foreign" referenceId="MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID" table="magento_operation" column="bulk_uuid" referenceTable="magento_bulk" referenceColumn="uuid" onDelete="CASCADE"/> - <index name="MAGENTO_OPERATION_BULK_UUID_ERROR_CODE" indexType="btree"> + <index referenceId="MAGENTO_OPERATION_BULK_UUID_ERROR_CODE" indexType="btree"> <column name="bulk_uuid"/> <column name="error_code"/> </index> @@ -62,13 +62,13 @@ <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Internal ID"/> <column xsi:type="varbinary" name="bulk_uuid" nullable="true" length="39" comment="Related Bulk UUID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID" + <constraint xsi:type="foreign" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID" table="magento_acknowledged_bulk" column="bulk_uuid" referenceTable="magento_bulk" referenceColumn="uuid" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID"> + <constraint xsi:type="unique" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID"> <column name="bulk_uuid"/> </constraint> </table> diff --git a/app/code/Magento/Authorization/etc/db_schema.xml b/app/code/Magento/Authorization/etc/db_schema.xml index 45c02128bfc99..a38828eb6efca 100644 --- a/app/code/Magento/Authorization/etc/db_schema.xml +++ b/app/code/Magento/Authorization/etc/db_schema.xml @@ -21,14 +21,14 @@ comment="User ID"/> <column xsi:type="varchar" name="user_type" nullable="true" length="16" comment="User Type"/> <column xsi:type="varchar" name="role_name" nullable="true" length="50" comment="Role Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="role_id"/> </constraint> - <index name="AUTHORIZATION_ROLE_PARENT_ID_SORT_ORDER" indexType="btree"> + <index referenceId="AUTHORIZATION_ROLE_PARENT_ID_SORT_ORDER" indexType="btree"> <column name="parent_id"/> <column name="sort_order"/> </index> - <index name="AUTHORIZATION_ROLE_TREE_LEVEL" indexType="btree"> + <index referenceId="AUTHORIZATION_ROLE_TREE_LEVEL" indexType="btree"> <column name="tree_level"/> </index> </table> @@ -40,17 +40,17 @@ <column xsi:type="varchar" name="resource_id" nullable="true" length="255" comment="Resource ID"/> <column xsi:type="varchar" name="privileges" nullable="true" length="20" comment="Privileges"/> <column xsi:type="varchar" name="permission" nullable="true" length="10" comment="Permission"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <constraint xsi:type="foreign" name="AUTHORIZATION_RULE_ROLE_ID_AUTHORIZATION_ROLE_ROLE_ID" + <constraint xsi:type="foreign" referenceId="AUTHORIZATION_RULE_ROLE_ID_AUTHORIZATION_ROLE_ROLE_ID" table="authorization_rule" column="role_id" referenceTable="authorization_role" referenceColumn="role_id" onDelete="CASCADE"/> - <index name="AUTHORIZATION_RULE_RESOURCE_ID_ROLE_ID" indexType="btree"> + <index referenceId="AUTHORIZATION_RULE_RESOURCE_ID_ROLE_ID" indexType="btree"> <column name="resource_id"/> <column name="role_id"/> </index> - <index name="AUTHORIZATION_RULE_ROLE_ID_RESOURCE_ID" indexType="btree"> + <index referenceId="AUTHORIZATION_RULE_ROLE_ID_RESOURCE_ID" indexType="btree"> <column name="role_id"/> <column name="resource_id"/> </index> diff --git a/app/code/Magento/Bundle/etc/db_schema.xml b/app/code/Magento/Bundle/etc/db_schema.xml index 8092f34c533fa..6ff779518d34c 100644 --- a/app/code/Magento/Bundle/etc/db_schema.xml +++ b/app/code/Magento/Bundle/etc/db_schema.xml @@ -18,13 +18,13 @@ <column xsi:type="int" name="position" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Position"/> <column xsi:type="varchar" name="type" nullable="true" length="255" comment="Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_OPT_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_OPT_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_option" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_OPTION_PARENT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_OPTION_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -39,13 +39,13 @@ <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> <column xsi:type="int" name="parent_product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent Product Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" table="catalog_product_bundle_option_value" column="option_id" referenceTable="catalog_product_bundle_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_BNDL_OPT_VAL_OPT_ID_PARENT_PRD_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_BNDL_OPT_VAL_OPT_ID_PARENT_PRD_ID_STORE_ID"> <column name="option_id"/> <column name="parent_product_id"/> <column name="store_id"/> @@ -73,19 +73,19 @@ comment="Selection Qty"/> <column xsi:type="smallint" name="selection_can_change_qty" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Selection Can Change Qty"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="selection_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" table="catalog_product_bundle_selection" column="option_id" referenceTable="catalog_product_bundle_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_selection" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_OPTION_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -101,19 +101,19 @@ nullable="false" default="0" comment="Selection Price Value"/> <column xsi:type="int" name="parent_product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent Product Id"/> - <constraint xsi:type="primary" name="PK_CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE"> + <constraint xsi:type="primary" referenceId="PK_CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE"> <column name="selection_id"/> <column name="parent_product_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_bundle_selection_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_DCF37523AA05D770A70AA4ED7C2616E4" + <constraint xsi:type="foreign" referenceId="FK_DCF37523AA05D770A70AA4ED7C2616E4" table="catalog_product_bundle_selection_price" column="selection_id" referenceTable="catalog_product_bundle_selection" referenceColumn="selection_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -129,24 +129,24 @@ comment="Min Price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" comment="Max Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="website_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_bundle_price_index" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_price_index" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_WS_ID_STORE_WS_WS_ID" table="catalog_product_bundle_price_index" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> @@ -162,7 +162,7 @@ default="0" comment="Option Id"/> <column xsi:type="smallint" name="stock_status" padding="6" unsigned="false" nullable="true" identity="false" default="0" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="website_id"/> <column name="stock_id"/> @@ -197,7 +197,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -231,7 +231,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -257,7 +257,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -285,7 +285,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -313,7 +313,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="alt_tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Alt Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -340,7 +340,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="alt_tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Alt Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> diff --git a/app/code/Magento/Captcha/etc/db_schema.xml b/app/code/Magento/Captcha/etc/db_schema.xml index fa9a14abb8963..b8987363569ca 100644 --- a/app/code/Magento/Captcha/etc/db_schema.xml +++ b/app/code/Magento/Captcha/etc/db_schema.xml @@ -13,7 +13,7 @@ <column xsi:type="int" name="count" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Count"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type"/> <column name="value"/> </constraint> diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 7b4e1a96adda0..07378f6a27fec 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -22,13 +22,13 @@ comment="Creation Time"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID" indexType="btree"> <column name="attribute_set_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_SKU" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_SKU" indexType="btree"> <column name="sku"/> </index> </table> @@ -43,27 +43,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -79,27 +79,27 @@ default="0"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DEC_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DEC_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_decimal" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -115,27 +115,27 @@ default="0"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="true" identity="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_INT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_INT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_int" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_INT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -150,27 +150,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TEXT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TEXT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_text" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -185,27 +185,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_varchar" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -222,30 +222,30 @@ <column xsi:type="int" name="position" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Position"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_gallery" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_GLR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_GLR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_gallery" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_gallery" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -267,13 +267,13 @@ comment="Tree Level"/> <column xsi:type="int" name="children_count" padding="11" unsigned="false" nullable="false" identity="false" comment="Child Count"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_LEVEL" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_LEVEL" indexType="btree"> <column name="level"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_PATH" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_PATH" indexType="btree"> <column name="path"/> </index> </table> @@ -288,30 +288,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DTIME_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DTIME_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_datetime" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -327,30 +327,30 @@ default="0"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DEC_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DEC_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_decimal" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -366,30 +366,30 @@ default="0"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="true" identity="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_INT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_INT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_int" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_INT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -404,30 +404,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_TEXT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_TEXT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_text" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -442,30 +442,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_VCHR_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_VCHR_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_varchar" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -479,22 +479,22 @@ default="0" comment="Product ID"/> <column xsi:type="int" name="position" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Position"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="category_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_PRD_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_category_product" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_PRD_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_category_product" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_PRD_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_PRD_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_product" column="category_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_PRODUCT_CATEGORY_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_PRODUCT_CATEGORY_ID_PRODUCT_ID"> <column name="category_id"/> <column name="product_id"/> </constraint> - <index name="CATALOG_CATEGORY_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -512,18 +512,18 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> <column name="product_id"/> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> </index> - <index name="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> @@ -542,29 +542,29 @@ default="0" comment="Product ID"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="catalog_compare_item_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="catalog_compare_item" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="catalog_compare_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_STORE_ID_STORE_STORE_ID" table="catalog_compare_item" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_STORE_ID_STORE_STORE_ID" table="catalog_compare_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="CATALOG_COMPARE_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_VISITOR_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_VISITOR_ID_PRODUCT_ID" indexType="btree"> <column name="visitor_id"/> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_CUSTOMER_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_CUSTOMER_ID_PRODUCT_ID" indexType="btree"> <column name="customer_id"/> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -574,17 +574,17 @@ comment="Product ID"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="catalog_product_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_WS_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_website" + <constraint xsi:type="foreign" referenceId="CAT_PRD_WS_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_website" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -593,7 +593,7 @@ <column xsi:type="smallint" name="link_type_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Link Type ID"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_type_id"/> </constraint> </table> @@ -607,27 +607,27 @@ default="0" comment="Linked Product ID"/> <column xsi:type="smallint" name="link_type_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Link Type ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_LNKED_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_link" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_LNKED_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_link" column="linked_product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="catalog_product_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" table="catalog_product_link" column="link_type_id" referenceTable="catalog_product_link_type" referenceColumn="link_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_LINK_LINK_TYPE_ID_PRODUCT_ID_LINKED_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_LINK_LINK_TYPE_ID_PRODUCT_ID_LINKED_PRODUCT_ID"> <column name="link_type_id"/> <column name="product_id"/> <column name="linked_product_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="CATALOG_PRODUCT_LINK_LINKED_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_LINKED_PRODUCT_ID" indexType="btree"> <column name="linked_product_id"/> </index> </table> @@ -640,13 +640,13 @@ <column xsi:type="varchar" name="product_link_attribute_code" nullable="true" length="32" comment="Product Link Attribute Code"/> <column xsi:type="varchar" name="data_type" nullable="true" length="32" comment="Data Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_link_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" table="catalog_product_link_attribute" column="link_type_id" referenceTable="catalog_product_link_type" referenceColumn="link_type_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_LINK_TYPE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_LINK_TYPE_ID" indexType="btree"> <column name="link_type_id"/> </index> </table> @@ -660,21 +660,21 @@ comment="Link ID"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_DEC_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_DEC_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_decimal" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_AB2EFA9A14F7BCF1D5400056203D14B6" + <constraint xsi:type="foreign" referenceId="FK_AB2EFA9A14F7BCF1D5400056203D14B6" table="catalog_product_link_attribute_decimal" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_DEC_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_DEC_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_DECIMAL_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_DECIMAL_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -688,21 +688,21 @@ comment="Link ID"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_INT_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_INT_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_int" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_D6D878F8BA2A4282F8DDED7E6E3DE35C" + <constraint xsi:type="foreign" referenceId="FK_D6D878F8BA2A4282F8DDED7E6E3DE35C" table="catalog_product_link_attribute_int" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_INT_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_INT_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_INT_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_INT_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -715,21 +715,21 @@ <column xsi:type="int" name="link_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Link ID"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_VCHR_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_VCHR_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_varchar" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_DEE9C4DA61CFCC01DFCF50F0D79CEA51" + <constraint xsi:type="foreign" referenceId="FK_DEE9C4DA61CFCC01DFCF50F0D79CEA51" table="catalog_product_link_attribute_varchar" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_VCHR_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_VCHR_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_VARCHAR_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_VARCHAR_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -751,29 +751,29 @@ comment="Website ID"/> <column xsi:type="decimal" name="percentage_value" scale="2" precision="5" unsigned="false" nullable="true" comment="Percentage value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_entity_tier_price" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_tier_price" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_entity_tier_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_E8AB433B9ACB00343ABB312AD2FAB087"> + <constraint xsi:type="unique" referenceId="UNQ_E8AB433B9ACB00343ABB312AD2FAB087"> <column name="entity_id"/> <column name="all_groups"/> <column name="customer_group_id"/> <column name="qty"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_TIER_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TIER_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -788,13 +788,13 @@ comment="Media entry type"/> <column xsi:type="smallint" name="disabled" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Visibility status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_media_gallery" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -813,26 +813,26 @@ default="0" comment="Is Disabled"/> <column xsi:type="int" name="record_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Record Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="record_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_VAL_ID_CAT_PRD_ENTT_MDA_GLR_VAL_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VAL_ID_CAT_PRD_ENTT_MDA_GLR_VAL_ID" table="catalog_product_entity_media_gallery_value" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_media_gallery_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_media_gallery_value" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> </table> @@ -854,13 +854,13 @@ comment="Image Size Y"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_option" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_option" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_OPTION_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -875,20 +875,20 @@ <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> <column xsi:type="varchar" name="price_type" nullable="false" length="7" default="fixed" comment="Price Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_price_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_PRICE_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_PRICE_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_price" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_price" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_PRICE_OPTION_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_PRICE_OPTION_ID_STORE_ID"> <column name="option_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -901,20 +901,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_title_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_TTL_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_TTL_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_title" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TITLE_OPTION_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TITLE_OPTION_ID_STORE_ID"> <column name="option_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -927,13 +927,13 @@ <column xsi:type="varchar" name="sku" nullable="true" length="64" comment="SKU"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_TYPE_VAL_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_TYPE_VAL_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_type_value" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_OPTION_TYPE_VALUE_OPTION_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_VALUE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> </table> @@ -948,21 +948,21 @@ <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> <column xsi:type="varchar" name="price_type" nullable="false" length="7" default="fixed" comment="Price Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_price_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_B523E3378E8602F376CC415825576B7F" + <constraint xsi:type="foreign" referenceId="FK_B523E3378E8602F376CC415825576B7F" table="catalog_product_option_type_price" column="option_type_id" referenceTable="catalog_product_option_type_value" referenceColumn="option_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_type_price" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_OPTION_TYPE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_OPTION_TYPE_ID_STORE_ID"> <column name="option_type_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -975,21 +975,21 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_title_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_C085B9CF2C2A302E8043FDEA1937D6A2" + <constraint xsi:type="foreign" referenceId="FK_C085B9CF2C2A302E8043FDEA1937D6A2" table="catalog_product_option_type_title" column="option_type_id" referenceTable="catalog_product_option_type_value" referenceColumn="option_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_type_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_OPTION_TYPE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_OPTION_TYPE_ID_STORE_ID"> <column name="option_type_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1037,16 +1037,16 @@ identity="false" default="0" comment="Is Visible in Grid"/> <column xsi:type="smallint" name="is_filterable_in_grid" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is Filterable in Grid"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="catalog_eav_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CATALOG_EAV_ATTRIBUTE_USED_FOR_SORT_BY" indexType="btree"> + <index referenceId="CATALOG_EAV_ATTRIBUTE_USED_FOR_SORT_BY" indexType="btree"> <column name="used_for_sort_by"/> </index> - <index name="CATALOG_EAV_ATTRIBUTE_USED_IN_PRODUCT_LISTING" indexType="btree"> + <index referenceId="CATALOG_EAV_ATTRIBUTE_USED_IN_PRODUCT_LISTING" indexType="btree"> <column name="used_in_product_listing"/> </index> </table> @@ -1055,17 +1055,17 @@ comment="Parent ID"/> <column xsi:type="int" name="child_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Child ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_RELATION_CHILD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_RELATION_CHILD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_relation" column="child_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_RELATION_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_RELATION_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_relation" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_RELATION_CHILD_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_RELATION_CHILD_ID" indexType="btree"> <column name="child_id"/> </index> </table> @@ -1081,20 +1081,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1110,20 +1110,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1147,18 +1147,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> - <index name="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> + <index referenceId="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> <column name="website_id"/> <column name="customer_group_id"/> <column name="min_price"/> @@ -1174,24 +1174,24 @@ comment="Website ID"/> <column xsi:type="decimal" name="min_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Min Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_index_tier_price" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_index_tier_price" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_tier_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_INDEX_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_TIER_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_TIER_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -1203,12 +1203,12 @@ comment="Default store id for website"/> <column xsi:type="date" name="website_date" comment="Website Date"/> <column xsi:type="float" name="rate" unsigned="false" nullable="true" default="1" comment="Rate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_WS_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_website" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_WS_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_INDEX_WEBSITE_WEBSITE_DATE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_WEBSITE_WEBSITE_DATE" indexType="btree"> <column name="website_date"/> </index> </table> @@ -1226,7 +1226,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> <column name="customer_group_id"/> @@ -1247,7 +1247,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> <column name="customer_group_id"/> @@ -1268,7 +1268,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1288,7 +1288,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1316,7 +1316,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1344,7 +1344,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1364,7 +1364,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1384,7 +1384,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1406,7 +1406,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1429,7 +1429,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1448,20 +1448,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1477,20 +1477,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> <column name="value"/> </index> </table> @@ -1506,20 +1506,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1535,20 +1535,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> <column name="value"/> </index> </table> @@ -1572,18 +1572,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> </table> @@ -1607,18 +1607,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> <column name="min_price"/> </index> </table> @@ -1636,12 +1636,12 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> + <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> <column name="product_id"/> <column name="category_id"/> <column name="store_id"/> @@ -1652,14 +1652,14 @@ <column xsi:type="int" name="value_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Value media Entry ID"/> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false"/> - <constraint xsi:type="foreign" name="FK_A6C6C8FAA386736921D3A7C4B50B1185" + <constraint xsi:type="foreign" referenceId="FK_A6C6C8FAA386736921D3A7C4B50B1185" table="catalog_product_entity_media_gallery_value_to_entity" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_media_gallery_value_to_entity" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_VAL_ID_ENTT_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_VAL_ID_ENTT_ID"> <column name="value_id"/> <column name="entity_id"/> </constraint> @@ -1676,20 +1676,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1705,20 +1705,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1742,18 +1742,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> - <index name="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> + <index referenceId="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> <column name="website_id"/> <column name="customer_group_id"/> <column name="min_price"/> @@ -1773,18 +1773,18 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> <column name="product_id"/> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> </index> - <index name="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> @@ -1805,21 +1805,21 @@ comment="Product Id"/> <column xsi:type="bigint" name="added_at" padding="20" unsigned="false" nullable="false" identity="false" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="action_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID" table="catalog_product_frontend_action" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_frontend_action" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE" /> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID"> <column name="visitor_id"/> <column name="product_id"/> <column name="type_id"/> </constraint> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID"> <column name="customer_id"/> <column name="product_id"/> <column name="type_id"/> diff --git a/app/code/Magento/CatalogInventory/etc/db_schema.xml b/app/code/Magento/CatalogInventory/etc/db_schema.xml index 8a6ae8d2d93c6..5ac7fedc5aa18 100644 --- a/app/code/Magento/CatalogInventory/etc/db_schema.xml +++ b/app/code/Magento/CatalogInventory/etc/db_schema.xml @@ -13,10 +13,10 @@ <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> <column xsi:type="varchar" name="stock_name" nullable="true" length="255" comment="Stock Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -71,23 +71,23 @@ identity="false" default="0" comment="Is Divided into Multiple Boxes for Shipping"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="cataloginventory_stock_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATINV_STOCK_ITEM_STOCK_ID_CATINV_STOCK_STOCK_ID" + <constraint xsi:type="foreign" referenceId="CATINV_STOCK_ITEM_STOCK_ID_CATINV_STOCK_STOCK_ID" table="cataloginventory_stock_item" column="stock_id" referenceTable="cataloginventory_stock" referenceColumn="stock_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID"> + <constraint xsi:type="unique" referenceId="CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID"> <column name="product_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_ITEM_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_ITEM_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_ITEM_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_ITEM_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> </table> @@ -103,18 +103,18 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> <column name="stock_status"/> </index> </table> @@ -130,15 +130,15 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_IDX_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_IDX_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_IDX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_IDX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -154,15 +154,15 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> <column name="website_id"/> </index> </table> @@ -178,18 +178,18 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> <column name="stock_status"/> </index> </table> diff --git a/app/code/Magento/CatalogRule/etc/db_schema.xml b/app/code/Magento/CatalogRule/etc/db_schema.xml index f4c40a6930cc0..0ad71089bed5f 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema.xml +++ b/app/code/Magento/CatalogRule/etc/db_schema.xml @@ -25,10 +25,10 @@ <column xsi:type="varchar" name="simple_action" nullable="true" length="32" comment="Simple Action"/> <column xsi:type="decimal" name="discount_amount" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Discount Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <index name="CATALOGRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> + <index referenceId="CATALOGRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> <column name="to_date"/> @@ -57,10 +57,10 @@ default="0" comment="Sort Order"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_id"/> </constraint> - <constraint xsi:type="unique" name="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> + <constraint xsi:type="unique" referenceId="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> <column name="rule_id"/> <column name="from_time"/> <column name="to_time"/> @@ -69,19 +69,19 @@ <column name="product_id"/> <column name="sort_order"/> </constraint> - <index name="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> <column name="from_time"/> </index> - <index name="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> <column name="to_time"/> </index> - <index name="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -98,22 +98,22 @@ comment="Website Id"/> <column xsi:type="date" name="latest_start_date" comment="Latest StartDate"/> <column xsi:type="date" name="earliest_end_date" comment="Earliest EndDate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_price_id"/> </constraint> - <constraint xsi:type="unique" name="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> <column name="rule_date"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="product_id"/> </constraint> - <index name="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -124,15 +124,15 @@ default="0" comment="Customer Group Id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -140,17 +140,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGRULE_WEBSITE_RULE_ID_CATALOGRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_WEBSITE_RULE_ID_CATALOGRULE_RULE_ID" table="catalogrule_website" column="rule_id" referenceTable="catalogrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOGRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="catalogrule_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOGRULE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -159,17 +159,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="int" name="customer_group_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Customer Group Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGRULE_CUSTOMER_GROUP_RULE_ID_CATALOGRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_CUSTOMER_GROUP_RULE_ID_CATALOGRULE_RULE_ID" table="catalogrule_customer_group" column="rule_id" referenceTable="catalogrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CATRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalogrule_customer_group" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <index name="CATALOGRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> @@ -195,10 +195,10 @@ default="0" comment="Sort Order"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_id"/> </constraint> - <constraint xsi:type="unique" name="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> + <constraint xsi:type="unique" referenceId="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> <column name="rule_id"/> <column name="from_time"/> <column name="to_time"/> @@ -207,19 +207,19 @@ <column name="product_id"/> <column name="sort_order"/> </constraint> - <index name="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> <column name="from_time"/> </index> - <index name="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> <column name="to_time"/> </index> - <index name="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -237,22 +237,22 @@ comment="Website Id"/> <column xsi:type="date" name="latest_start_date" comment="Latest StartDate"/> <column xsi:type="date" name="earliest_end_date" comment="Earliest EndDate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_price_id"/> </constraint> - <constraint xsi:type="unique" name="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> <column name="rule_date"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="product_id"/> </constraint> - <index name="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -264,15 +264,15 @@ default="0" comment="Customer Group Id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml b/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml index 174173fa2019f..c8da5b59cf5f5 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml @@ -15,16 +15,16 @@ comment="category_id"/> <column xsi:type="int" name="product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="product_id"/> - <constraint xsi:type="foreign" name="CAT_URL_REWRITE_PRD_CTGR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_URL_REWRITE_PRD_CTGR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_url_rewrite_product_category" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_BB79E64705D7F17FE181F23144528FC8" + <constraint xsi:type="foreign" referenceId="FK_BB79E64705D7F17FE181F23144528FC8" table="catalog_url_rewrite_product_category" column="url_rewrite_id" referenceTable="url_rewrite" referenceColumn="url_rewrite_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_URL_REWRITE_PRD_CTGR_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_URL_REWRITE_PRD_CTGR_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_url_rewrite_product_category" column="category_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_URL_REWRITE_PRODUCT_CATEGORY_CATEGORY_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_URL_REWRITE_PRODUCT_CATEGORY_CATEGORY_ID_PRODUCT_ID" indexType="btree"> <column name="category_id"/> <column name="product_id"/> </index> diff --git a/app/code/Magento/CheckoutAgreements/etc/db_schema.xml b/app/code/Magento/CheckoutAgreements/etc/db_schema.xml index 31b3111df98eb..09cd1c5b63965 100644 --- a/app/code/Magento/CheckoutAgreements/etc/db_schema.xml +++ b/app/code/Magento/CheckoutAgreements/etc/db_schema.xml @@ -20,7 +20,7 @@ default="0" comment="Is Html"/> <column xsi:type="smallint" name="mode" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Applied mode"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> </constraint> </table> @@ -29,14 +29,14 @@ comment="Agreement Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CHKT_AGRT_STORE_AGRT_ID_CHKT_AGRT_AGRT_ID" table="checkout_agreement_store" + <constraint xsi:type="foreign" referenceId="CHKT_AGRT_STORE_AGRT_ID_CHKT_AGRT_AGRT_ID" table="checkout_agreement_store" column="agreement_id" referenceTable="checkout_agreement" referenceColumn="agreement_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CHECKOUT_AGREEMENT_STORE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CHECKOUT_AGREEMENT_STORE_STORE_ID_STORE_STORE_ID" table="checkout_agreement_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/Cms/etc/db_schema.xml b/app/code/Magento/Cms/etc/db_schema.xml index 2b825544f56f1..3075601215fe3 100644 --- a/app/code/Magento/Cms/etc/db_schema.xml +++ b/app/code/Magento/Cms/etc/db_schema.xml @@ -19,10 +19,10 @@ comment="Block Modification Time"/> <column xsi:type="smallint" name="is_active" padding="6" unsigned="false" nullable="false" identity="false" default="1" comment="Is Block Active"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="block_id"/> </constraint> - <index name="CMS_BLOCK_TITLE_IDENTIFIER_CONTENT" indexType="fulltext"> + <index referenceId="CMS_BLOCK_TITLE_IDENTIFIER_CONTENT" indexType="fulltext"> <column name="title"/> <column name="identifier"/> <column name="content"/> @@ -32,15 +32,15 @@ <column xsi:type="smallint" name="block_id" padding="6" unsigned="false" nullable="false" identity="false"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="block_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CMS_BLOCK_STORE_BLOCK_ID_CMS_BLOCK_BLOCK_ID" table="cms_block_store" + <constraint xsi:type="foreign" referenceId="CMS_BLOCK_STORE_BLOCK_ID_CMS_BLOCK_BLOCK_ID" table="cms_block_store" column="block_id" referenceTable="cms_block" referenceColumn="block_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CMS_BLOCK_STORE_STORE_ID_STORE_STORE_ID" table="cms_block_store" + <constraint xsi:type="foreign" referenceId="CMS_BLOCK_STORE_STORE_ID_STORE_STORE_ID" table="cms_block_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="CMS_BLOCK_STORE_STORE_ID" indexType="btree"> + <index referenceId="CMS_BLOCK_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -71,13 +71,13 @@ <column xsi:type="date" name="custom_theme_from" comment="Page Custom Theme Active From Date"/> <column xsi:type="date" name="custom_theme_to" comment="Page Custom Theme Active To Date"/> <column xsi:type="varchar" name="meta_title" nullable="true" length="255" comment="Page Meta Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> - <index name="CMS_PAGE_IDENTIFIER" indexType="btree"> + <index referenceId="CMS_PAGE_IDENTIFIER" indexType="btree"> <column name="identifier"/> </index> - <index name="CMS_PAGE_TITLE_META_KEYWORDS_META_DESCRIPTION_IDENTIFIER_CONTENT" indexType="fulltext"> + <index referenceId="CMS_PAGE_TITLE_META_KEYWORDS_META_DESCRIPTION_IDENTIFIER_CONTENT" indexType="fulltext"> <column name="title"/> <column name="meta_keywords"/> <column name="meta_description"/> @@ -89,15 +89,15 @@ <column xsi:type="smallint" name="page_id" padding="6" unsigned="false" nullable="false" identity="false"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CMS_PAGE_STORE_PAGE_ID_CMS_PAGE_PAGE_ID" table="cms_page_store" + <constraint xsi:type="foreign" referenceId="CMS_PAGE_STORE_PAGE_ID_CMS_PAGE_PAGE_ID" table="cms_page_store" column="page_id" referenceTable="cms_page" referenceColumn="page_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CMS_PAGE_STORE_STORE_ID_STORE_STORE_ID" table="cms_page_store" + <constraint xsi:type="foreign" referenceId="CMS_PAGE_STORE_STORE_ID_STORE_STORE_ID" table="cms_page_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="CMS_PAGE_STORE_STORE_ID" indexType="btree"> + <index referenceId="CMS_PAGE_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Config/etc/db_schema.xml b/app/code/Magento/Config/etc/db_schema.xml index 3f55d582776ce..8aeac802fbd91 100644 --- a/app/code/Magento/Config/etc/db_schema.xml +++ b/app/code/Magento/Config/etc/db_schema.xml @@ -15,10 +15,10 @@ default="0" comment="Config Scope Id"/> <column xsi:type="varchar" name="path" nullable="false" length="255" default="general" comment="Config Path"/> <column xsi:type="text" name="value" nullable="true" comment="Config Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="config_id"/> </constraint> - <constraint xsi:type="unique" name="CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH"> + <constraint xsi:type="unique" referenceId="CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH"> <column name="scope"/> <column name="scope_id"/> <column name="path"/> diff --git a/app/code/Magento/ConfigurableProduct/etc/db_schema.xml b/app/code/Magento/ConfigurableProduct/etc/db_schema.xml index 7c6661a5f399a..d6917e8c1845a 100644 --- a/app/code/Magento/ConfigurableProduct/etc/db_schema.xml +++ b/app/code/Magento/ConfigurableProduct/etc/db_schema.xml @@ -17,13 +17,13 @@ default="0" comment="Attribute ID"/> <column xsi:type="smallint" name="position" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Position"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_super_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_ATTR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_ATTR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_attribute" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_PRODUCT_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_PRODUCT_ID_ATTRIBUTE_ID"> <column name="product_id"/> <column name="attribute_id"/> </constraint> @@ -39,21 +39,21 @@ <column xsi:type="smallint" name="use_default" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Use Default Value"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_309442281DF7784210ED82B2CC51E5D5" + <constraint xsi:type="foreign" referenceId="FK_309442281DF7784210ED82B2CC51E5D5" table="catalog_product_super_attribute_label" column="product_super_attribute_id" referenceTable="catalog_product_super_attribute" referenceColumn="product_super_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="catalog_product_super_attribute_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_SPR_ATTR_LBL_PRD_SPR_ATTR_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_SPR_ATTR_LBL_PRD_SPR_ATTR_ID_STORE_ID"> <column name="product_super_attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -65,20 +65,20 @@ default="0" comment="Product ID"/> <column xsi:type="int" name="parent_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Parent ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_LNK_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_LNK_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_LNK_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_LNK_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_link" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_SUPER_LINK_PRODUCT_ID_PARENT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_SUPER_LINK_PRODUCT_ID_PARENT_ID"> <column name="product_id"/> <column name="parent_id"/> </constraint> - <index name="CATALOG_PRODUCT_SUPER_LINK_PARENT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_SUPER_LINK_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> diff --git a/app/code/Magento/Cron/etc/db_schema.xml b/app/code/Magento/Cron/etc/db_schema.xml index deff05d3eec96..b3061eefa6313 100644 --- a/app/code/Magento/Cron/etc/db_schema.xml +++ b/app/code/Magento/Cron/etc/db_schema.xml @@ -18,13 +18,13 @@ <column xsi:type="timestamp" name="scheduled_at" on_update="false" nullable="true" comment="Scheduled At"/> <column xsi:type="timestamp" name="executed_at" on_update="false" nullable="true" comment="Executed At"/> <column xsi:type="timestamp" name="finished_at" on_update="false" nullable="true" comment="Finished At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="schedule_id"/> </constraint> - <index name="CRON_SCHEDULE_JOB_CODE" indexType="btree"> + <index referenceId="CRON_SCHEDULE_JOB_CODE" indexType="btree"> <column name="job_code"/> </index> - <index name="CRON_SCHEDULE_SCHEDULED_AT_STATUS" indexType="btree"> + <index referenceId="CRON_SCHEDULE_SCHEDULED_AT_STATUS" indexType="btree"> <column name="scheduled_at"/> <column name="status"/> </index> diff --git a/app/code/Magento/Customer/etc/db_schema.xml b/app/code/Magento/Customer/etc/db_schema.xml index 368ca417432fd..b3c15799011a2 100644 --- a/app/code/Magento/Customer/etc/db_schema.xml +++ b/app/code/Magento/Customer/etc/db_schema.xml @@ -50,28 +50,28 @@ <column xsi:type="timestamp" name="first_failure" on_update="false" nullable="true" comment="First Failure"/> <column xsi:type="timestamp" name="lock_expires" on_update="false" nullable="true" comment="Lock Expiration Date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_STORE_ID_STORE_STORE_ID" table="customer_entity" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_STORE_ID_STORE_STORE_ID" table="customer_entity" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="customer_entity" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_EMAIL_WEBSITE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_EMAIL_WEBSITE_ID"> <column name="email"/> <column name="website_id"/> </constraint> - <index name="CUSTOMER_ENTITY_STORE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CUSTOMER_ENTITY_WEBSITE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CUSTOMER_ENTITY_FIRSTNAME" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_FIRSTNAME" indexType="btree"> <column name="firstname"/> </index> - <index name="CUSTOMER_ENTITY_LASTNAME" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_LASTNAME" indexType="btree"> <column name="lastname"/> </index> </table> @@ -111,13 +111,13 @@ comment="VAT number validation request ID"/> <column xsi:type="int" name="vat_request_success" padding="10" unsigned="true" nullable="true" identity="false" comment="VAT number validation request success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ADDRESS_ENTITY_PARENT_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ADDRESS_ENTITY_PARENT_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_address_entity" column="parent_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CUSTOMER_ADDRESS_ENTITY_PARENT_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -130,23 +130,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DTIME_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DTIME_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_datetime" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -162,23 +162,23 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DEC_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DEC_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_decimal" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -193,23 +193,23 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_INT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_INT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_int" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -224,20 +224,20 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_TEXT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_TEXT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_text" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -250,23 +250,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_VCHR_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_VCHR_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_varchar" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -280,23 +280,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_datetime" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -311,23 +311,23 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_decimal" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -342,23 +342,23 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_INT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_int" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -372,20 +372,20 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_TEXT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_TEXT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_text" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -397,23 +397,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_varchar" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -425,7 +425,7 @@ comment="Customer Group Code"/> <column xsi:type="int" name="tax_class_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Tax Class Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="customer_group_id"/> </constraint> </table> @@ -451,10 +451,10 @@ identity="false" default="0" comment="Is Filterable in Grid"/> <column xsi:type="smallint" name="is_searchable_in_grid" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is Searchable in Grid"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_eav_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> </table> @@ -462,14 +462,14 @@ <column xsi:type="varchar" name="form_code" nullable="false" length="32" comment="Form Code"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="form_code"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_form_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -486,17 +486,17 @@ <column xsi:type="text" name="default_value" nullable="true" comment="Default Value"/> <column xsi:type="smallint" name="multiline_count" padding="5" unsigned="true" nullable="true" identity="false" comment="Multiline Count"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_EAV_ATTR_WS_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EAV_ATTR_WS_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_eav_attribute_website" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_EAV_ATTR_WS_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EAV_ATTR_WS_WS_ID_STORE_WS_WS_ID" table="customer_eav_attribute_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CUSTOMER_EAV_ATTRIBUTE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CUSTOMER_EAV_ATTRIBUTE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -508,13 +508,13 @@ <column xsi:type="varchar" name="session_id" nullable="true" length="64" comment="Session ID"/> <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" comment="Last Visit Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="visitor_id"/> </constraint> - <index name="CUSTOMER_VISITOR_CUSTOMER_ID" indexType="btree"> + <index referenceId="CUSTOMER_VISITOR_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="CUSTOMER_VISITOR_LAST_VISIT_AT" indexType="btree"> + <index referenceId="CUSTOMER_VISITOR_LAST_VISIT_AT" indexType="btree"> <column name="last_visit_at"/> </index> </table> @@ -526,10 +526,10 @@ <column xsi:type="timestamp" name="last_login_at" on_update="false" nullable="true" comment="Last Login Time"/> <column xsi:type="timestamp" name="last_logout_at" on_update="false" nullable="true" comment="Last Logout Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <constraint xsi:type="unique" name="CUSTOMER_LOG_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_LOG_CUSTOMER_ID"> <column name="customer_id"/> </constraint> </table> diff --git a/app/code/Magento/Directory/etc/db_schema.xml b/app/code/Magento/Directory/etc/db_schema.xml index 72fd929b98a07..c11e0ee525e37 100644 --- a/app/code/Magento/Directory/etc/db_schema.xml +++ b/app/code/Magento/Directory/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="varchar" name="country_id" nullable="false" length="2" comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="iso2_code" nullable="true" length="2" comment="Country ISO-2 format"/> <column xsi:type="varchar" name="iso3_code" nullable="true" length="3" comment="Country ISO-3"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="country_id"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="varchar" name="country_id" nullable="true" length="2" comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="type" nullable="true" length="30" comment="Country Format Type"/> <column xsi:type="text" name="format" nullable="false" comment="Country Format"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="country_format_id"/> </constraint> - <constraint xsi:type="unique" name="DIRECTORY_COUNTRY_FORMAT_COUNTRY_ID_TYPE"> + <constraint xsi:type="unique" referenceId="DIRECTORY_COUNTRY_FORMAT_COUNTRY_ID_TYPE"> <column name="country_id"/> <column name="type"/> </constraint> @@ -36,10 +36,10 @@ comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Region code"/> <column xsi:type="varchar" name="default_name" nullable="true" length="255" comment="Region Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="region_id"/> </constraint> - <index name="DIRECTORY_COUNTRY_REGION_COUNTRY_ID" indexType="btree"> + <index referenceId="DIRECTORY_COUNTRY_REGION_COUNTRY_ID" indexType="btree"> <column name="country_id"/> </index> </table> @@ -49,14 +49,14 @@ <column xsi:type="int" name="region_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Region Id"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Region Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="locale"/> <column name="region_id"/> </constraint> - <constraint xsi:type="foreign" name="DIR_COUNTRY_REGION_NAME_REGION_ID_DIR_COUNTRY_REGION_REGION_ID" + <constraint xsi:type="foreign" referenceId="DIR_COUNTRY_REGION_NAME_REGION_ID_DIR_COUNTRY_REGION_REGION_ID" table="directory_country_region_name" column="region_id" referenceTable="directory_country_region" referenceColumn="region_id" onDelete="CASCADE"/> - <index name="DIRECTORY_COUNTRY_REGION_NAME_REGION_ID" indexType="btree"> + <index referenceId="DIRECTORY_COUNTRY_REGION_NAME_REGION_ID" indexType="btree"> <column name="region_id"/> </index> </table> @@ -66,11 +66,11 @@ <column xsi:type="varchar" name="currency_to" nullable="false" length="3" comment="Currency Code Convert To"/> <column xsi:type="decimal" name="rate" scale="12" precision="24" unsigned="false" nullable="false" default="0" comment="Currency Conversion Rate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="currency_from"/> <column name="currency_to"/> </constraint> - <index name="DIRECTORY_CURRENCY_RATE_CURRENCY_TO" indexType="btree"> + <index referenceId="DIRECTORY_CURRENCY_RATE_CURRENCY_TO" indexType="btree"> <column name="currency_to"/> </index> </table> diff --git a/app/code/Magento/Downloadable/etc/db_schema.xml b/app/code/Magento/Downloadable/etc/db_schema.xml index ed25628bcffd9..89d47644661a5 100644 --- a/app/code/Magento/Downloadable/etc/db_schema.xml +++ b/app/code/Magento/Downloadable/etc/db_schema.xml @@ -24,13 +24,13 @@ <column xsi:type="varchar" name="sample_url" nullable="true" length="255" comment="Sample Url"/> <column xsi:type="varchar" name="sample_file" nullable="true" length="255" comment="Sample File"/> <column xsi:type="varchar" name="sample_type" nullable="true" length="20" comment="Sample Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="downloadable_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_LINK_PRODUCT_ID_SORT_ORDER" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRODUCT_ID_SORT_ORDER" indexType="btree"> <column name="product_id"/> <column name="sort_order"/> </index> @@ -44,19 +44,19 @@ default="0" comment="Website ID"/> <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="price_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRICE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRICE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" table="downloadable_link_price" column="link_id" referenceTable="downloadable_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="downloadable_link_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_LINK_PRICE_LINK_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRICE_LINK_ID" indexType="btree"> <column name="link_id"/> </index> - <index name="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -78,22 +78,22 @@ <column xsi:type="varchar" name="product_name" nullable="true" length="255" comment="Product name"/> <column xsi:type="varchar" name="product_sku" nullable="true" length="255" comment="Product sku"/> <column xsi:type="varchar" name="link_section_title" nullable="true" length="255" comment="Link_section_title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="purchased_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_CSTR_ID_CSTR_ENTT_ENTT_ID" table="downloadable_link_purchased" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID_SALES_ORDER_ENTITY_ID" table="downloadable_link_purchased" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="SET NULL"/> - <index name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ITEM_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ITEM_ID" indexType="btree"> <column name="order_item_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_CUSTOMER_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -125,22 +125,22 @@ comment="Creation Time"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_ITEM_PURCHASED_ID_DL_LNK_PURCHASED_PURCHASED_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_ITEM_PURCHASED_ID_DL_LNK_PURCHASED_PURCHASED_ID" table="downloadable_link_purchased_item" column="purchased_id" referenceTable="downloadable_link_purchased" referenceColumn="purchased_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_ITEM_ORDER_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_ITEM_ORDER_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="downloadable_link_purchased_item" column="order_item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="SET NULL"/> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_LINK_HASH" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_LINK_HASH" indexType="btree"> <column name="link_hash"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_ORDER_ITEM_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_ORDER_ITEM_ID" indexType="btree"> <column name="order_item_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_PURCHASED_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_PURCHASED_ID" indexType="btree"> <column name="purchased_id"/> </index> </table> @@ -152,20 +152,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="title_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_TITLE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_TITLE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" table="downloadable_link_title" column="link_id" referenceTable="downloadable_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_TITLE_STORE_ID_STORE_STORE_ID" table="downloadable_link_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="DOWNLOADABLE_LINK_TITLE_LINK_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="DOWNLOADABLE_LINK_TITLE_LINK_ID_STORE_ID"> <column name="link_id"/> <column name="store_id"/> </constraint> - <index name="DOWNLOADABLE_LINK_TITLE_STORE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -179,13 +179,13 @@ <column xsi:type="varchar" name="sample_type" nullable="true" length="20" comment="Sample Type"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="sample_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_SAMPLE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_SAMPLE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="downloadable_sample" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_SAMPLE_PRODUCT_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_SAMPLE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -198,20 +198,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="title_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_SAMPLE_TTL_SAMPLE_ID_DL_SAMPLE_SAMPLE_ID" + <constraint xsi:type="foreign" referenceId="DL_SAMPLE_TTL_SAMPLE_ID_DL_SAMPLE_SAMPLE_ID" table="downloadable_sample_title" column="sample_id" referenceTable="downloadable_sample" referenceColumn="sample_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID_STORE_STORE_ID" table="downloadable_sample_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="DOWNLOADABLE_SAMPLE_TITLE_SAMPLE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="DOWNLOADABLE_SAMPLE_TITLE_SAMPLE_ID_STORE_ID"> <column name="sample_id"/> <column name="store_id"/> </constraint> - <index name="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -227,7 +227,7 @@ default="0" comment="Minimum price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Maximum price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -245,7 +245,7 @@ default="0" comment="Minimum price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Maximum price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index f930321e5259b..c27c3cb32c488 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -33,10 +33,10 @@ comment="Additional Attribute Table"/> <column xsi:type="varchar" name="entity_attribute_collection" nullable="true" length="255" comment="Entity Attribute Collection"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_type_id"/> </constraint> - <index name="EAV_ENTITY_TYPE_ENTITY_TYPE_CODE" indexType="btree"> + <index referenceId="EAV_ENTITY_TYPE_ENTITY_TYPE_CODE" indexType="btree"> <column name="entity_type_code"/> </index> </table> @@ -58,18 +58,18 @@ comment="Updated At"/> <column xsi:type="smallint" name="is_active" padding="5" unsigned="true" nullable="false" identity="false" default="1" comment="Defines Is Entity Active"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_ID_STORE_STORE_ID" table="eav_entity" column="store_id" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_ID_STORE_STORE_ID" table="eav_entity" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ENTITY_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -85,30 +85,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_DATETIME_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DATETIME_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_datetime" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTT_DTIME_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTT_DTIME_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" table="eav_entity_datetime" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="eav_entity_datetime" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="eav_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_DATETIME_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_DATETIME_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -126,30 +126,30 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_decimal" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_decimal" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="eav_entity_decimal" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="eav_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_DECIMAL_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -167,29 +167,29 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_int" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_int" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_int" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="eav_entity_int" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="eav_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_INT_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_INT_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -206,28 +206,28 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_text" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_text" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_text" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="eav_entity_text" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="eav_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_TEXT_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="EAV_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -243,30 +243,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_varchar" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_varchar" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="eav_entity_varchar" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="eav_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_VARCHAR_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -295,13 +295,13 @@ <column xsi:type="smallint" name="is_unique" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Defines Is Unique"/> <column xsi:type="varchar" name="note" nullable="true" length="255" comment="Note"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_attribute" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE"> <column name="entity_type_id"/> <column name="attribute_code"/> </constraint> @@ -315,18 +315,18 @@ default="0" comment="Store Id"/> <column xsi:type="varchar" name="increment_prefix" nullable="true" length="20" comment="Increment Prefix"/> <column xsi:type="varchar" name="increment_last_id" nullable="true" length="50" comment="Last Incremented Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_store_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_store" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_STORE_ID_STORE_STORE_ID" table="eav_entity_store" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_STORE_ID_STORE_STORE_ID" table="eav_entity_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ENTITY_STORE_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_STORE_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -338,17 +338,17 @@ <column xsi:type="varchar" name="attribute_set_name" nullable="true" length="255" comment="Attribute Set Name"/> <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_set_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_attribute_set" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_ATTRIBUTE_SET_NAME"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_ATTRIBUTE_SET_NAME"> <column name="entity_type_id"/> <column name="attribute_set_name"/> </constraint> - <index name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_SORT_ORDER" indexType="btree"> <column name="entity_type_id"/> <column name="sort_order"/> </index> @@ -367,21 +367,21 @@ <column xsi:type="varchar" name="attribute_group_code" nullable="false" length="255" comment="Attribute Group Code"/> <column xsi:type="varchar" name="tab_group_code" nullable="true" length="255" comment="Tab Group Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_group_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID" table="eav_attribute_group" column="attribute_set_id" referenceTable="eav_attribute_set" referenceColumn="attribute_set_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME"> <column name="attribute_set_id"/> <column name="attribute_group_name"/> </constraint> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE"> <column name="attribute_set_id"/> <column name="attribute_group_code"/> </constraint> - <index name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> <column name="attribute_set_id"/> <column name="sort_order"/> </index> @@ -399,28 +399,28 @@ default="0" comment="Attribute Id"/> <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_entity_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTT_ATTR_ATTR_GROUP_ID_EAV_ATTR_GROUP_ATTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTT_ATTR_ATTR_GROUP_ID_EAV_ATTR_GROUP_ATTR_GROUP_ID" table="eav_entity_attribute" column="attribute_group_id" referenceTable="eav_attribute_group" referenceColumn="attribute_group_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID"> <column name="attribute_set_id"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="unique" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID"> <column name="attribute_group_id"/> <column name="attribute_id"/> </constraint> - <index name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> <column name="attribute_set_id"/> <column name="sort_order"/> </index> - <index name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -431,13 +431,13 @@ default="0" comment="Attribute Id"/> <column xsi:type="smallint" name="sort_order" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_attribute_option" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -449,19 +449,19 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID" table="eav_attribute_option_value" column="option_id" referenceTable="eav_attribute_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID" table="eav_attribute_option_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_OPTION_VALUE_OPTION_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_VALUE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> - <index name="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -473,18 +473,18 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_label_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_attribute_label" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> <column name="attribute_id"/> <column name="store_id"/> </index> @@ -499,17 +499,17 @@ <column xsi:type="varchar" name="theme" nullable="true" length="64" comment="Theme"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_STORE_ID_STORE_STORE_ID" table="eav_form_type" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_STORE_ID_STORE_STORE_ID" table="eav_form_type" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_TYPE_CODE_THEME_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_FORM_TYPE_CODE_THEME_STORE_ID"> <column name="code"/> <column name="theme"/> <column name="store_id"/> </constraint> - <index name="EAV_FORM_TYPE_STORE_ID" indexType="btree"> + <index referenceId="EAV_FORM_TYPE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -518,17 +518,17 @@ comment="Type Id"/> <column xsi:type="smallint" name="entity_type_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Entity Type Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type_id"/> <column name="entity_type_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_ENTT_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_ENTT_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" table="eav_form_type_entity" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_ENTITY_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_ENTITY_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_type_entity" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <index name="EAV_FORM_TYPE_ENTITY_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_FORM_TYPE_ENTITY_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> </table> @@ -540,12 +540,12 @@ <column xsi:type="varchar" name="code" nullable="false" length="64" comment="Code"/> <column xsi:type="int" name="sort_order" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="fieldset_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_FIELDSET_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_fieldset" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FIELDSET_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_fieldset" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_FIELDSET_TYPE_ID_CODE"> + <constraint xsi:type="unique" referenceId="EAV_FORM_FIELDSET_TYPE_ID_CODE"> <column name="type_id"/> <column name="code"/> </constraint> @@ -556,17 +556,17 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="false" length="255" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="fieldset_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_FSET_LBL_FSET_ID_EAV_FORM_FSET_FSET_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FSET_LBL_FSET_ID_EAV_FORM_FSET_FSET_ID" table="eav_form_fieldset_label" column="fieldset_id" referenceTable="eav_form_fieldset" referenceColumn="fieldset_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_FIELDSET_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FIELDSET_LABEL_STORE_ID_STORE_STORE_ID" table="eav_form_fieldset_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_FORM_FIELDSET_LABEL_STORE_ID" indexType="btree"> + <index referenceId="EAV_FORM_FIELDSET_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -581,25 +581,25 @@ comment="Attribute Id"/> <column xsi:type="int" name="sort_order" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="element_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_form_element" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_FIELDSET_ID_EAV_FORM_FIELDSET_FIELDSET_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_FIELDSET_ID_EAV_FORM_FIELDSET_FIELDSET_ID" table="eav_form_element" column="fieldset_id" referenceTable="eav_form_fieldset" referenceColumn="fieldset_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_element" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_element" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID"> <column name="type_id"/> <column name="attribute_id"/> </constraint> - <index name="EAV_FORM_ELEMENT_FIELDSET_ID" indexType="btree"> + <index referenceId="EAV_FORM_ELEMENT_FIELDSET_ID" indexType="btree"> <column name="fieldset_id"/> </index> - <index name="EAV_FORM_ELEMENT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_FORM_ELEMENT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> diff --git a/app/code/Magento/Email/etc/db_schema.xml b/app/code/Magento/Email/etc/db_schema.xml index 53ef349a383ae..dbb8855e9e57e 100644 --- a/app/code/Magento/Email/etc/db_schema.xml +++ b/app/code/Magento/Email/etc/db_schema.xml @@ -27,16 +27,16 @@ <column xsi:type="varchar" name="orig_template_code" nullable="true" length="200" comment="Original Template Code"/> <column xsi:type="text" name="orig_template_variables" nullable="true" comment="Original Template Variables"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="template_id"/> </constraint> - <constraint xsi:type="unique" name="EMAIL_TEMPLATE_TEMPLATE_CODE"> + <constraint xsi:type="unique" referenceId="EMAIL_TEMPLATE_TEMPLATE_CODE"> <column name="template_code"/> </constraint> - <index name="EMAIL_TEMPLATE_ADDED_AT" indexType="btree"> + <index referenceId="EMAIL_TEMPLATE_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="EMAIL_TEMPLATE_MODIFIED_AT" indexType="btree"> + <index referenceId="EMAIL_TEMPLATE_MODIFIED_AT" indexType="btree"> <column name="modified_at"/> </index> </table> diff --git a/app/code/Magento/GiftMessage/etc/db_schema.xml b/app/code/Magento/GiftMessage/etc/db_schema.xml index 518c6398e4c8d..4ae98799df0c2 100644 --- a/app/code/Magento/GiftMessage/etc/db_schema.xml +++ b/app/code/Magento/GiftMessage/etc/db_schema.xml @@ -15,7 +15,7 @@ <column xsi:type="varchar" name="sender" nullable="true" length="255" comment="Sender"/> <column xsi:type="varchar" name="recipient" nullable="true" length="255" comment="Registrant"/> <column xsi:type="text" name="message" nullable="true" comment="Message"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="gift_message_id"/> </constraint> </table> diff --git a/app/code/Magento/GoogleOptimizer/etc/db_schema.xml b/app/code/Magento/GoogleOptimizer/etc/db_schema.xml index ad3e03e490b05..76c377544cfb3 100644 --- a/app/code/Magento/GoogleOptimizer/etc/db_schema.xml +++ b/app/code/Magento/GoogleOptimizer/etc/db_schema.xml @@ -16,12 +16,12 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store id"/> <column xsi:type="text" name="experiment_script" nullable="true" comment="Google experiment script"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="code_id"/> </constraint> - <constraint xsi:type="foreign" name="GOOGLEOPTIMIZER_CODE_STORE_ID_STORE_STORE_ID" table="googleoptimizer_code" + <constraint xsi:type="foreign" referenceId="GOOGLEOPTIMIZER_CODE_STORE_ID_STORE_STORE_ID" table="googleoptimizer_code" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="GOOGLEOPTIMIZER_CODE_STORE_ID_ENTITY_ID_ENTITY_TYPE"> + <constraint xsi:type="unique" referenceId="GOOGLEOPTIMIZER_CODE_STORE_ID_ENTITY_ID_ENTITY_TYPE"> <column name="store_id"/> <column name="entity_id"/> <column name="entity_type"/> diff --git a/app/code/Magento/ImportExport/etc/db_schema.xml b/app/code/Magento/ImportExport/etc/db_schema.xml index 01f20daabf0f9..df45131848519 100644 --- a/app/code/Magento/ImportExport/etc/db_schema.xml +++ b/app/code/Magento/ImportExport/etc/db_schema.xml @@ -12,7 +12,7 @@ <column xsi:type="varchar" name="entity" nullable="false" length="50" comment="Entity"/> <column xsi:type="varchar" name="behavior" nullable="false" length="10" default="append" comment="Behavior"/> <column xsi:type="longtext" name="data" nullable="true" comment="Data"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> @@ -27,7 +27,7 @@ <column xsi:type="varchar" name="execution_time" nullable="true" length="255" comment="Execution time"/> <column xsi:type="varchar" name="summary" nullable="true" length="255" comment="Summary"/> <column xsi:type="varchar" name="error_file" nullable="false" length="255" comment="Imported file with errors"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="history_id"/> </constraint> </table> diff --git a/app/code/Magento/Indexer/etc/db_schema.xml b/app/code/Magento/Indexer/etc/db_schema.xml index 58c447f4d262e..d7cb006a2cf45 100644 --- a/app/code/Magento/Indexer/etc/db_schema.xml +++ b/app/code/Magento/Indexer/etc/db_schema.xml @@ -15,10 +15,10 @@ comment="Indexer Status"/> <column xsi:type="datetime" name="updated" on_update="false" nullable="true" comment="Indexer Status"/> <column xsi:type="varchar" name="hash_config" nullable="false" length="32" comment="Hash of indexer config"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="state_id"/> </constraint> - <index name="INDEXER_STATE_INDEXER_ID" indexType="btree"> + <index referenceId="INDEXER_STATE_INDEXER_ID" indexType="btree"> <column name="indexer_id"/> </index> </table> @@ -31,13 +31,13 @@ <column xsi:type="datetime" name="updated" on_update="false" nullable="true" comment="View updated time"/> <column xsi:type="int" name="version_id" padding="10" unsigned="true" nullable="true" identity="false" comment="View Version Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="state_id"/> </constraint> - <index name="MVIEW_STATE_VIEW_ID" indexType="btree"> + <index referenceId="MVIEW_STATE_VIEW_ID" indexType="btree"> <column name="view_id"/> </index> - <index name="MVIEW_STATE_MODE" indexType="btree"> + <index referenceId="MVIEW_STATE_MODE" indexType="btree"> <column name="mode"/> </index> </table> diff --git a/app/code/Magento/Integration/etc/db_schema.xml b/app/code/Magento/Integration/etc/db_schema.xml index 9e81b867d36d5..c2c2cedc665fb 100644 --- a/app/code/Magento/Integration/etc/db_schema.xml +++ b/app/code/Magento/Integration/etc/db_schema.xml @@ -19,19 +19,19 @@ <column xsi:type="varchar" name="secret" nullable="false" length="32" comment="Secret code"/> <column xsi:type="text" name="callback_url" nullable="true" comment="Callback URL"/> <column xsi:type="text" name="rejected_callback_url" nullable="false" comment="Rejected callback URL"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_CONSUMER_KEY"> + <constraint xsi:type="unique" referenceId="OAUTH_CONSUMER_KEY"> <column name="key"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_CONSUMER_SECRET"> + <constraint xsi:type="unique" referenceId="OAUTH_CONSUMER_SECRET"> <column name="secret"/> </constraint> - <index name="OAUTH_CONSUMER_CREATED_AT" indexType="btree"> + <index referenceId="OAUTH_CONSUMER_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="OAUTH_CONSUMER_UPDATED_AT" indexType="btree"> + <index referenceId="OAUTH_CONSUMER_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> </table> @@ -57,21 +57,21 @@ comment="User type"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Token creation timestamp"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_ADMIN_ID_ADMIN_USER_USER_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_ADMIN_ID_ADMIN_USER_USER_ID" table="oauth_token" column="admin_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_token" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="oauth_token" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="OAUTH_TOKEN_TOKEN"> + <constraint xsi:type="unique" referenceId="OAUTH_TOKEN_TOKEN"> <column name="token"/> </constraint> - <index name="OAUTH_TOKEN_CONSUMER_ID" indexType="btree"> + <index referenceId="OAUTH_TOKEN_CONSUMER_ID" indexType="btree"> <column name="consumer_id"/> </index> </table> @@ -81,14 +81,14 @@ comment="Nonce Timestamp"/> <column xsi:type="int" name="consumer_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Consumer ID"/> - <constraint xsi:type="foreign" name="OAUTH_NONCE_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_nonce" + <constraint xsi:type="foreign" referenceId="OAUTH_NONCE_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_nonce" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="OAUTH_NONCE_NONCE_CONSUMER_ID"> + <constraint xsi:type="unique" referenceId="OAUTH_NONCE_NONCE_CONSUMER_ID"> <column name="nonce"/> <column name="consumer_id"/> </constraint> - <index name="OAUTH_NONCE_TIMESTAMP" indexType="btree"> + <index referenceId="OAUTH_NONCE_TIMESTAMP" indexType="btree"> <column name="timestamp"/> </index> </table> @@ -113,16 +113,16 @@ default="0" comment="Integration type - manual or config file"/> <column xsi:type="varchar" name="identity_link_url" nullable="true" length="255" comment="Identity linking Url"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="integration_id"/> </constraint> - <constraint xsi:type="foreign" name="INTEGRATION_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="integration" + <constraint xsi:type="foreign" referenceId="INTEGRATION_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="integration" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="INTEGRATION_NAME"> + <constraint xsi:type="unique" referenceId="INTEGRATION_NAME"> <column name="name"/> </constraint> - <constraint xsi:type="unique" name="INTEGRATION_CONSUMER_ID"> + <constraint xsi:type="unique" referenceId="INTEGRATION_CONSUMER_ID"> <column name="consumer_id"/> </constraint> </table> @@ -138,10 +138,10 @@ default="0" comment="Number of failed authentication attempts in a row"/> <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" comment="Lock expiration time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_TOKEN_REQUEST_LOG_USER_NAME_USER_TYPE"> + <constraint xsi:type="unique" referenceId="OAUTH_TOKEN_REQUEST_LOG_USER_NAME_USER_TYPE"> <column name="user_name"/> <column name="user_type"/> </constraint> diff --git a/app/code/Magento/MessageQueue/etc/db_schema.xml b/app/code/Magento/MessageQueue/etc/db_schema.xml index 9cbad4d32a889..7a20d2bd4df5d 100644 --- a/app/code/Magento/MessageQueue/etc/db_schema.xml +++ b/app/code/Magento/MessageQueue/etc/db_schema.xml @@ -14,10 +14,10 @@ <column xsi:type="varchar" name="message_code" nullable="false" length="255" default="" comment="Message Code"/> <column xsi:type="timestamp" name="created_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="QUEUE_LOCK_MESSAGE_CODE"> + <constraint xsi:type="unique" referenceId="QUEUE_LOCK_MESSAGE_CODE"> <column name="message_code"/> </constraint> </table> diff --git a/app/code/Magento/MysqlMq/etc/db_schema.xml b/app/code/Magento/MysqlMq/etc/db_schema.xml index 02757afa53fcd..3850a6749a3d6 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema.xml +++ b/app/code/Magento/MysqlMq/etc/db_schema.xml @@ -11,10 +11,10 @@ <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Queue ID"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Queue name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="QUEUE_NAME"> + <constraint xsi:type="unique" referenceId="QUEUE_NAME"> <column name="name"/> </constraint> </table> @@ -23,7 +23,7 @@ comment="Message ID"/> <column xsi:type="varchar" name="topic_name" nullable="true" length="255" comment="Message topic"/> <column xsi:type="longtext" name="body" nullable="true" comment="Message body"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> @@ -41,19 +41,19 @@ comment="Message status in particular queue"/> <column xsi:type="smallint" name="number_of_trials" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Number of trials to processed failed message processing"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID" + <constraint xsi:type="foreign" referenceId="QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID" table="queue_message_status" column="message_id" referenceTable="queue_message" referenceColumn="id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID" table="queue_message_status" + <constraint xsi:type="foreign" referenceId="QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID" table="queue_message_status" column="queue_id" referenceTable="queue" referenceColumn="id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID"> + <constraint xsi:type="unique" referenceId="QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID"> <column name="queue_id"/> <column name="message_id"/> </constraint> - <index name="QUEUE_MESSAGE_STATUS_STATUS_UPDATED_AT" indexType="btree"> + <index referenceId="QUEUE_MESSAGE_STATUS_STATUS_UPDATED_AT" indexType="btree"> <column name="status"/> <column name="updated_at"/> </index> diff --git a/app/code/Magento/NewRelicReporting/etc/db_schema.xml b/app/code/Magento/NewRelicReporting/etc/db_schema.xml index 6f9ce29436f65..ff23f3210111e 100644 --- a/app/code/Magento/NewRelicReporting/etc/db_schema.xml +++ b/app/code/Magento/NewRelicReporting/etc/db_schema.xml @@ -16,7 +16,7 @@ comment="Count Value"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -29,7 +29,7 @@ <column xsi:type="varchar" name="state" nullable="true" length="255" comment="Module State"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -44,7 +44,7 @@ comment="Line Item Count"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -55,7 +55,7 @@ <column xsi:type="varchar" name="action" nullable="true" length="255" comment="Action Performed"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -66,7 +66,7 @@ <column xsi:type="varchar" name="action" nullable="true" length="255" comment="Action Performed"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> diff --git a/app/code/Magento/Newsletter/etc/db_schema.xml b/app/code/Magento/Newsletter/etc/db_schema.xml index 5084b8b6d01e7..5cb572f41b6be 100644 --- a/app/code/Magento/Newsletter/etc/db_schema.xml +++ b/app/code/Magento/Newsletter/etc/db_schema.xml @@ -21,19 +21,19 @@ default="0" comment="Subscriber Status"/> <column xsi:type="varchar" name="subscriber_confirm_code" nullable="true" length="32" default="NULL" comment="Subscriber Confirm Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="subscriber_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_SUBSCRIBER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_SUBSCRIBER_STORE_ID_STORE_STORE_ID" table="newsletter_subscriber" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="NEWSLETTER_SUBSCRIBER_CUSTOMER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="NEWSLETTER_SUBSCRIBER_STORE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL" indexType="btree"> <column name="subscriber_email"/> </index> </table> @@ -54,16 +54,16 @@ default="1" comment="Template Actual"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="true" comment="Added At"/> <column xsi:type="timestamp" name="modified_at" on_update="false" nullable="true" comment="Modified At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="template_id"/> </constraint> - <index name="NEWSLETTER_TEMPLATE_TEMPLATE_ACTUAL" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_TEMPLATE_ACTUAL" indexType="btree"> <column name="template_actual"/> </index> - <index name="NEWSLETTER_TEMPLATE_ADDED_AT" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="NEWSLETTER_TEMPLATE_MODIFIED_AT" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_MODIFIED_AT" indexType="btree"> <column name="modified_at"/> </index> </table> @@ -86,13 +86,13 @@ <column xsi:type="timestamp" name="queue_start_at" on_update="false" nullable="true" comment="Queue Start At"/> <column xsi:type="timestamp" name="queue_finish_at" on_update="false" nullable="true" comment="Queue Finish At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_TEMPLATE_ID_NEWSLETTER_TEMPLATE_TEMPLATE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_TEMPLATE_ID_NEWSLETTER_TEMPLATE_TEMPLATE_ID" table="newsletter_queue" column="template_id" referenceTable="newsletter_template" referenceColumn="template_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_TEMPLATE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_TEMPLATE_ID" indexType="btree"> <column name="template_id"/> </index> </table> @@ -104,19 +104,19 @@ <column xsi:type="int" name="subscriber_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Subscriber Id"/> <column xsi:type="timestamp" name="letter_sent_at" on_update="false" nullable="true" comment="Letter Sent At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_link_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_queue_link" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NLTTR_QUEUE_LNK_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" + <constraint xsi:type="foreign" referenceId="NLTTR_QUEUE_LNK_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" table="newsletter_queue_link" column="subscriber_id" referenceTable="newsletter_subscriber" referenceColumn="subscriber_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_LINK_SUBSCRIBER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_LINK_SUBSCRIBER_ID" indexType="btree"> <column name="subscriber_id"/> </index> - <index name="NEWSLETTER_QUEUE_LINK_QUEUE_ID_LETTER_SENT_AT" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_LINK_QUEUE_ID_LETTER_SENT_AT" indexType="btree"> <column name="queue_id"/> <column name="letter_sent_at"/> </index> @@ -126,17 +126,17 @@ default="0" comment="Queue Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_STORE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_STORE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_queue_store_link" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID_STORE_STORE_ID" table="newsletter_queue_store_link" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -150,19 +150,19 @@ <column xsi:type="int" name="problem_error_code" padding="10" unsigned="true" nullable="true" identity="false" default="0" comment="Problem Error Code"/> <column xsi:type="varchar" name="problem_error_text" nullable="true" length="200" comment="Problem Error Text"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="problem_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_PROBLEM_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_PROBLEM_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_problem" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" + <constraint xsi:type="foreign" referenceId="NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" table="newsletter_problem" column="subscriber_id" referenceTable="newsletter_subscriber" referenceColumn="subscriber_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_PROBLEM_SUBSCRIBER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_PROBLEM_SUBSCRIBER_ID" indexType="btree"> <column name="subscriber_id"/> </index> - <index name="NEWSLETTER_PROBLEM_QUEUE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_PROBLEM_QUEUE_ID" indexType="btree"> <column name="queue_id"/> </index> </table> diff --git a/app/code/Magento/OfflineShipping/etc/db_schema.xml b/app/code/Magento/OfflineShipping/etc/db_schema.xml index 80f4b56a1723d..0510ce9b9b8eb 100644 --- a/app/code/Magento/OfflineShipping/etc/db_schema.xml +++ b/app/code/Magento/OfflineShipping/etc/db_schema.xml @@ -25,10 +25,10 @@ comment="Price"/> <column xsi:type="decimal" name="cost" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Cost"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="pk"/> </constraint> - <constraint xsi:type="unique" name="UNQ_D60821CDB2AFACEE1566CFC02D0D4CAA"> + <constraint xsi:type="unique" referenceId="UNQ_D60821CDB2AFACEE1566CFC02D0D4CAA"> <column name="website_id"/> <column name="dest_country_id"/> <column name="dest_region_id"/> diff --git a/app/code/Magento/Paypal/etc/db_schema.xml b/app/code/Magento/Paypal/etc/db_schema.xml index 2703ee4f5be30..2d7874453a6d9 100644 --- a/app/code/Magento/Paypal/etc/db_schema.xml +++ b/app/code/Magento/Paypal/etc/db_schema.xml @@ -21,19 +21,19 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="agreement_label" nullable="true" length="255" comment="Agreement Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="paypal_billing_agreement" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_STORE_ID_STORE_STORE_ID" table="paypal_billing_agreement" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PAYPAL_BILLING_AGREEMENT_STORE_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -43,17 +43,17 @@ comment="Agreement Id"/> <column xsi:type="int" name="order_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Order Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> <column name="order_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGRT_ORDER_AGRT_ID_PAYPAL_BILLING_AGRT_AGRT_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGRT_ORDER_AGRT_ID_PAYPAL_BILLING_AGRT_AGRT_ID" table="paypal_billing_agreement_order" column="agreement_id" referenceTable="paypal_billing_agreement" referenceColumn="agreement_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID_SALES_ORDER_ENTITY_ID" table="paypal_billing_agreement_order" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> </table> @@ -64,10 +64,10 @@ <column xsi:type="varchar" name="account_id" nullable="true" length="64" comment="Account Id"/> <column xsi:type="varchar" name="filename" nullable="true" length="24" comment="Filename"/> <column xsi:type="timestamp" name="last_modified" on_update="false" nullable="true" comment="Last Modified"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="report_id"/> </constraint> - <constraint xsi:type="unique" name="PAYPAL_SETTLEMENT_REPORT_REPORT_DATE_ACCOUNT_ID"> + <constraint xsi:type="unique" referenceId="PAYPAL_SETTLEMENT_REPORT_REPORT_DATE_ACCOUNT_ID"> <column name="report_date"/> <column name="account_id"/> </constraint> @@ -105,13 +105,13 @@ <column xsi:type="varchar" name="payment_tracking_id" nullable="true" length="255" comment="Payment Tracking ID"/> <column xsi:type="varchar" name="store_id" nullable="true" length="50" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="row_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_E183E488F593E0DE10C6EBFFEBAC9B55" table="paypal_settlement_report_row" + <constraint xsi:type="foreign" referenceId="FK_E183E488F593E0DE10C6EBFFEBAC9B55" table="paypal_settlement_report_row" column="report_id" referenceTable="paypal_settlement_report" referenceColumn="report_id" onDelete="CASCADE"/> - <index name="PAYPAL_SETTLEMENT_REPORT_ROW_REPORT_ID" indexType="btree"> + <index referenceId="PAYPAL_SETTLEMENT_REPORT_ROW_REPORT_ID" indexType="btree"> <column name="report_id"/> </index> </table> @@ -122,12 +122,12 @@ default="0" comment="Website Id"/> <column xsi:type="text" name="content" nullable="true" comment="Content"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="cert_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_CERT_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="paypal_cert" + <constraint xsi:type="foreign" referenceId="PAYPAL_CERT_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="paypal_cert" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="PAYPAL_CERT_WEBSITE_ID" indexType="btree"> + <index referenceId="PAYPAL_CERT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -138,10 +138,10 @@ <column xsi:type="varchar" name="txn_id" nullable="true" length="100" comment="Txn Id"/> <column xsi:type="blob" name="additional_information" nullable="true" comment="Additional Information"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="transaction_id"/> </constraint> - <constraint xsi:type="unique" name="PAYPAL_PAYMENT_TRANSACTION_TXN_ID"> + <constraint xsi:type="unique" referenceId="PAYPAL_PAYMENT_TRANSACTION_TXN_ID"> <column name="txn_id"/> </constraint> </table> diff --git a/app/code/Magento/Persistent/etc/db_schema.xml b/app/code/Magento/Persistent/etc/db_schema.xml index 68678fc60f096..5021d240417b2 100644 --- a/app/code/Magento/Persistent/etc/db_schema.xml +++ b/app/code/Magento/Persistent/etc/db_schema.xml @@ -18,22 +18,22 @@ <column xsi:type="text" name="info" nullable="true" comment="Session Data"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="persistent_id"/> </constraint> - <constraint xsi:type="foreign" name="PERSISTENT_SESSION_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PERSISTENT_SESSION_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="persistent_session" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PERSISTENT_SESSION_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PERSISTENT_SESSION_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="persistent_session" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="PERSISTENT_SESSION_KEY"> + <constraint xsi:type="unique" referenceId="PERSISTENT_SESSION_KEY"> <column name="key"/> </constraint> - <constraint xsi:type="unique" name="PERSISTENT_SESSION_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="PERSISTENT_SESSION_CUSTOMER_ID"> <column name="customer_id"/> </constraint> - <index name="PERSISTENT_SESSION_UPDATED_AT" indexType="btree"> + <index referenceId="PERSISTENT_SESSION_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> </table> diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index ddf8be8a37e9c..62f0eda16afa1 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -26,25 +26,25 @@ default="0" comment="Product alert send count"/> <column xsi:type="smallint" name="status" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Product alert status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="alert_price_id"/> </constraint> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_price" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="product_alert_price" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -65,25 +65,25 @@ default="0" comment="Send Count"/> <column xsi:type="smallint" name="status" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Product alert status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="alert_stock_id"/> </constraint> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="product_alert_stock" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="PRODUCT_ALERT_STOCK_CUSTOMER_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_PRODUCT_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/ProductVideo/etc/db_schema.xml b/app/code/Magento/ProductVideo/etc/db_schema.xml index ceaf4d7fbd85d..bfe087d9a5769 100644 --- a/app/code/Magento/ProductVideo/etc/db_schema.xml +++ b/app/code/Magento/ProductVideo/etc/db_schema.xml @@ -18,14 +18,14 @@ <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> <column xsi:type="text" name="description" nullable="true" comment="Page Meta Description"/> <column xsi:type="text" name="metadata" nullable="true" comment="Video meta data"/> - <constraint xsi:type="foreign" name="FK_6FDF205946906B0E653E60AA769899F8" + <constraint xsi:type="foreign" referenceId="FK_6FDF205946906B0E653E60AA769899F8" table="catalog_product_entity_media_gallery_value_video" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_media_gallery_value_video" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_VAL_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_VAL_ID_STORE_ID"> <column name="value_id"/> <column name="store_id"/> </constraint> diff --git a/app/code/Magento/Quote/etc/db_schema.xml b/app/code/Magento/Quote/etc/db_schema.xml index 3bd7122e65d7f..8e399f03afecd 100644 --- a/app/code/Magento/Quote/etc/db_schema.xml +++ b/app/code/Magento/Quote/etc/db_schema.xml @@ -87,17 +87,17 @@ <column xsi:type="smallint" name="trigger_recollect" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Trigger Recollect"/> <column xsi:type="text" name="ext_shipping_info" nullable="true" comment="Ext Shipping Info"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_STORE_ID_STORE_STORE_ID" table="quote" column="store_id" + <constraint xsi:type="foreign" referenceId="QUOTE_STORE_ID_STORE_STORE_ID" table="quote" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="QUOTE_CUSTOMER_ID_STORE_ID_IS_ACTIVE" indexType="btree"> + <index referenceId="QUOTE_CUSTOMER_ID_STORE_ID_IS_ACTIVE" indexType="btree"> <column name="customer_id"/> <column name="store_id"/> <column name="is_active"/> </index> - <index name="QUOTE_STORE_ID" indexType="btree"> + <index referenceId="QUOTE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -202,12 +202,12 @@ <column xsi:type="text" name="vat_request_date" nullable="true" comment="Vat Request Date"/> <column xsi:type="smallint" name="vat_request_success" padding="6" unsigned="false" nullable="true" identity="false" comment="Vat Request Success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="address_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_address" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_address" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_ADDRESS_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> </table> @@ -289,25 +289,25 @@ nullable="true" comment="Discount Tax Compensation Amount"/> <column xsi:type="decimal" name="base_discount_tax_compensation_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ITEM_PARENT_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_PARENT_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item" column="parent_item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ITEM_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_item" column="quote_id" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_item" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ITEM_STORE_ID_STORE_STORE_ID" table="quote_item" column="store_id" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_STORE_ID_STORE_STORE_ID" table="quote_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="QUOTE_ITEM_PARENT_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_PARENT_ITEM_ID" indexType="btree"> <column name="parent_item_id"/> </index> - <index name="QUOTE_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="QUOTE_ITEM_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="QUOTE_ITEM_STORE_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -382,25 +382,25 @@ nullable="true" comment="Discount Tax Compensation Amount"/> <column xsi:type="decimal" name="base_discount_tax_compensation_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="address_item_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" table="quote_address_item" column="quote_address_id" referenceTable="quote_address" referenceColumn="address_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ADDR_ITEM_PARENT_ITEM_ID_QUOTE_ADDR_ITEM_ADDR_ITEM_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDR_ITEM_PARENT_ITEM_ID_QUOTE_ADDR_ITEM_ADDR_ITEM_ID" table="quote_address_item" column="parent_item_id" referenceTable="quote_address_item" referenceColumn="address_item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID_QUOTE_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_address_item" column="quote_item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <index name="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID" indexType="btree"> <column name="quote_address_id"/> </index> - <index name="QUOTE_ADDRESS_ITEM_PARENT_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_PARENT_ITEM_ID" indexType="btree"> <column name="parent_item_id"/> </index> - <index name="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID" indexType="btree"> <column name="quote_item_id"/> </index> </table> @@ -413,12 +413,12 @@ comment="Product Id"/> <column xsi:type="varchar" name="code" nullable="false" length="255" comment="Code"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ITEM_OPTION_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item_option" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_OPTION_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item_option" column="item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <index name="QUOTE_ITEM_OPTION_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_OPTION_ITEM_ID" indexType="btree"> <column name="item_id"/> </index> </table> @@ -449,12 +449,12 @@ <column xsi:type="text" name="additional_data" nullable="true" comment="Additional Data"/> <column xsi:type="varchar" name="cc_ss_issue" nullable="true" length="255" comment="Cc Ss Issue"/> <column xsi:type="text" name="additional_information" nullable="true" comment="Additional Information"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="payment_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_PAYMENT_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_payment" + <constraint xsi:type="foreign" referenceId="QUOTE_PAYMENT_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_payment" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_PAYMENT_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_PAYMENT_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> </table> @@ -476,13 +476,13 @@ comment="Price"/> <column xsi:type="text" name="error_message" nullable="true" comment="Error Message"/> <column xsi:type="text" name="method_title" nullable="true" comment="Method Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rate_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_SHIPPING_RATE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_SHIPPING_RATE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" table="quote_shipping_rate" column="address_id" referenceTable="quote_address" referenceColumn="address_id" onDelete="CASCADE"/> - <index name="QUOTE_SHIPPING_RATE_ADDRESS_ID" indexType="btree"> + <index referenceId="QUOTE_SHIPPING_RATE_ADDRESS_ID" indexType="btree"> <column name="address_id"/> </index> </table> @@ -492,16 +492,16 @@ <column xsi:type="int" name="quote_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Quote ID"/> <column xsi:type="varchar" name="masked_id" nullable="true" length="32" comment="Masked ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="quote_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ID_MASK_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_id_mask" + <constraint xsi:type="foreign" referenceId="QUOTE_ID_MASK_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_id_mask" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_ID_MASK_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ID_MASK_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="QUOTE_ID_MASK_MASKED_ID" indexType="btree"> + <index referenceId="QUOTE_ID_MASK_MASKED_ID" indexType="btree"> <column name="masked_id"/> </index> </table> diff --git a/app/code/Magento/ReleaseNotification/etc/db_schema.xml b/app/code/Magento/ReleaseNotification/etc/db_schema.xml index 367957fc17732..6f3aa481f73d4 100644 --- a/app/code/Magento/ReleaseNotification/etc/db_schema.xml +++ b/app/code/Magento/ReleaseNotification/etc/db_schema.xml @@ -15,13 +15,13 @@ comment="Viewer admin user ID"/> <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" comment="Viewer last view on product version"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" + <constraint xsi:type="foreign" referenceId="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" table="release_notification_viewer_log" column="viewer_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> + <constraint xsi:type="unique" referenceId="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> <column name="viewer_id"/> </constraint> </table> diff --git a/app/code/Magento/Reports/etc/db_schema.xml b/app/code/Magento/Reports/etc/db_schema.xml index f6c8074411bfc..1321ebba4d3d6 100644 --- a/app/code/Magento/Reports/etc/db_schema.xml +++ b/app/code/Magento/Reports/etc/db_schema.xml @@ -21,33 +21,33 @@ comment="Store Id"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="index_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_CMPD_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_CMPD_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" table="report_compared_product_index" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_CMPD_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_CMPD_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_compared_product_index" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" table="report_compared_product_index" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="REPORT_COMPARED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_COMPARED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> <column name="visitor_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="unique" name="REPORT_COMPARED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_COMPARED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> <column name="customer_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_COMPARED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="REPORT_COMPARED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -65,33 +65,33 @@ comment="Store Id"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="index_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" table="report_viewed_product_index" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_index" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" table="report_viewed_product_index" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> <column name="visitor_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> <column name="customer_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="REPORT_VIEWED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -101,7 +101,7 @@ <column xsi:type="varchar" name="event_name" nullable="false" length="64" comment="Event Name"/> <column xsi:type="smallint" name="customer_login" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Customer Login"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="event_type_id"/> </constraint> </table> @@ -120,27 +120,27 @@ default="0" comment="Subtype"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="event_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_EVENT_STORE_ID_STORE_STORE_ID" table="report_event" + <constraint xsi:type="foreign" referenceId="REPORT_EVENT_STORE_ID_STORE_STORE_ID" table="report_event" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_EVENT_EVENT_TYPE_ID_REPORT_EVENT_TYPES_EVENT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_EVENT_EVENT_TYPE_ID_REPORT_EVENT_TYPES_EVENT_TYPE_ID" table="report_event" column="event_type_id" referenceTable="report_event_types" referenceColumn="event_type_id" onDelete="CASCADE"/> - <index name="REPORT_EVENT_EVENT_TYPE_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_EVENT_TYPE_ID" indexType="btree"> <column name="event_type_id"/> </index> - <index name="REPORT_EVENT_SUBJECT_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_SUBJECT_ID" indexType="btree"> <column name="subject_id"/> </index> - <index name="REPORT_EVENT_OBJECT_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_OBJECT_ID" indexType="btree"> <column name="object_id"/> </index> - <index name="REPORT_EVENT_SUBTYPE" indexType="btree"> + <index referenceId="REPORT_EVENT_SUBTYPE" indexType="btree"> <column name="subtype"/> </index> - <index name="REPORT_EVENT_STORE_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -159,24 +159,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_daily" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_DAILY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_DAILY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_daily" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_DAILY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_DAILY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -195,24 +195,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_monthly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_monthly" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -231,24 +231,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_yearly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_YEARLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_YEARLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_yearly" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_YEARLY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_YEARLY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> diff --git a/app/code/Magento/Review/etc/db_schema.xml b/app/code/Magento/Review/etc/db_schema.xml index 1a2ff588180ce..65cc4d01fed2d 100644 --- a/app/code/Magento/Review/etc/db_schema.xml +++ b/app/code/Magento/Review/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="smallint" name="entity_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Review entity id"/> <column xsi:type="varchar" name="entity_code" nullable="false" length="32" comment="Review entity code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -19,7 +19,7 @@ <column xsi:type="smallint" name="status_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Status id"/> <column xsi:type="varchar" name="status_code" nullable="false" length="32" comment="Status code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status_id"/> </constraint> </table> @@ -34,20 +34,20 @@ default="0" comment="Product id"/> <column xsi:type="smallint" name="status_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Status code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="review_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_ENTITY_ID_REVIEW_ENTITY_ENTITY_ID" table="review" column="entity_id" + <constraint xsi:type="foreign" referenceId="REVIEW_ENTITY_ID_REVIEW_ENTITY_ENTITY_ID" table="review" column="entity_id" referenceTable="review_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_STATUS_ID_REVIEW_STATUS_STATUS_ID" table="review" column="status_id" + <constraint xsi:type="foreign" referenceId="REVIEW_STATUS_ID_REVIEW_STATUS_STATUS_ID" table="review" column="status_id" referenceTable="review_status" referenceColumn="status_id" onDelete="NO ACTION"/> - <index name="REVIEW_ENTITY_ID" indexType="btree"> + <index referenceId="REVIEW_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="REVIEW_STATUS_ID" indexType="btree"> + <index referenceId="REVIEW_STATUS_ID" indexType="btree"> <column name="status_id"/> </index> - <index name="REVIEW_ENTITY_PK_VALUE" indexType="btree"> + <index referenceId="REVIEW_ENTITY_PK_VALUE" indexType="btree"> <column name="entity_pk_value"/> </index> </table> @@ -63,23 +63,23 @@ <column xsi:type="varchar" name="nickname" nullable="false" length="128" comment="User nickname"/> <column xsi:type="int" name="customer_id" padding="10" unsigned="true" nullable="true" identity="false" comment="Customer Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="detail_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="review_detail" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_REVIEW_ID_REVIEW_REVIEW_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_REVIEW_ID_REVIEW_REVIEW_ID" table="review_detail" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_STORE_ID_STORE_STORE_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_STORE_ID_STORE_STORE_ID" table="review_detail" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="REVIEW_DETAIL_REVIEW_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_REVIEW_ID" indexType="btree"> <column name="review_id"/> </index> - <index name="REVIEW_DETAIL_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REVIEW_DETAIL_CUSTOMER_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -96,13 +96,13 @@ default="0" comment="Summarized rating"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="primary_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_ENTITY_SUMMARY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REVIEW_ENTITY_SUMMARY_STORE_ID_STORE_STORE_ID" table="review_entity_summary" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="REVIEW_ENTITY_SUMMARY_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_ENTITY_SUMMARY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -111,15 +111,15 @@ comment="Review Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="review_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_STORE_REVIEW_ID_REVIEW_REVIEW_ID" table="review_store" + <constraint xsi:type="foreign" referenceId="REVIEW_STORE_REVIEW_ID_REVIEW_REVIEW_ID" table="review_store" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_STORE_STORE_ID_STORE_STORE_ID" table="review_store" + <constraint xsi:type="foreign" referenceId="REVIEW_STORE_STORE_ID_STORE_STORE_ID" table="review_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="REVIEW_STORE_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -127,10 +127,10 @@ <column xsi:type="smallint" name="entity_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Entity Id"/> <column xsi:type="varchar" name="entity_code" nullable="false" length="64" comment="Entity Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="RATING_ENTITY_ENTITY_CODE"> + <constraint xsi:type="unique" referenceId="RATING_ENTITY_ENTITY_CODE"> <column name="entity_code"/> </constraint> </table> @@ -144,15 +144,15 @@ default="0" comment="Rating Position On Storefront"/> <column xsi:type="smallint" name="is_active" padding="6" unsigned="false" nullable="false" identity="false" default="1" comment="Rating is active."/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_ENTITY_ID_RATING_ENTITY_ENTITY_ID" table="rating" column="entity_id" + <constraint xsi:type="foreign" referenceId="RATING_ENTITY_ID_RATING_ENTITY_ENTITY_ID" table="rating" column="entity_id" referenceTable="rating_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="RATING_RATING_CODE"> + <constraint xsi:type="unique" referenceId="RATING_RATING_CODE"> <column name="rating_code"/> </constraint> - <index name="RATING_ENTITY_ID" indexType="btree"> + <index referenceId="RATING_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> </table> @@ -166,12 +166,12 @@ default="0" comment="Rating Option Value"/> <column xsi:type="smallint" name="position" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Ration option position on Storefront"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_RATING_ID_RATING_RATING_ID" table="rating_option" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_RATING_ID_RATING_RATING_ID" table="rating_option" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_RATING_ID" indexType="btree"> + <index referenceId="RATING_OPTION_RATING_ID" indexType="btree"> <column name="rating_id"/> </index> </table> @@ -195,15 +195,15 @@ default="0" comment="Percent amount"/> <column xsi:type="smallint" name="value" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Vote option value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="vote_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_OPTION_ID_RATING_OPTION_OPTION_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_OPTION_ID_RATING_OPTION_OPTION_ID" table="rating_option_vote" column="option_id" referenceTable="rating_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_REVIEW_ID_REVIEW_REVIEW_ID" table="rating_option_vote" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_REVIEW_ID_REVIEW_REVIEW_ID" table="rating_option_vote" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_VOTE_OPTION_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> </table> @@ -224,19 +224,19 @@ identity="false" default="0" comment="Vote percent approved by admin"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="primary_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_AGGREGATED_RATING_ID_RATING_RATING_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_AGGREGATED_RATING_ID_RATING_RATING_ID" table="rating_option_vote_aggregated" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_AGGREGATED_STORE_ID_STORE_STORE_ID" table="rating_option_vote_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_VOTE_AGGREGATED_RATING_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_AGGREGATED_RATING_ID" indexType="btree"> <column name="rating_id"/> </index> - <index name="RATING_OPTION_VOTE_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -245,15 +245,15 @@ default="0" comment="Rating id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_STORE_STORE_ID_STORE_STORE_ID" table="rating_store" + <constraint xsi:type="foreign" referenceId="RATING_STORE_STORE_ID_STORE_STORE_ID" table="rating_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_STORE_RATING_ID_RATING_RATING_ID" table="rating_store" + <constraint xsi:type="foreign" referenceId="RATING_STORE_RATING_ID_RATING_RATING_ID" table="rating_store" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <index name="RATING_STORE_STORE_ID" indexType="btree"> + <index referenceId="RATING_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -263,15 +263,15 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="false" length="255" comment="Rating Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_TITLE_RATING_ID_RATING_RATING_ID" table="rating_title" + <constraint xsi:type="foreign" referenceId="RATING_TITLE_RATING_ID_RATING_RATING_ID" table="rating_title" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_TITLE_STORE_ID_STORE_STORE_ID" table="rating_title" + <constraint xsi:type="foreign" referenceId="RATING_TITLE_STORE_ID_STORE_STORE_ID" table="rating_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="RATING_TITLE_STORE_ID" indexType="btree"> + <index referenceId="RATING_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml index 4b716e761094c..6847b4681de52 100644 --- a/app/code/Magento/Sales/etc/db_schema.xml +++ b/app/code/Magento/Sales/etc/db_schema.xml @@ -252,46 +252,46 @@ nullable="true" comment="Base Shipping Incl Tax"/> <column xsi:type="varchar" name="coupon_rule_name" nullable="true" length="255" comment="Coupon Sales Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="sales_order" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="sales_order" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="SALES_ORDER_STORE_ID_STORE_STORE_ID" table="sales_order" column="store_id" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STORE_ID_STORE_STORE_ID" table="sales_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS" indexType="btree"> <column name="status"/> </index> - <index name="SALES_ORDER_STATE" indexType="btree"> + <index referenceId="SALES_ORDER_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_ORDER_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="SALES_ORDER_EXT_ORDER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_EXT_ORDER_ID" indexType="btree"> <column name="ext_order_id"/> </index> - <index name="SALES_ORDER_QUOTE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="SALES_ORDER_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_ORDER_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_ORDER_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_ORDER_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_ORDER_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -334,47 +334,47 @@ <column xsi:type="varchar" name="payment_method" nullable="true" length="255" comment="Payment Method"/> <column xsi:type="decimal" name="total_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_ORDER_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_ORDER_GRID_STATUS" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_STATUS" indexType="btree"> <column name="status"/> </index> - <index name="SALES_ORDER_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_ORDER_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> - <index name="SALES_ORDER_GRID_BASE_TOTAL_PAID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BASE_TOTAL_PAID" indexType="btree"> <column name="base_total_paid"/> </index> - <index name="SALES_ORDER_GRID_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_ORDER_GRID_TOTAL_PAID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_TOTAL_PAID" indexType="btree"> <column name="total_paid"/> </index> - <index name="SALES_ORDER_GRID_SHIPPING_NAME" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_SHIPPING_NAME" indexType="btree"> <column name="shipping_name"/> </index> - <index name="SALES_ORDER_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="SALES_ORDER_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_ORDER_GRID_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="SALES_ORDER_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="FTI_65B9E9925EC58F0C7C2E2F6379C233E7" indexType="fulltext"> + <index referenceId="FTI_65B9E9925EC58F0C7C2E2F6379C233E7" indexType="fulltext"> <column name="increment_id"/> <column name="billing_name"/> <column name="shipping_name"/> @@ -419,13 +419,13 @@ <column xsi:type="text" name="vat_request_date" nullable="true" comment="Vat Request Date"/> <column xsi:type="smallint" name="vat_request_success" padding="6" unsigned="false" nullable="true" identity="false" comment="Vat Request Success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_ADDRESS_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ADDRESS_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_address" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_ADDRESS_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ADDRESS_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -444,16 +444,16 @@ comment="Created At"/> <column xsi:type="varchar" name="entity_name" nullable="true" length="32" comment="Shows what entity history is bind to."/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_HISTORY_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_HISTORY_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_status_history" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_STATUS_HISTORY_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_HISTORY_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_ORDER_STATUS_HISTORY_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_HISTORY_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> @@ -586,17 +586,17 @@ comment="Discount Refunded"/> <column xsi:type="decimal" name="base_discount_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_ITEM_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_order_item" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ITEM_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_order_item" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_ITEM_STORE_ID_STORE_STORE_ID" table="sales_order_item" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ITEM_STORE_ID_STORE_STORE_ID" table="sales_order_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="SALES_ORDER_ITEM_ORDER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ITEM_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_ORDER_ITEM_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -684,13 +684,13 @@ <column xsi:type="varchar" name="cc_trans_id" nullable="true" length="32" comment="Cc Trans Id"/> <column xsi:type="varchar" name="address_status" nullable="true" length="32" comment="Address Status"/> <column xsi:type="text" name="additional_information" nullable="true" comment="Additional Information"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_PAYMENT_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_PAYMENT_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_payment" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_PAYMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_PAYMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -727,36 +727,36 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_shipment" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_shipment" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_STORE_ID_STORE_STORE_ID" table="sales_shipment" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_STORE_ID_STORE_STORE_ID" table="sales_shipment" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_SHIPMENT_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SHIPMENT_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_SHIPMENT_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_SHIPMENT_TOTAL_QTY" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TOTAL_QTY" indexType="btree"> <column name="total_qty"/> </index> - <index name="SALES_SHIPMENT_ORDER_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_SHIPMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_SHIPMENT_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_SHIPMENT_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_SHIPMENT_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -788,44 +788,44 @@ comment="Shipping Method Name"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created At"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_SHIPMENT_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SHIPMENT_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_SHIPMENT_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_SHIPMENT_GRID_TOTAL_QTY" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_TOTAL_QTY" indexType="btree"> <column name="total_qty"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_SHIPMENT_GRID_SHIPMENT_STATUS" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_SHIPMENT_STATUS" indexType="btree"> <column name="shipment_status"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_STATUS" indexType="btree"> <column name="order_status"/> </index> - <index name="SALES_SHIPMENT_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_SHIPMENT_GRID_SHIPPING_NAME" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_SHIPPING_NAME" indexType="btree"> <column name="shipping_name"/> </index> - <index name="SALES_SHIPMENT_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="FTI_086B40C8955F167B8EA76653437879B4" indexType="fulltext"> + <index referenceId="FTI_086B40C8955F167B8EA76653437879B4" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="shipping_name"/> @@ -855,13 +855,13 @@ <column xsi:type="text" name="description" nullable="true" comment="Description"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Name"/> <column xsi:type="varchar" name="sku" nullable="true" length="255" comment="Sku"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_ITEM_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_ITEM_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_item" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -883,19 +883,19 @@ comment="Created At"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_TRACK_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_TRACK_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_track" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_TRACK_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_SHIPMENT_TRACK_ORDER_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_SHIPMENT_TRACK_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> @@ -911,16 +911,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_COMMENT_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_COMMENT_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_comment" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1013,39 +1013,39 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_invoice" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_invoice" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_INVOICE_STORE_ID_STORE_STORE_ID" table="sales_invoice" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_STORE_ID_STORE_STORE_ID" table="sales_invoice" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICE_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_INVOICE_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_INVOICE_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_INVOICE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_INVOICE_ORDER_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_INVOICE_STATE" indexType="btree"> + <index referenceId="SALES_INVOICE_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_INVOICE_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_INVOICE_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_INVOICE_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_INVOICE_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_INVOICE_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -1087,41 +1087,41 @@ <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> <column xsi:type="decimal" name="base_grand_total" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Grand Total"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_INVOICE_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_INVOICE_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_INVOICE_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_INVOICE_GRID_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_INVOICE_GRID_STATE" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_INVOICE_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_INVOICE_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="FTI_95D9C924DD6A8734EB8B5D01D60F90DE" indexType="fulltext"> + <index referenceId="FTI_95D9C924DD6A8734EB8B5D01D60F90DE" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="billing_name"/> @@ -1130,7 +1130,7 @@ <column name="customer_name"/> <column name="customer_email"/> </index> - <index name="SALES_INVOICE_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> </table> @@ -1180,13 +1180,13 @@ unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> <column xsi:type="text" name="tax_ratio" nullable="true" comment="Ratio of tax invoiced over tax of the order item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_ITEM_PARENT_ID_SALES_INVOICE_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_ITEM_PARENT_ID_SALES_INVOICE_ENTITY_ID" table="sales_invoice_item" column="parent_id" referenceTable="sales_invoice" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_INVOICE_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1202,16 +1202,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_COMMENT_PARENT_ID_SALES_INVOICE_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_COMMENT_PARENT_ID_SALES_INVOICE_ENTITY_ID" table="sales_invoice_comment" column="parent_id" referenceTable="sales_invoice" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_INVOICE_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1312,39 +1312,39 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_creditmemo" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_creditmemo" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_STORE_ID_STORE_STORE_ID" table="sales_creditmemo" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_STORE_ID_STORE_STORE_ID" table="sales_creditmemo" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_CREDITMEMO_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_CREDITMEMO_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_CREDITMEMO_STORE_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_CREDITMEMO_ORDER_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_CREDITMEMO_CREDITMEMO_STATUS" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_CREDITMEMO_STATUS" indexType="btree"> <column name="creditmemo_status"/> </index> - <index name="SALES_CREDITMEMO_STATE" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_CREDITMEMO_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_CREDITMEMO_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_CREDITMEMO_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -1386,47 +1386,47 @@ comment="Adjustment Negative"/> <column xsi:type="decimal" name="order_base_grand_total" scale="4" precision="12" unsigned="false" nullable="true" comment="Order Grand Total"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_CREDITMEMO_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_CREDITMEMO_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_CREDITMEMO_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_CREDITMEMO_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_STATE" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_CREDITMEMO_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_STATUS" indexType="btree"> <column name="order_status"/> </index> - <index name="SALES_CREDITMEMO_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> - <index name="SALES_CREDITMEMO_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_BASE_GRAND_TOTAL" indexType="btree"> <column name="order_base_grand_total"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="FTI_32B7BA885941A8254EE84AE650ABDC86" indexType="fulltext"> + <index referenceId="FTI_32B7BA885941A8254EE84AE650ABDC86" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="billing_name"/> @@ -1482,13 +1482,13 @@ unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> <column xsi:type="text" name="tax_ratio" nullable="true" comment="Ratio of tax in the creditmemo item over tax of the order item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_ITEM_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_ITEM_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" table="sales_creditmemo_item" column="parent_id" referenceTable="sales_creditmemo" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_CREDITMEMO_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1504,16 +1504,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_COMMENT_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_COMMENT_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" table="sales_creditmemo_comment" column="parent_id" referenceTable="sales_creditmemo" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_CREDITMEMO_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1533,18 +1533,18 @@ comment="Invoiced Captured"/> <column xsi:type="decimal" name="invoiced_not_captured" scale="4" precision="12" unsigned="false" nullable="true" comment="Invoiced Not Captured"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICED_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICED_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_invoiced_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_INVOICED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_INVOICED_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICED_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1565,18 +1565,18 @@ comment="Invoiced Captured"/> <column xsi:type="decimal" name="invoiced_not_captured" scale="4" precision="12" unsigned="false" nullable="true" comment="Invoiced Not Captured"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_invoiced_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_INVOICED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1619,18 +1619,18 @@ nullable="false" default="0" comment="Total Discount Amount"/> <column xsi:type="decimal" name="total_discount_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Discount Amount Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" table="sales_order_aggregated_created" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_AGGREGATED_CREATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_AGGREGATED_CREATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1673,18 +1673,18 @@ nullable="false" default="0" comment="Total Discount Amount"/> <column xsi:type="decimal" name="total_discount_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Discount Amount Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="sales_order_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_AGGREGATED_UPDATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_AGGREGATED_UPDATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1705,27 +1705,27 @@ <column xsi:type="blob" name="additional_information" nullable="true" comment="Additional Information"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="transaction_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_PAYMENT_TRANSACTION_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_PAYMENT_TRANSACTION_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_payment_transaction" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_B99FF1A06402D725EBDB0F3A7ECD47A2" table="sales_payment_transaction" + <constraint xsi:type="foreign" referenceId="FK_B99FF1A06402D725EBDB0F3A7ECD47A2" table="sales_payment_transaction" column="parent_id" referenceTable="sales_payment_transaction" referenceColumn="transaction_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_PAYMENT_TRANSACTION_PAYMENT_ID_SALES_ORDER_PAYMENT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="SALES_PAYMENT_TRANSACTION_PAYMENT_ID_SALES_ORDER_PAYMENT_ENTT_ID" table="sales_payment_transaction" column="payment_id" referenceTable="sales_order_payment" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_PAYMENT_TRANSACTION_ORDER_ID_PAYMENT_ID_TXN_ID"> + <constraint xsi:type="unique" referenceId="SALES_PAYMENT_TRANSACTION_ORDER_ID_PAYMENT_ID_TXN_ID"> <column name="order_id"/> <column name="payment_id"/> <column name="txn_id"/> </constraint> - <index name="SALES_PAYMENT_TRANSACTION_PARENT_ID" indexType="btree"> + <index referenceId="SALES_PAYMENT_TRANSACTION_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_PAYMENT_TRANSACTION_PAYMENT_ID" indexType="btree"> + <index referenceId="SALES_PAYMENT_TRANSACTION_PAYMENT_ID" indexType="btree"> <column name="payment_id"/> </index> </table> @@ -1743,18 +1743,18 @@ comment="Online Refunded"/> <column xsi:type="decimal" name="offline_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Offline Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_REFUNDED_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_REFUNDED_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_refunded_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_REFUNDED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_REFUNDED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_REFUNDED_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_REFUNDED_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1773,18 +1773,18 @@ comment="Online Refunded"/> <column xsi:type="decimal" name="offline_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Offline Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_refunded_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_REFUNDED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_REFUNDED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1802,19 +1802,19 @@ comment="Total Shipping"/> <column xsi:type="decimal" name="total_shipping_actual" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Shipping Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPPING_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPPING_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_shipping_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_SHPP_AGGRED_PERIOD_STORE_ID_ORDER_STS_SHPP_DESCRIPTION"> + <constraint xsi:type="unique" referenceId="SALES_SHPP_AGGRED_PERIOD_STORE_ID_ORDER_STS_SHPP_DESCRIPTION"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="shipping_description"/> </constraint> - <index name="SALES_SHIPPING_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPPING_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1833,19 +1833,19 @@ comment="Total Shipping"/> <column xsi:type="decimal" name="total_shipping_actual" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Shipping Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_shipping_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="UNQ_C05FAE47282EEA68654D0924E946761F"> + <constraint xsi:type="unique" referenceId="UNQ_C05FAE47282EEA68654D0924E946761F"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="shipping_description"/> </constraint> - <index name="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1864,21 +1864,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_daily" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_DAILY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1897,21 +1897,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_monthly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1930,21 +1930,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_yearly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_YEARLY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1969,10 +1969,10 @@ comment="Process"/> <column xsi:type="decimal" name="base_real_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Real Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_id"/> </constraint> - <index name="SALES_ORDER_TAX_ORDER_ID_PRIORITY_POSITION" indexType="btree"> + <index referenceId="SALES_ORDER_TAX_ORDER_ID_PRIORITY_POSITION" indexType="btree"> <column name="order_id"/> <column name="priority"/> <column name="position"/> @@ -1999,30 +1999,30 @@ comment="Id of the associated item"/> <column xsi:type="varchar" name="taxable_item_type" nullable="false" length="32" comment="Type of the taxable item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_item_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_ASSOCIATED_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_ASSOCIATED_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="sales_order_tax_item" column="associated_item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_TAX_ID_SALES_ORDER_TAX_TAX_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_TAX_ID_SALES_ORDER_TAX_TAX_ID" table="sales_order_tax_item" column="tax_id" referenceTable="sales_order_tax" referenceColumn="tax_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="sales_order_tax_item" column="item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_ORDER_TAX_ITEM_TAX_ID_ITEM_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_TAX_ITEM_TAX_ID_ITEM_ID"> <column name="tax_id"/> <column name="item_id"/> </constraint> - <index name="SALES_ORDER_TAX_ITEM_ITEM_ID" indexType="btree"> + <index referenceId="SALES_ORDER_TAX_ITEM_ITEM_ID" indexType="btree"> <column name="item_id"/> </index> </table> <table name="sales_order_status" resource="sales" engine="innodb" comment="Sales Order Status Table"> <column xsi:type="varchar" name="status" nullable="false" length="32" comment="Status"/> <column xsi:type="varchar" name="label" nullable="false" length="128" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> </constraint> </table> @@ -2033,11 +2033,11 @@ default="0" comment="Is Default"/> <column xsi:type="smallint" name="visible_on_front" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Visible on front"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> <column name="state"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_STATE_STATUS_SALES_ORDER_STATUS_STATUS" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_STATE_STATUS_SALES_ORDER_STATUS_STATUS" table="sales_order_status_state" column="status" referenceTable="sales_order_status" referenceColumn="status" onDelete="CASCADE"/> </table> @@ -2046,17 +2046,17 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="false" length="128" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_LABEL_STATUS_SALES_ORDER_STATUS_STATUS" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_LABEL_STATUS_SALES_ORDER_STATUS_STATUS" table="sales_order_status_label" column="status" referenceTable="sales_order_status" referenceColumn="status" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_LABEL_STORE_ID_STORE_STORE_ID" table="sales_order_status_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_STATUS_LABEL_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/SalesRule/etc/db_schema.xml b/app/code/Magento/SalesRule/etc/db_schema.xml index cdbd50c3f3472..9c220d36d387a 100644 --- a/app/code/Magento/SalesRule/etc/db_schema.xml +++ b/app/code/Magento/SalesRule/etc/db_schema.xml @@ -46,10 +46,10 @@ identity="false" default="0" comment="Use Auto Generation"/> <column xsi:type="int" name="uses_per_coupon" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="User Per Coupon"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <index name="SALESRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> + <index referenceId="SALESRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> <column name="to_date"/> @@ -76,19 +76,19 @@ comment="Coupon Code Creation Date"/> <column xsi:type="smallint" name="type" padding="6" unsigned="false" nullable="true" identity="false" default="0" comment="Coupon Code Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="coupon_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_RULE_ID_SALESRULE_RULE_ID" table="salesrule_coupon" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_RULE_ID_SALESRULE_RULE_ID" table="salesrule_coupon" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_COUPON_CODE"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_CODE"> <column name="code"/> </constraint> - <constraint xsi:type="unique" name="SALESRULE_COUPON_RULE_ID_IS_PRIMARY"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_RULE_ID_IS_PRIMARY"> <column name="rule_id"/> <column name="is_primary"/> </constraint> - <index name="SALESRULE_COUPON_RULE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_RULE_ID" indexType="btree"> <column name="rule_id"/> </index> </table> @@ -99,17 +99,17 @@ comment="Customer Id"/> <column xsi:type="int" name="times_used" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Times Used"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="coupon_id"/> <column name="customer_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_USAGE_COUPON_ID_SALESRULE_COUPON_COUPON_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_USAGE_COUPON_ID_SALESRULE_COUPON_COUPON_ID" table="salesrule_coupon_usage" column="coupon_id" referenceTable="salesrule_coupon" referenceColumn="coupon_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_USAGE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_USAGE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="salesrule_coupon_usage" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALESRULE_COUPON_USAGE_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_USAGE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -122,19 +122,19 @@ default="0" comment="Customer Id"/> <column xsi:type="smallint" name="times_used" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Times Used"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_customer_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="salesrule_customer" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <index name="SALESRULE_CUSTOMER_RULE_ID_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_RULE_ID_CUSTOMER_ID" indexType="btree"> <column name="rule_id"/> <column name="customer_id"/> </index> - <index name="SALESRULE_CUSTOMER_CUSTOMER_ID_RULE_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_CUSTOMER_ID_RULE_ID" indexType="btree"> <column name="customer_id"/> <column name="rule_id"/> </index> @@ -147,18 +147,18 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="true" length="255" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="label_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_LABEL_RULE_ID_SALESRULE_RULE_ID" table="salesrule_label" + <constraint xsi:type="foreign" referenceId="SALESRULE_LABEL_RULE_ID_SALESRULE_RULE_ID" table="salesrule_label" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_LABEL_STORE_ID_STORE_STORE_ID" table="salesrule_label" + <constraint xsi:type="foreign" referenceId="SALESRULE_LABEL_STORE_ID_STORE_STORE_ID" table="salesrule_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_LABEL_RULE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALESRULE_LABEL_RULE_ID_STORE_ID"> <column name="rule_id"/> <column name="store_id"/> </constraint> - <index name="SALESRULE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -170,31 +170,31 @@ comment="Customer Group Id"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_PRD_ATTR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRD_ATTR_ATTR_ID_EAV_ATTR_ATTR_ID" table="salesrule_product_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRD_ATTR_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRD_ATTR_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="salesrule_product_attribute" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRODUCT_ATTRIBUTE_RULE_ID_SALESRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRODUCT_ATTRIBUTE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_product_attribute" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="salesrule_product_attribute" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -220,22 +220,22 @@ <column xsi:type="decimal" name="total_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount Actual"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_COUPON_AGGRED_PERIOD_STORE_ID_ORDER_STS_COUPON_CODE"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_AGGRED_PERIOD_STORE_ID_ORDER_STS_COUPON_CODE"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -262,22 +262,22 @@ <column xsi:type="decimal" name="total_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount Actual"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_7196FA120A4F0F84E1B66605E87E213E"> + <constraint xsi:type="unique" referenceId="UNQ_7196FA120A4F0F84E1B66605E87E213E"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_UPDATED_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -298,22 +298,22 @@ <column xsi:type="decimal" name="total_amount" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_1094D1FBBCBB11704A29DEF3ACC37D2B"> + <constraint xsi:type="unique" referenceId="UNQ_1094D1FBBCBB11704A29DEF3ACC37D2B"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_ORDER_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -321,16 +321,16 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_WEBSITE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_website" + <constraint xsi:type="foreign" referenceId="SALESRULE_WEBSITE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_website" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="salesrule_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SALESRULE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="SALESRULE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -339,17 +339,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="int" name="customer_group_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Customer Group Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_GROUP_RULE_ID_SALESRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_GROUP_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer_group" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="salesrule_customer_group" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <index name="SALESRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> diff --git a/app/code/Magento/SalesSequence/etc/db_schema.xml b/app/code/Magento/SalesSequence/etc/db_schema.xml index 530a9a33b0cfe..0e580b85bd608 100644 --- a/app/code/Magento/SalesSequence/etc/db_schema.xml +++ b/app/code/Magento/SalesSequence/etc/db_schema.xml @@ -23,13 +23,13 @@ <column xsi:type="int" name="warning_value" padding="10" unsigned="true" nullable="false" identity="false" comment="WarningValue for sequence"/> <column xsi:type="boolean" name="is_active" nullable="false" default="false" comment="isActive flag"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="profile_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SEQUENCE_PROFILE_META_ID_SALES_SEQUENCE_META_META_ID" + <constraint xsi:type="foreign" referenceId="SALES_SEQUENCE_PROFILE_META_ID_SALES_SEQUENCE_META_META_ID" table="sales_sequence_profile" column="meta_id" referenceTable="sales_sequence_meta" referenceColumn="meta_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_SEQUENCE_PROFILE_META_ID_PREFIX_SUFFIX"> + <constraint xsi:type="unique" referenceId="SALES_SEQUENCE_PROFILE_META_ID_PREFIX_SUFFIX"> <column name="meta_id"/> <column name="prefix"/> <column name="suffix"/> @@ -42,10 +42,10 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="sequence_table" nullable="false" length="32" comment="table for sequence"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="meta_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_SEQUENCE_META_ENTITY_TYPE_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SEQUENCE_META_ENTITY_TYPE_STORE_ID"> <column name="entity_type"/> <column name="store_id"/> </constraint> diff --git a/app/code/Magento/Search/etc/db_schema.xml b/app/code/Magento/Search/etc/db_schema.xml index 9b2dfb493dbb8..754af7d246d6d 100644 --- a/app/code/Magento/Search/etc/db_schema.xml +++ b/app/code/Magento/Search/etc/db_schema.xml @@ -26,24 +26,24 @@ default="0" comment="Processed status"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="query_id"/> </constraint> - <constraint xsi:type="foreign" name="SEARCH_QUERY_STORE_ID_STORE_STORE_ID" table="search_query" + <constraint xsi:type="foreign" referenceId="SEARCH_QUERY_STORE_ID_STORE_STORE_ID" table="search_query" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SEARCH_QUERY_QUERY_TEXT_STORE_ID"> + <constraint xsi:type="unique" referenceId="SEARCH_QUERY_QUERY_TEXT_STORE_ID"> <column name="query_text"/> <column name="store_id"/> </constraint> - <index name="SEARCH_QUERY_QUERY_TEXT_STORE_ID_POPULARITY" indexType="btree"> + <index referenceId="SEARCH_QUERY_QUERY_TEXT_STORE_ID_POPULARITY" indexType="btree"> <column name="query_text"/> <column name="store_id"/> <column name="popularity"/> </index> - <index name="SEARCH_QUERY_STORE_ID" indexType="btree"> + <index referenceId="SEARCH_QUERY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SEARCH_QUERY_IS_PROCESSED" indexType="btree"> + <index referenceId="SEARCH_QUERY_IS_PROCESSED" indexType="btree"> <column name="is_processed"/> </index> </table> @@ -55,21 +55,21 @@ default="0" comment="Store Id - identifies the store view these synonyms belong to"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id - identifies the website id these synonyms belong to"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="group_id"/> </constraint> - <constraint xsi:type="foreign" name="SEARCH_SYNONYMS_STORE_ID_STORE_STORE_ID" table="search_synonyms" + <constraint xsi:type="foreign" referenceId="SEARCH_SYNONYMS_STORE_ID_STORE_STORE_ID" table="search_synonyms" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SEARCH_SYNONYMS_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SEARCH_SYNONYMS_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="search_synonyms" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SEARCH_SYNONYMS_SYNONYMS" indexType="fulltext"> + <index referenceId="SEARCH_SYNONYMS_SYNONYMS" indexType="fulltext"> <column name="synonyms"/> </index> - <index name="SEARCH_SYNONYMS_STORE_ID" indexType="btree"> + <index referenceId="SEARCH_SYNONYMS_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SEARCH_SYNONYMS_WEBSITE_ID" indexType="btree"> + <index referenceId="SEARCH_SYNONYMS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/Security/etc/db_schema.xml b/app/code/Magento/Security/etc/db_schema.xml index f14e6de79e894..ce7143582ce69 100644 --- a/app/code/Magento/Security/etc/db_schema.xml +++ b/app/code/Magento/Security/etc/db_schema.xml @@ -21,15 +21,15 @@ comment="Update Time"/> <column xsi:type="varchar" name="ip" nullable="false" length="15" onCreate="migrateDataFrom(ip)" comment="Remote user IP"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="ADMIN_USER_SESSION_USER_ID_ADMIN_USER_USER_ID" table="admin_user_session" + <constraint xsi:type="foreign" referenceId="ADMIN_USER_SESSION_USER_ID_ADMIN_USER_USER_ID" table="admin_user_session" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="ADMIN_USER_SESSION_SESSION_ID" indexType="btree"> + <index referenceId="ADMIN_USER_SESSION_SESSION_ID" indexType="btree"> <column name="session_id"/> </index> - <index name="ADMIN_USER_SESSION_USER_ID" indexType="btree"> + <index referenceId="ADMIN_USER_SESSION_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> @@ -45,13 +45,13 @@ comment="Timestamp when the event occurs"/> <column xsi:type="varchar" name="ip" nullable="false" length="15" onCreate="migrateDataFrom(ip)" comment="Remote user IP"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <index name="PASSWORD_RESET_REQUEST_EVENT_ACCOUNT_REFERENCE" indexType="btree"> + <index referenceId="PASSWORD_RESET_REQUEST_EVENT_ACCOUNT_REFERENCE" indexType="btree"> <column name="account_reference"/> </index> - <index name="PASSWORD_RESET_REQUEST_EVENT_CREATED_AT" indexType="btree"> + <index referenceId="PASSWORD_RESET_REQUEST_EVENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> diff --git a/app/code/Magento/SendFriend/etc/db_schema.xml b/app/code/Magento/SendFriend/etc/db_schema.xml index 7537f67cf552a..b9551749dfc6d 100644 --- a/app/code/Magento/SendFriend/etc/db_schema.xml +++ b/app/code/Magento/SendFriend/etc/db_schema.xml @@ -16,13 +16,13 @@ comment="Log time"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <index name="SENDFRIEND_LOG_IP" indexType="btree"> + <index referenceId="SENDFRIEND_LOG_IP" indexType="btree"> <column name="ip"/> </index> - <index name="SENDFRIEND_LOG_TIME" indexType="btree"> + <index referenceId="SENDFRIEND_LOG_TIME" indexType="btree"> <column name="time"/> </index> </table> diff --git a/app/code/Magento/Signifyd/etc/db_schema.xml b/app/code/Magento/Signifyd/etc/db_schema.xml index 6a31eacbb45f5..1cee590dec745 100644 --- a/app/code/Magento/Signifyd/etc/db_schema.xml +++ b/app/code/Magento/Signifyd/etc/db_schema.xml @@ -24,15 +24,15 @@ <column xsi:type="varchar" name="review_disposition" nullable="true" length="32" comment="Review_disposition"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created_at"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated_at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SIGNIFYD_CASE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="signifyd_case" + <constraint xsi:type="foreign" referenceId="SIGNIFYD_CASE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="signifyd_case" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SIGNIFYD_CASE_ORDER_ID"> + <constraint xsi:type="unique" referenceId="SIGNIFYD_CASE_ORDER_ID"> <column name="order_id"/> </constraint> - <constraint xsi:type="unique" name="SIGNIFYD_CASE_CASE_ID"> + <constraint xsi:type="unique" referenceId="SIGNIFYD_CASE_CASE_ID"> <column name="case_id"/> </constraint> </table> diff --git a/app/code/Magento/Sitemap/etc/db_schema.xml b/app/code/Magento/Sitemap/etc/db_schema.xml index 82a9b8ef5148c..b3c028b626b73 100644 --- a/app/code/Magento/Sitemap/etc/db_schema.xml +++ b/app/code/Magento/Sitemap/etc/db_schema.xml @@ -16,12 +16,12 @@ <column xsi:type="timestamp" name="sitemap_time" on_update="false" nullable="true" comment="Sitemap Time"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="sitemap_id"/> </constraint> - <constraint xsi:type="foreign" name="SITEMAP_STORE_ID_STORE_STORE_ID" table="sitemap" column="store_id" + <constraint xsi:type="foreign" referenceId="SITEMAP_STORE_ID_STORE_STORE_ID" table="sitemap" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="SITEMAP_STORE_ID" indexType="btree"> + <index referenceId="SITEMAP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Store/etc/db_schema.xml b/app/code/Magento/Store/etc/db_schema.xml index 3c2bc3e3c117b..6eea94b8deec7 100644 --- a/app/code/Magento/Store/etc/db_schema.xml +++ b/app/code/Magento/Store/etc/db_schema.xml @@ -18,16 +18,16 @@ identity="false" default="0" comment="Default Group Id"/> <column xsi:type="smallint" name="is_default" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Defines Is Website Default"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="website_id"/> </constraint> - <constraint xsi:type="unique" name="STORE_WEBSITE_CODE"> + <constraint xsi:type="unique" referenceId="STORE_WEBSITE_CODE"> <column name="code"/> </constraint> - <index name="STORE_WEBSITE_SORT_ORDER" indexType="btree"> + <index referenceId="STORE_WEBSITE_SORT_ORDER" indexType="btree"> <column name="sort_order"/> </index> - <index name="STORE_WEBSITE_DEFAULT_GROUP_ID" indexType="btree"> + <index referenceId="STORE_WEBSITE_DEFAULT_GROUP_ID" indexType="btree"> <column name="default_group_id"/> </index> </table> @@ -42,18 +42,18 @@ <column xsi:type="smallint" name="default_store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Default Store Id"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Store group unique code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="group_id"/> </constraint> - <constraint xsi:type="foreign" name="STORE_GROUP_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store_group" + <constraint xsi:type="foreign" referenceId="STORE_GROUP_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store_group" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="STORE_GROUP_CODE"> + <constraint xsi:type="unique" referenceId="STORE_GROUP_CODE"> <column name="code"/> </constraint> - <index name="STORE_GROUP_WEBSITE_ID" indexType="btree"> + <index referenceId="STORE_GROUP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="STORE_GROUP_DEFAULT_STORE_ID" indexType="btree"> + <index referenceId="STORE_GROUP_DEFAULT_STORE_ID" indexType="btree"> <column name="default_store_id"/> </index> </table> @@ -70,24 +70,24 @@ default="0" comment="Store Sort Order"/> <column xsi:type="smallint" name="is_active" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Activity"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="STORE_GROUP_ID_STORE_GROUP_GROUP_ID" table="store" column="group_id" + <constraint xsi:type="foreign" referenceId="STORE_GROUP_ID_STORE_GROUP_GROUP_ID" table="store" column="group_id" referenceTable="store_group" referenceColumn="group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="STORE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store" + <constraint xsi:type="foreign" referenceId="STORE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="STORE_CODE"> + <constraint xsi:type="unique" referenceId="STORE_CODE"> <column name="code"/> </constraint> - <index name="STORE_WEBSITE_ID" indexType="btree"> + <index referenceId="STORE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="STORE_IS_ACTIVE_SORT_ORDER" indexType="btree"> + <index referenceId="STORE_IS_ACTIVE_SORT_ORDER" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> </index> - <index name="STORE_GROUP_ID" indexType="btree"> + <index referenceId="STORE_GROUP_ID" indexType="btree"> <column name="group_id"/> </index> </table> diff --git a/app/code/Magento/Swatches/etc/db_schema.xml b/app/code/Magento/Swatches/etc/db_schema.xml index c960f27b0fb54..3dafbc3876494 100644 --- a/app/code/Magento/Swatches/etc/db_schema.xml +++ b/app/code/Magento/Swatches/etc/db_schema.xml @@ -20,20 +20,20 @@ <column xsi:type="smallint" name="type" padding="5" unsigned="true" nullable="false" identity="false" comment="Swatch type: 0 - text, 1 - visual color, 2 - visual image"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Swatch Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="swatch_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_STORE_STORE_ID" table="eav_attribute_option_swatch" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTR_OPT_SWATCH_OPT_ID_EAV_ATTR_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_OPT_SWATCH_OPT_ID_EAV_ATTR_OPT_OPT_ID" table="eav_attribute_option_swatch" column="option_id" referenceTable="eav_attribute_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_OPTION_ID"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_OPTION_ID"> <column name="store_id"/> <column name="option_id"/> </constraint> - <index name="EAV_ATTRIBUTE_OPTION_SWATCH_SWATCH_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_SWATCH_ID" indexType="btree"> <column name="swatch_id"/> </index> </table> diff --git a/app/code/Magento/Tax/etc/db_schema.xml b/app/code/Magento/Tax/etc/db_schema.xml index 6e83a64791969..f5227a9ef3a66 100644 --- a/app/code/Magento/Tax/etc/db_schema.xml +++ b/app/code/Magento/Tax/etc/db_schema.xml @@ -13,7 +13,7 @@ <column xsi:type="varchar" name="class_name" nullable="false" length="255" comment="Class Name"/> <column xsi:type="varchar" name="class_type" nullable="false" length="8" default="CUSTOMER" comment="Class Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="class_id"/> </constraint> </table> @@ -27,14 +27,14 @@ comment="Position"/> <column xsi:type="int" name="calculate_subtotal" padding="11" unsigned="false" nullable="false" identity="false" comment="Calculate off subtotal option"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rule_id"/> </constraint> - <index name="TAX_CALCULATION_RULE_PRIORITY_POSITION" indexType="btree"> + <index referenceId="TAX_CALCULATION_RULE_PRIORITY_POSITION" indexType="btree"> <column name="priority"/> <column name="position"/> </index> - <index name="TAX_CALCULATION_RULE_CODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RULE_CODE" indexType="btree"> <column name="code"/> </index> </table> @@ -54,18 +54,18 @@ comment="Zip From"/> <column xsi:type="int" name="zip_to" padding="10" unsigned="true" nullable="true" identity="false" comment="Zip To"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rate_id"/> </constraint> - <index name="TAX_CALCULATION_RATE_TAX_COUNTRY_ID_TAX_REGION_ID_TAX_POSTCODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TAX_COUNTRY_ID_TAX_REGION_ID_TAX_POSTCODE" indexType="btree"> <column name="tax_country_id"/> <column name="tax_region_id"/> <column name="tax_postcode"/> </index> - <index name="TAX_CALCULATION_RATE_CODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_CODE" indexType="btree"> <column name="code"/> </index> - <index name="IDX_CA799F1E2CB843495F601E56C84A626D" indexType="btree"> + <index referenceId="IDX_CA799F1E2CB843495F601E56C84A626D" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="tax_country_id"/> <column name="tax_region_id"/> @@ -84,31 +84,31 @@ identity="false" comment="Customer Tax Class Id"/> <column xsi:type="smallint" name="product_tax_class_id" padding="6" unsigned="false" nullable="false" identity="false" comment="Product Tax Class Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" table="tax_calculation" column="product_tax_class_id" referenceTable="tax_class" referenceColumn="class_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" table="tax_calculation" column="customer_tax_class_id" referenceTable="tax_class" referenceColumn="class_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALC_TAX_CALC_RATE_ID_TAX_CALC_RATE_TAX_CALC_RATE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALC_TAX_CALC_RATE_ID_TAX_CALC_RATE_TAX_CALC_RATE_ID" table="tax_calculation" column="tax_calculation_rate_id" referenceTable="tax_calculation_rate" referenceColumn="tax_calculation_rate_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALC_TAX_CALC_RULE_ID_TAX_CALC_RULE_TAX_CALC_RULE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALC_TAX_CALC_RULE_ID_TAX_CALC_RULE_TAX_CALC_RULE_ID" table="tax_calculation" column="tax_calculation_rule_id" referenceTable="tax_calculation_rule" referenceColumn="tax_calculation_rule_id" onDelete="CASCADE"/> - <index name="TAX_CALCULATION_TAX_CALCULATION_RULE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_TAX_CALCULATION_RULE_ID" indexType="btree"> <column name="tax_calculation_rule_id"/> </index> - <index name="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID" indexType="btree"> <column name="customer_tax_class_id"/> </index> - <index name="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID" indexType="btree"> <column name="product_tax_class_id"/> </index> - <index name="TAX_CALC_TAX_CALC_RATE_ID_CSTR_TAX_CLASS_ID_PRD_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALC_TAX_CALC_RATE_ID_CSTR_TAX_CLASS_ID_PRD_TAX_CLASS_ID" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="customer_tax_class_id"/> <column name="product_tax_class_id"/> @@ -122,20 +122,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="false" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rate_title_id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_CALCULATION_RATE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_RATE_TITLE_STORE_ID_STORE_STORE_ID" table="tax_calculation_rate_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_37FB965F786AD5897BB3AE90470C42AB" table="tax_calculation_rate_title" + <constraint xsi:type="foreign" referenceId="FK_37FB965F786AD5897BB3AE90470C42AB" table="tax_calculation_rate_title" column="tax_calculation_rate_id" referenceTable="tax_calculation_rate" referenceColumn="tax_calculation_rate_id" onDelete="CASCADE"/> - <index name="TAX_CALCULATION_RATE_TITLE_TAX_CALCULATION_RATE_ID_STORE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TITLE_TAX_CALCULATION_RATE_ID_STORE_ID" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="store_id"/> </index> - <index name="TAX_CALCULATION_RATE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -151,20 +151,20 @@ default="0" comment="Orders Count"/> <column xsi:type="float" name="tax_base_amount_sum" unsigned="false" nullable="true" comment="Tax Base Amount Sum"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" table="tax_order_aggregated_created" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TAX_ORDER_AGGRED_CREATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> + <constraint xsi:type="unique" referenceId="TAX_ORDER_AGGRED_CREATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> <column name="period"/> <column name="store_id"/> <column name="code"/> <column name="percent"/> <column name="order_status"/> </constraint> - <index name="TAX_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> + <index referenceId="TAX_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -181,20 +181,20 @@ default="0" comment="Orders Count"/> <column xsi:type="float" name="tax_base_amount_sum" unsigned="false" nullable="true" comment="Tax Base Amount Sum"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="tax_order_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TAX_ORDER_AGGRED_UPDATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> + <constraint xsi:type="unique" referenceId="TAX_ORDER_AGGRED_UPDATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> <column name="period"/> <column name="store_id"/> <column name="code"/> <column name="percent"/> <column name="order_status"/> </constraint> - <index name="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Theme/etc/db_schema.xml b/app/code/Magento/Theme/etc/db_schema.xml index ee1185e6e576d..7f3a3fc607947 100644 --- a/app/code/Magento/Theme/etc/db_schema.xml +++ b/app/code/Magento/Theme/etc/db_schema.xml @@ -20,7 +20,7 @@ <column xsi:type="smallint" name="type" padding="6" unsigned="false" nullable="false" identity="false" comment="Theme type: 0:physical, 1:virtual, 2:staging"/> <column xsi:type="text" name="code" nullable="true" comment="Full theme code, including package"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="theme_id"/> </constraint> </table> @@ -35,10 +35,10 @@ <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> <column xsi:type="boolean" name="is_temporary" nullable="false" default="false" comment="Is Temporary File"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="theme_files_id"/> </constraint> - <constraint xsi:type="foreign" name="THEME_FILE_THEME_ID_THEME_THEME_ID" table="theme_file" column="theme_id" + <constraint xsi:type="foreign" referenceId="THEME_FILE_THEME_ID_THEME_THEME_ID" table="theme_file" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> </table> <table name="design_change" resource="default" engine="innodb" comment="Design Changes"> @@ -49,12 +49,12 @@ <column xsi:type="varchar" name="design" nullable="true" length="255" comment="Design"/> <column xsi:type="date" name="date_from" comment="First Date of Design Activity"/> <column xsi:type="date" name="date_to" comment="Last Date of Design Activity"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="design_change_id"/> </constraint> - <constraint xsi:type="foreign" name="DESIGN_CHANGE_STORE_ID_STORE_STORE_ID" table="design_change" + <constraint xsi:type="foreign" referenceId="DESIGN_CHANGE_STORE_ID_STORE_STORE_ID" table="design_change" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="DESIGN_CHANGE_STORE_ID" indexType="btree"> + <index referenceId="DESIGN_CHANGE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Translation/etc/db_schema.xml b/app/code/Magento/Translation/etc/db_schema.xml index 523ef3a1279d0..a0d08467acf06 100644 --- a/app/code/Magento/Translation/etc/db_schema.xml +++ b/app/code/Magento/Translation/etc/db_schema.xml @@ -18,12 +18,12 @@ <column xsi:type="varchar" name="locale" nullable="false" length="20" default="en_US" comment="Locale"/> <column xsi:type="bigint" name="crc_string" padding="20" unsigned="false" nullable="false" identity="false" default="1591228201" comment="Translation String CRC32 Hash"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="key_id"/> </constraint> - <constraint xsi:type="foreign" name="TRANSLATION_STORE_ID_STORE_STORE_ID" table="translation" column="store_id" + <constraint xsi:type="foreign" referenceId="TRANSLATION_STORE_ID_STORE_STORE_ID" table="translation" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TRANSLATION_STORE_ID_LOCALE_CRC_STRING_STRING"> + <constraint xsi:type="unique" referenceId="TRANSLATION_STORE_ID_LOCALE_CRC_STRING_STRING"> <column name="store_id"/> <column name="locale"/> <column name="crc_string"/> diff --git a/app/code/Magento/Ui/etc/db_schema.xml b/app/code/Magento/Ui/etc/db_schema.xml index d07329df9eb21..e2a04b0cdc72d 100644 --- a/app/code/Magento/Ui/etc/db_schema.xml +++ b/app/code/Magento/Ui/etc/db_schema.xml @@ -20,12 +20,12 @@ <column xsi:type="longtext" name="config" nullable="true" comment="Bookmark config"/> <column xsi:type="datetime" name="created_at" on_update="false" nullable="false" comment="Bookmark created at"/> <column xsi:type="datetime" name="updated_at" on_update="false" nullable="false" comment="Bookmark updated at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="bookmark_id"/> </constraint> - <constraint xsi:type="foreign" name="UI_BOOKMARK_USER_ID_ADMIN_USER_USER_ID" table="ui_bookmark" + <constraint xsi:type="foreign" referenceId="UI_BOOKMARK_USER_ID_ADMIN_USER_USER_ID" table="ui_bookmark" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="UI_BOOKMARK_USER_ID_NAMESPACE_IDENTIFIER" indexType="btree"> + <index referenceId="UI_BOOKMARK_USER_ID_NAMESPACE_IDENTIFIER" indexType="btree"> <column name="user_id"/> <column name="namespace"/> <column name="identifier"/> diff --git a/app/code/Magento/UrlRewrite/etc/db_schema.xml b/app/code/Magento/UrlRewrite/etc/db_schema.xml index af328873deee7..6e0014873202d 100644 --- a/app/code/Magento/UrlRewrite/etc/db_schema.xml +++ b/app/code/Magento/UrlRewrite/etc/db_schema.xml @@ -23,17 +23,17 @@ <column xsi:type="smallint" name="is_autogenerated" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is rewrite generated automatically flag"/> <column xsi:type="varchar" name="metadata" nullable="true" length="255" comment="Meta data for url rewrite"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="url_rewrite_id"/> </constraint> - <constraint xsi:type="unique" name="URL_REWRITE_REQUEST_PATH_STORE_ID"> + <constraint xsi:type="unique" referenceId="URL_REWRITE_REQUEST_PATH_STORE_ID"> <column name="request_path"/> <column name="store_id"/> </constraint> - <index name="URL_REWRITE_TARGET_PATH" indexType="btree"> + <index referenceId="URL_REWRITE_TARGET_PATH" indexType="btree"> <column name="target_path"/> </index> - <index name="URL_REWRITE_STORE_ID_ENTITY_ID" indexType="btree"> + <index referenceId="URL_REWRITE_STORE_ID_ENTITY_ID" indexType="btree"> <column name="store_id"/> <column name="entity_id"/> </index> diff --git a/app/code/Magento/User/etc/db_schema.xml b/app/code/Magento/User/etc/db_schema.xml index df9b39a27883d..c3356a96b94a7 100644 --- a/app/code/Magento/User/etc/db_schema.xml +++ b/app/code/Magento/User/etc/db_schema.xml @@ -37,10 +37,10 @@ <column xsi:type="timestamp" name="first_failure" on_update="false" nullable="true" comment="First Failure"/> <column xsi:type="timestamp" name="lock_expires" on_update="false" nullable="true" comment="Expiration Lock Dates"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="user_id"/> </constraint> - <constraint xsi:type="unique" name="ADMIN_USER_USERNAME"> + <constraint xsi:type="unique" referenceId="ADMIN_USER_USERNAME"> <column name="username"/> </constraint> </table> @@ -54,12 +54,12 @@ comment="Deprecated"/> <column xsi:type="int" name="last_updated" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Last Updated"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="password_id"/> </constraint> - <constraint xsi:type="foreign" name="ADMIN_PASSWORDS_USER_ID_ADMIN_USER_USER_ID" table="admin_passwords" + <constraint xsi:type="foreign" referenceId="ADMIN_PASSWORDS_USER_ID_ADMIN_USER_USER_ID" table="admin_passwords" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="ADMIN_PASSWORDS_USER_ID" indexType="btree"> + <index referenceId="ADMIN_PASSWORDS_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> diff --git a/app/code/Magento/Variable/etc/db_schema.xml b/app/code/Magento/Variable/etc/db_schema.xml index d89bdb7e710b7..239e3b49983c1 100644 --- a/app/code/Magento/Variable/etc/db_schema.xml +++ b/app/code/Magento/Variable/etc/db_schema.xml @@ -12,10 +12,10 @@ comment="Variable Id"/> <column xsi:type="varchar" name="code" nullable="true" length="255" comment="Variable Code"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Variable Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="variable_id"/> </constraint> - <constraint xsi:type="unique" name="VARIABLE_CODE"> + <constraint xsi:type="unique" referenceId="VARIABLE_CODE"> <column name="code"/> </constraint> </table> @@ -28,18 +28,18 @@ default="0" comment="Store Id"/> <column xsi:type="text" name="plain_value" nullable="true" comment="Plain Text Value"/> <column xsi:type="text" name="html_value" nullable="true" comment="Html Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="unique" name="VARIABLE_VALUE_VARIABLE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="VARIABLE_VALUE_VARIABLE_ID_STORE_ID"> <column name="variable_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="VARIABLE_VALUE_STORE_ID_STORE_STORE_ID" table="variable_value" + <constraint xsi:type="foreign" referenceId="VARIABLE_VALUE_STORE_ID_STORE_STORE_ID" table="variable_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="VARIABLE_VALUE_VARIABLE_ID_VARIABLE_VARIABLE_ID" table="variable_value" + <constraint xsi:type="foreign" referenceId="VARIABLE_VALUE_VARIABLE_ID_VARIABLE_VARIABLE_ID" table="variable_value" column="variable_id" referenceTable="variable" referenceColumn="variable_id" onDelete="CASCADE"/> - <index name="VARIABLE_VALUE_STORE_ID" indexType="btree"> + <index referenceId="VARIABLE_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Vault/etc/db_schema.xml b/app/code/Magento/Vault/etc/db_schema.xml index ed1f2adba2142..c647ea92b091a 100644 --- a/app/code/Magento/Vault/etc/db_schema.xml +++ b/app/code/Magento/Vault/etc/db_schema.xml @@ -24,18 +24,18 @@ <column xsi:type="text" name="details" nullable="true" comment="Details"/> <column xsi:type="boolean" name="is_active" nullable="false" default="true"/> <column xsi:type="boolean" name="is_visible" nullable="false" default="true"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="vault_payment_token" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN"> + <constraint xsi:type="unique" referenceId="VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN"> <column name="payment_method_code"/> <column name="customer_id"/> <column name="gateway_token"/> </constraint> - <constraint xsi:type="unique" name="VAULT_PAYMENT_TOKEN_PUBLIC_HASH"> + <constraint xsi:type="unique" referenceId="VAULT_PAYMENT_TOKEN_PUBLIC_HASH"> <column name="public_hash"/> </constraint> </table> @@ -45,14 +45,14 @@ comment="Order payment Id"/> <column xsi:type="int" name="payment_token_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Payment token Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="order_payment_id"/> <column name="payment_token_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_CF37B9D854256534BE23C818F6291CA2" + <constraint xsi:type="foreign" referenceId="FK_CF37B9D854256534BE23C818F6291CA2" table="vault_payment_token_order_payment_link" column="order_payment_id" referenceTable="sales_order_payment" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_4ED894655446D385894580BECA993862" + <constraint xsi:type="foreign" referenceId="FK_4ED894655446D385894580BECA993862" table="vault_payment_token_order_payment_link" column="payment_token_id" referenceTable="vault_payment_token" referenceColumn="entity_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/Weee/etc/db_schema.xml b/app/code/Magento/Weee/etc/db_schema.xml index 96c3be9740e56..c0a8a3429454f 100644 --- a/app/code/Magento/Weee/etc/db_schema.xml +++ b/app/code/Magento/Weee/etc/db_schema.xml @@ -21,30 +21,30 @@ comment="State"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="WEEE_TAX_COUNTRY_DIRECTORY_COUNTRY_COUNTRY_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_COUNTRY_DIRECTORY_COUNTRY_COUNTRY_ID" table="weee_tax" column="country" referenceTable="directory_country" referenceColumn="country_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_ENTITY_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_ENTITY_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="weee_tax" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="weee_tax" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="weee_tax" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="WEEE_TAX_WEBSITE_ID" indexType="btree"> + <index referenceId="WEEE_TAX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="WEEE_TAX_ENTITY_ID" indexType="btree"> + <index referenceId="WEEE_TAX_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="WEEE_TAX_COUNTRY" indexType="btree"> + <index referenceId="WEEE_TAX_COUNTRY" indexType="btree"> <column name="country"/> </index> - <index name="WEEE_TAX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="WEEE_TAX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> diff --git a/app/code/Magento/Widget/etc/db_schema.xml b/app/code/Magento/Widget/etc/db_schema.xml index 149bb27fcdb2a..a82e6aae20296 100644 --- a/app/code/Magento/Widget/etc/db_schema.xml +++ b/app/code/Magento/Widget/etc/db_schema.xml @@ -14,10 +14,10 @@ comment="Widget code for template directive"/> <column xsi:type="varchar" name="widget_type" nullable="true" length="255" comment="Widget Type"/> <column xsi:type="text" name="parameters" nullable="true" comment="Parameters"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="widget_id"/> </constraint> - <index name="WIDGET_WIDGET_CODE" indexType="btree"> + <index referenceId="WIDGET_WIDGET_CODE" indexType="btree"> <column name="widget_code"/> </index> </table> @@ -32,10 +32,10 @@ <column xsi:type="text" name="widget_parameters" nullable="true" comment="Widget parameters"/> <column xsi:type="smallint" name="sort_order" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Sort order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="instance_id"/> </constraint> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_THEME_ID_THEME_THEME_ID" table="widget_instance" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_THEME_ID_THEME_THEME_ID" table="widget_instance" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> </table> <table name="widget_instance_page" resource="default" engine="innodb" comment="Instance of Widget on Page"> @@ -49,13 +49,13 @@ <column xsi:type="varchar" name="page_for" nullable="true" length="25" comment="For instance entities"/> <column xsi:type="text" name="entities" nullable="true" comment="Catalog entities (comma separated)"/> <column xsi:type="varchar" name="page_template" nullable="true" length="255" comment="Path to widget template"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_INSTANCE_ID_WIDGET_INSTANCE_INSTANCE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_INSTANCE_ID_WIDGET_INSTANCE_INSTANCE_ID" table="widget_instance_page" column="instance_id" referenceTable="widget_instance" referenceColumn="instance_id" onDelete="CASCADE"/> - <index name="WIDGET_INSTANCE_PAGE_INSTANCE_ID" indexType="btree"> + <index referenceId="WIDGET_INSTANCE_PAGE_INSTANCE_ID" indexType="btree"> <column name="instance_id"/> </index> </table> @@ -64,17 +64,17 @@ comment="Page Id"/> <column xsi:type="int" name="layout_update_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Layout Update Id"/> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID_WIDGET_INSTANCE_PAGE_PAGE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID_WIDGET_INSTANCE_PAGE_PAGE_ID" table="widget_instance_page_layout" column="page_id" referenceTable="widget_instance_page" referenceColumn="page_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_LYT_LYT_UPDATE_ID_LYT_UPDATE_LYT_UPDATE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_LYT_LYT_UPDATE_ID_LYT_UPDATE_LYT_UPDATE_ID" table="widget_instance_page_layout" column="layout_update_id" referenceTable="layout_update" referenceColumn="layout_update_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="WIDGET_INSTANCE_PAGE_LAYOUT_LAYOUT_UPDATE_ID_PAGE_ID"> + <constraint xsi:type="unique" referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_LAYOUT_UPDATE_ID_PAGE_ID"> <column name="layout_update_id"/> <column name="page_id"/> </constraint> - <index name="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID" indexType="btree"> + <index referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID" indexType="btree"> <column name="page_id"/> </index> </table> @@ -87,10 +87,10 @@ default="0" comment="Sort Order"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="true" default="0" comment="Last Update Timestamp"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="layout_update_id"/> </constraint> - <index name="LAYOUT_UPDATE_HANDLE" indexType="btree"> + <index referenceId="LAYOUT_UPDATE_HANDLE" indexType="btree"> <column name="handle"/> </index> </table> @@ -105,20 +105,20 @@ default="0" comment="Layout Update Id"/> <column xsi:type="boolean" name="is_temporary" nullable="false" default="false" comment="Defines whether Layout Update is Temporary"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="layout_link_id"/> </constraint> - <constraint xsi:type="foreign" name="LAYOUT_LINK_LAYOUT_UPDATE_ID_LAYOUT_UPDATE_LAYOUT_UPDATE_ID" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_LAYOUT_UPDATE_ID_LAYOUT_UPDATE_LAYOUT_UPDATE_ID" table="layout_link" column="layout_update_id" referenceTable="layout_update" referenceColumn="layout_update_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="LAYOUT_LINK_STORE_ID_STORE_STORE_ID" table="layout_link" column="store_id" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_STORE_ID_STORE_STORE_ID" table="layout_link" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="LAYOUT_LINK_THEME_ID_THEME_THEME_ID" table="layout_link" column="theme_id" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_THEME_ID_THEME_THEME_ID" table="layout_link" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> - <index name="LAYOUT_LINK_LAYOUT_UPDATE_ID" indexType="btree"> + <index referenceId="LAYOUT_LINK_LAYOUT_UPDATE_ID" indexType="btree"> <column name="layout_update_id"/> </index> - <index name="LAYOUT_LINK_STORE_ID_THEME_ID_LAYOUT_UPDATE_ID_IS_TEMPORARY" indexType="btree"> + <index referenceId="LAYOUT_LINK_STORE_ID_THEME_ID_LAYOUT_UPDATE_ID_IS_TEMPORARY" indexType="btree"> <column name="store_id"/> <column name="theme_id"/> <column name="layout_update_id"/> diff --git a/app/code/Magento/Wishlist/etc/db_schema.xml b/app/code/Magento/Wishlist/etc/db_schema.xml index 73fcb7ce0cab4..8a02f411ad0db 100644 --- a/app/code/Magento/Wishlist/etc/db_schema.xml +++ b/app/code/Magento/Wishlist/etc/db_schema.xml @@ -16,16 +16,16 @@ default="0" comment="Sharing flag (0 or 1)"/> <column xsi:type="varchar" name="sharing_code" nullable="true" length="32" comment="Sharing encrypted code"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Last updated date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="wishlist_id"/> </constraint> - <constraint xsi:type="foreign" name="WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="wishlist" + <constraint xsi:type="foreign" referenceId="WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="wishlist" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="WISHLIST_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="WISHLIST_CUSTOMER_ID"> <column name="customer_id"/> </constraint> - <index name="WISHLIST_SHARED" indexType="btree"> + <index referenceId="WISHLIST_SHARED" indexType="btree"> <column name="shared"/> </index> </table> @@ -42,23 +42,23 @@ <column xsi:type="text" name="description" nullable="true" comment="Short description of wish list item"/> <column xsi:type="decimal" name="qty" scale="4" precision="12" unsigned="false" nullable="false" comment="Qty"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="wishlist_item_id"/> </constraint> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID" table="wishlist_item" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID" table="wishlist_item" column="wishlist_id" referenceTable="wishlist" referenceColumn="wishlist_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="wishlist_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_STORE_ID_STORE_STORE_ID" table="wishlist_item" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_STORE_ID_STORE_STORE_ID" table="wishlist_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="WISHLIST_ITEM_WISHLIST_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_WISHLIST_ID" indexType="btree"> <column name="wishlist_id"/> </index> - <index name="WISHLIST_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="WISHLIST_ITEM_STORE_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -71,10 +71,10 @@ comment="Product Id"/> <column xsi:type="varchar" name="code" nullable="false" length="255" comment="Code"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_A014B30B04B72DD0EAB3EECD779728D6" table="wishlist_item_option" + <constraint xsi:type="foreign" referenceId="FK_A014B30B04B72DD0EAB3EECD779728D6" table="wishlist_item_option" column="wishlist_item_id" referenceTable="wishlist_item" referenceColumn="wishlist_item_id" onDelete="CASCADE"/> </table> diff --git a/app/etc/db_schema.xml b/app/etc/db_schema.xml index be13c28ee029b..d7af9091b238d 100644 --- a/app/etc/db_schema.xml +++ b/app/etc/db_schema.xml @@ -10,7 +10,7 @@ <table name="patch_list" resource="default" comment="List of data/schema patches"> <column xsi:type="int" name="patch_id" identity="true" comment="Patch Auto Increment" /> <column xsi:type="varchar" name="patch_name" length="1024" nullable="false" comment="Patch Class Name" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="patch_id" /> </constraint> </table> diff --git a/app/etc/di.xml b/app/etc/di.xml index db979f9b76382..b374645240ff7 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1484,6 +1484,27 @@ </argument> </arguments> </type> + <virtualType name="Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator" type="Magento\Framework\Config\SchemaLocator"> + <arguments> + <argument name="realPath" xsi:type="string">urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Framework\Setup\Declaration\Schema\FileSystem\XmlReader" type="Magento\Framework\Config\Reader\Filesystem"> + <arguments> + <argument name="fileResolver" xsi:type="object">Magento\Framework\Config\FileResolverByModule</argument> + <argument name="converter" xsi:type="object">Magento\Framework\Setup\Declaration\Schema\Config\Converter</argument> + <argument name="schemaLocator" xsi:type="object">Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator</argument> + <argument name="fileName" xsi:type="string">db_schema.xml</argument> + <argument name="idAttributes" xsi:type="array"> + <item name="/schema/table" xsi:type="string">name</item> + <item name="/schema/table/column" xsi:type="string">name</item> + <item name="/schema/table/constraint" xsi:type="string">referenceId</item> + <item name="/schema/table/index" xsi:type="string">referenceId</item> + <item name="/schema/table/index/column" xsi:type="string">name</item> + <item name="/schema/table/constraint/column" xsi:type="string">name</item> + </argument> + </arguments> + </virtualType> <type name="Magento\Framework\Setup\Declaration\Schema\OperationsExecutor"> <arguments> <argument name="operations" xsi:type="array"> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php index ed3f6326cd604..3882afb9f4360 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php @@ -5,6 +5,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Setup\Declaration\Schema\Config; /** @@ -23,7 +25,7 @@ class Converter implements \Magento\Framework\Config\ConverterInterface * @param \DOMDocument $source * @return array */ - public function convert($source) + public function convert($source): array { $output = $this->recursiveConvert($this->getTablesNode($source)); return $output; @@ -37,7 +39,7 @@ public function convert($source) * @param \DOMDocument $element * @return \DOMNodeList */ - private function getTablesNode(\DOMDocument $element) + private function getTablesNode(\DOMDocument $element): \DOMNodeList { return $element->getElementsByTagName('table'); } @@ -48,21 +50,21 @@ private function getTablesNode(\DOMDocument $element) * @param \Traversable $source * @return array */ - private function recursiveConvert(\Traversable $source) + private function recursiveConvert(\Traversable $source): array { $output = []; foreach ($source as $element) { if ($element instanceof \DOMElement) { - $key = $element->getAttribute('name'); + $key = $this->getIdAttributeValue($element); if ($element->hasChildNodes()) { $output[$element->tagName][$key] = array_replace( $this->recursiveConvert($element->childNodes), - $this->interpretateAttributes($element) + $this->interpretAttributes($element) ); - } else if ($this->hasAttributesExceptName($element)) { - $output[$element->tagName][$key] = $this->interpretateAttributes($element); + } elseif ($this->hasAttributesExceptIdAttribute($element)) { + $output[$element->tagName][$key] = $this->interpretAttributes($element); } else { $output[$element->tagName][$key] = $key; } @@ -73,25 +75,48 @@ private function recursiveConvert(\Traversable $source) } /** - * Check whether we have any attributes except name XSI:TYPE is in another namespace. - * Note: name is mandatory attribute. + * Provides the value of the ID attribute for each element. + * + * @param \DOMElement $element + * @return string + */ + private function getIdAttributeValue(\DOMElement $element): string + { + $idAttributeValue = ''; + switch ($element->tagName) { + case ('table'): + case ('column'): + $idAttributeValue = $element->getAttribute('name'); + break; + case ('index'): + case ('constraint'): + $idAttributeValue = $element->getAttribute('referenceId'); + break; + } + + return $idAttributeValue; + } + + /** + * Check whether we have any attributes except ID attribute. * * @param \DOMElement $element * @return bool */ - private function hasAttributesExceptName(\DOMElement $element) + private function hasAttributesExceptIdAttribute(\DOMElement $element) { return $element->hasAttribute('xsi:type') || $element->attributes->length >= 2; } /** * Mix attributes that comes from XML schema with default ones. + * * So if you will not have some attribute in schema - it will be taken from default one. * * @param \DOMElement $domElement - * @return mixed + * @return array */ - private function interpretateAttributes(\DOMElement $domElement) + private function interpretAttributes(\DOMElement $domElement): array { $attributes = $this->getAttributes($domElement); $xsiType = $domElement->getAttribute('xsi:type'); @@ -109,7 +134,7 @@ private function interpretateAttributes(\DOMElement $domElement) * @param \DOMElement $element * @return array */ - private function getAttributes(\DOMElement $element) + private function getAttributes(\DOMElement $element): array { $attributes = []; $attributeNodes = $element->attributes; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php deleted file mode 100644 index 5319c469f0458..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\Setup\Declaration\Schema\Config; - -/** - * This is system class that provides .xsd file for validation XML schema. - */ -class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface -{ - /** - * Path to corresponding XSD file with validation rules for merged config. - * - * @var string - */ - protected $_schema = null; - - /** - * Path to corresponding XSD file with validation rules for separate config files. - * - * @var string - */ - protected $_perFileSchema = null; - - /** - * Constructor. - * - * @param \Magento\Framework\Config\Dom\UrnResolver $urnResolver - * @param string $schemaUrn - */ - public function __construct( - \Magento\Framework\Config\Dom\UrnResolver $urnResolver, - $schemaUrn = 'urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd' - ) { - $this->_schema = $urnResolver->getRealPath($schemaUrn); - $this->_perFileSchema = $this->_schema; - } - - /** - * Get path to merged config schema. - * - * @return string|null - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * Get path to pre file validation schema. - * - * @return string|null - */ - public function getPerFileSchema() - { - return $this->_perFileSchema; - } -} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 830fcb293a8f1..735b8273019f7 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Setup\Declaration\Schema\Declaration; use Magento\Framework\DB\Adapter\AdapterInterface; @@ -19,8 +21,7 @@ use Magento\Framework\Setup\Declaration\Schema\Sharding; /** - * This type of builder is responsible for converting ENTIRE data, that comes from XML - * into DTO`s format, with aggregation root: Schema. + * This type of builder is responsible for converting ENTIRE data, that comes from XML into DTO`s format. * * Note: SchemaBuilder can not be used for one structural element, like column or constraint * because it should have references to other DTO objects. @@ -102,6 +103,7 @@ public function __construct( /** * Add tables data to builder. + * * Tables data holds tables information: columns, constraints, indexes, attributes. * * @param array $tablesData @@ -140,7 +142,7 @@ private function validate(Schema $schema) * @throws Exception * @return Schema */ - public function build(Schema $schema) + public function build(Schema $schema): Schema { foreach ($this->tablesData as $tableData) { if (!$schema->getTableByName($tableData['name'])) { @@ -161,7 +163,7 @@ public function build(Schema $schema) * @param array $tableData * @return string */ - private function getStructuralElementResource(array $tableData) + private function getStructuralElementResource(array $tableData): string { return isset($tableData['resource']) && $this->sharding->canUseResource($tableData['resource']) ? $tableData['resource'] : 'default'; @@ -173,7 +175,7 @@ private function getStructuralElementResource(array $tableData) * @param array $structuralElementData * @return bool */ - private function isDisabled($structuralElementData) + private function isDisabled(array $structuralElementData): bool { return isset($structuralElementData['disabled']) && $this->booleanUtils->toBoolean($structuralElementData['disabled']); @@ -181,14 +183,15 @@ private function isDisabled($structuralElementData) /** * Instantiate column DTO objects from array. + * * If column was renamed new key will be associated to it. * - * @param array $tableData - * @param string $resource - * @param Table $table + * @param array $tableData + * @param string $resource + * @param Table $table * @return array */ - private function processColumns(array $tableData, $resource, Table $table) + private function processColumns(array $tableData, string $resource, Table $table): array { $columns = []; @@ -208,12 +211,12 @@ private function processColumns(array $tableData, $resource, Table $table) /** * Process generic data that is support by all 3 child types: columns, constraints, indexes. * - * @param array $elementData - * @param Table $table - * @param $resource + * @param array $elementData + * @param string $resource + * @param Table $table * @return array */ - private function processGenericData(array $elementData, $resource, Table $table) + private function processGenericData(array $elementData, string $resource, Table $table): array { $elementData['table'] = $table; $elementData['resource'] = $resource; @@ -223,13 +226,14 @@ private function processGenericData(array $elementData, $resource, Table $table) /** * Process tables and add them to schema. + * * If table already exists - then we need to skip it. * * @param Schema $schema - * @param array $tableData - * @return \Magento\Framework\Setup\Declaration\Schema\Dto\Table + * @param array $tableData + * @return Table */ - private function processTable(Schema $schema, array $tableData) + private function processTable(Schema $schema, array $tableData): Table { if (!$schema->getTableByName($tableData['name'])) { $resource = $this->getStructuralElementResource($tableData); @@ -250,11 +254,13 @@ private function processTable(Schema $schema, array $tableData) } /** + * Provides column by name. + * * @param string $columnName * @param Table $table * @return Column */ - private function getColumnByName(string $columnName, Table $table) + private function getColumnByName(string $columnName, Table $table): Column { $columnCandidate = $table->getColumnByName($columnName); @@ -274,7 +280,7 @@ private function getColumnByName(string $columnName, Table $table) * @param Table $table * @return array */ - private function convertColumnNamesToObjects(array $columnNames, Table $table) + private function convertColumnNamesToObjects(array $columnNames, Table $table): array { $columns = []; @@ -288,20 +294,18 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table) /** * Provides the full index name based on the prefix value. * - * @param string $name * @param Table $table * @param array $columns * @param string $type * @return string */ private function getFullIndexName( - string $name, Table $table, array $columns, string $type = AdapterInterface::INDEX_TYPE_INDEX - ) { + ): string { if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { - return $name; + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); } $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); @@ -317,12 +321,12 @@ private function getFullIndexName( /** * Convert and instantiate index objects. * - * @param array $tableData - * @param $resource - * @param Table $table + * @param array $tableData + * @param string $resource + * @param Table $table * @return Index[] */ - private function processIndexes(array $tableData, $resource, Table $table) + private function processIndexes(array $tableData, string $resource, Table $table): array { if (!isset($tableData['index'])) { return []; @@ -345,7 +349,6 @@ private function processIndexes(array $tableData, $resource, Table $table) } $indexData['name'] = $this->getFullIndexName( - $indexData['name'], $table, $indexData['column'], $indexType @@ -363,12 +366,12 @@ private function processIndexes(array $tableData, $resource, Table $table) * Convert and instantiate constraint objects. * * @param array $tableData - * @param $resource + * @param string $resource * @param Schema $schema * @param Table $table * @return Constraint[] */ - private function processConstraints(array $tableData, $resource, Schema $schema, Table $table) + private function processConstraints(array $tableData, string $resource, Schema $schema, Table $table): array { if (!isset($tableData['constraint'])) { return []; @@ -422,7 +425,6 @@ private function processConstraints(array $tableData, $resource, Schema $schema, $constraints[$constraint->getName()] = $constraint; } else { $constraintData['name'] = $this->getFullIndexName( - $constraintData['name'], $table, $constraintData['column'], $constraintData['type'] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php deleted file mode 100644 index bd835c35fd890..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\Setup\Declaration\Schema\FileSystem; - -use Magento\Framework\Config\FileResolverByModule; -use Magento\Framework\Config\ReaderInterface; - -/** - * DB Schema XML configuration reader. - * Reads schema config from db_schema.xml files in enabled modules. - */ -class XmlReader extends \Magento\Framework\Config\Reader\Filesystem implements ReaderInterface -{ - /** - * Attributes by names of which we will do nodes merge. - * - * @var array - */ - private $idAttributes = [ - '/schema/table' => 'name', - '/schema/table/column' => 'name', - '/schema/table/constraint' => 'name', - '/schema/table/index' => 'name', - '/schema/table/index/column' => 'name', - '/schema/table/constraint/column' => 'name', - ]; - - /** - * XmlReader constructor. - * - * @param FileResolverByModule $fileResolver - * @param \Magento\Framework\Setup\Declaration\Schema\Config\Converter $converter - * @param \Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator $schemaLocator - * @param \Magento\Framework\Config\ValidationStateInterface $validationState - * @param string $fileName - * @param string $domDocumentClass - * @param string $defaultScope - */ - public function __construct( - FileResolverByModule $fileResolver, - \Magento\Framework\Setup\Declaration\Schema\Config\Converter $converter, - \Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator $schemaLocator, - \Magento\Framework\Config\ValidationStateInterface $validationState, - $fileName = 'db_schema.xml', - $domDocumentClass = \Magento\Framework\Config\Dom::class, - $defaultScope = 'global' - ) { - parent::__construct( - $fileResolver, - $converter, - $schemaLocator, - $validationState, - $fileName, - $this->idAttributes, - $domDocumentClass, - $defaultScope - ); - } -} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd index 8c264bd95a076..3eed77c37caac 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd @@ -10,6 +10,6 @@ <xs:attributeGroup name="baseConstraint"> <xs:attributeGroup ref="basicOperations" /> - <xs:attribute name="name" type="nameType" use="required" /> + <xs:attribute name="referenceId" type="referenceIdType" use="required" /> </xs:attributeGroup> </xs:schema> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd index ead4fc5604fcb..d6436204a32e5 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd @@ -19,7 +19,7 @@ </xs:sequence> <xs:attribute name="indexType" type="indexType" /> - <xs:attribute name="name" type="nameType" /> + <xs:attribute name="referenceId" type="referenceIdType" /> <xs:attribute name="disabled" type="xs:boolean" /> </xs:complexType> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd index 82db095d66821..dbebdefbda0c2 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd @@ -16,4 +16,18 @@ <xs:maxLength value="64" /> </xs:restriction> </xs:simpleType> + <xs:simpleType name="referenceIdType"> + <xs:union memberTypes="nameType"> + <xs:simpleType> + <xs:annotation> + <xs:documentation> + The attribute can contain only [A-Z0-9_]. + </xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[A-Z0-9_]+" /> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> </xs:schema> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd index 66cd19d051280..54c8f19753070 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd @@ -55,7 +55,7 @@ <xs:element name="constraint" /> <xs:element name="index" type="index" /> </xs:choice> - <xs:attribute name="name" type="xs:string" /> + <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="resource" type="resourceType" /> <xs:attribute name="engine" type="engineType" /> <xs:attribute name="comment" type="xs:string" /> From 3d3b45f384b2166fc86b5d4ec8eb856236336f64 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 19 Oct 2018 18:54:47 +0300 Subject: [PATCH 0677/1415] GraphQL-174: Absolute image paths for Products --- .../Model/Resolver/Product/ProductImage.php | 31 +------ .../Resolver/Product/ProductImage/Label.php | 85 +++++++++++++++++++ .../Resolver/Product/ProductImage/Path.php | 45 ++++++++++ .../Resolver/Product/ProductImage/Url.php | 75 ++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 6 +- 5 files changed, 211 insertions(+), 31 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 3caa79e68c235..d1566162472b0 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -8,7 +8,6 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\ImageFactory; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -19,22 +18,6 @@ */ class ProductImage implements ResolverInterface { - /** - * Product image factory - * - * @var ImageFactory - */ - private $productImageFactory; - - /** - * @param ImageFactory $productImageFactory - */ - public function __construct( - ImageFactory $productImageFactory - ) { - $this->productImageFactory = $productImageFactory; - } - /** * @inheritdoc */ @@ -48,22 +31,14 @@ public function resolve( if (!isset($value['model'])) { throw new LocalizedException(__('"model" value should be specified')); } + /** @var Product $product */ $product = $value['model']; $imageType = $field->getName(); - $imagePath = $product->getData($imageType); - $imageLabel = $product->getData($imageType . '_' . 'label') ?? $product->getName(); - - $image = $this->productImageFactory->create(); - $image->setDestinationSubdir($imageType) - ->setBaseFile($imagePath); - $imageUrl = $image->getUrl(); - return [ - 'url' => $imageUrl, - 'path' => $imagePath, - 'label' => $imageLabel, + 'model' => $product, + 'image_type' => $imageType, ]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php new file mode 100644 index 0000000000000..5b752e7184893 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -0,0 +1,85 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Returns product's image label + */ +class Label implements ResolverInterface +{ + /** + * @var ProductResourceModel + */ + private $productResource; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param ProductResourceModel $productResource + * @param StoreManagerInterface $storeManager + */ + public function __construct( + ProductResourceModel $productResource, + StoreManagerInterface $storeManager + ) { + $this->productResource = $productResource; + $this->storeManager = $storeManager; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + + $imageLabel = $this->getImageLabel((int)$product->getEntityId(), $value['image_type']); + return $imageLabel; + } + + /** + * @param int $productId + * @param string $imageType + * @return string + */ + private function getImageLabel(int $productId, string $imageType): string + { + $storeId = $this->storeManager->getStore()->getId(); + + $imageLabel = $this->productResource->getAttributeRawValue($productId, $imageType . '_label', $storeId); + if (empty($imageLabel)) { + $imageLabel = $this->productResource->getAttributeRawValue($productId, 'name', $storeId); + } + return $imageLabel; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php new file mode 100644 index 0000000000000..249f1dc40b19a --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Returns product's image path + */ +class Path implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + + $imagePath = $product->getData($value['image_type']); + return $imagePath; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php new file mode 100644 index 0000000000000..d9136e742b178 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\ImageFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Returns product's image url + */ +class Url implements ResolverInterface +{ + /** + * @var ImageFactory + */ + private $productImageFactory; + + /** + * @param ImageFactory $productImageFactory + */ + public function __construct( + ImageFactory $productImageFactory + ) { + $this->productImageFactory = $productImageFactory; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + $imagePath = $product->getData($value['image_type']); + + $imageUrl = $this->getImageUrl($value['image_type'], $imagePath); + return $imageUrl; + } + + /** + * @param string $imageType + * @param string $imagePath + * @return string + */ + private function getImageUrl(string $imageType, string $imagePath): string + { + $image = $this->productImageFactory->create(); + $image->setDestinationSubdir($imageType) + ->setBaseFile($imagePath); + $imageUrl = $image->getUrl(); + return $imageUrl; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f87e524a26b3f..fb042c7e59c15 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -350,9 +350,9 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the } type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { - url: String - path: String - label: String + url: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Url") + path: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Path") + label: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Label") } interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { From 93a2d716bf351f5ac48ba9b8bec000596eb6dc6b Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Fri, 19 Oct 2018 11:02:58 -0500 Subject: [PATCH 0678/1415] MAGETWO-95391: Widget Escaping - Add suppression for new block aware rule --- app/code/Magento/Widget/Block/Adminhtml/Widget.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget.php b/app/code/Magento/Widget/Block/Adminhtml/Widget.php index dad318f163b4b..33e6109b769db 100644 --- a/app/code/Magento/Widget/Block/Adminhtml/Widget.php +++ b/app/code/Magento/Widget/Block/Adminhtml/Widget.php @@ -16,6 +16,8 @@ class Widget extends \Magento\Backend\Block\Widget\Form\Container { /** * @inheritdoc + * + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ protected function _construct() { From a02ba47637dfce624ee0afceeed6c2851fa85c13 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 14:36:14 -0500 Subject: [PATCH 0679/1415] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- .../Model/Resolver/Products/Query/Search.php | 17 +++++- app/code/Magento/Elasticsearch/etc/di.xml | 8 +++ .../Magento/GraphQl/Controller/GraphQl.php | 1 + .../Search/Model/Search/PageSizeProvider.php | 53 ++++++++++++++++ .../Model/Search/PageSizeProviderTest.php | 61 +++++++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Search/Model/Search/PageSizeProvider.php create mode 100644 app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php index c4da59fd2cedf..80d65e96625e8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -12,7 +12,6 @@ use Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\Helper\Filter as FilterHelper; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResultFactory; -use Magento\Framework\EntityManager\EntityManager; use Magento\Search\Api\SearchInterface; /** @@ -45,31 +44,42 @@ class Search */ private $metadataPool; + /** + * @var \Magento\CatalogSearch\Model\Search\PageSizeProvider + */ + private $pageSizeProvider; + /** * @param SearchInterface $search * @param FilterHelper $filterHelper * @param Filter $filterQuery * @param SearchResultFactory $searchResultFactory + * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool + * @param \Magento\Search\Model\Search\PageSizeProvider $pageSize */ public function __construct( SearchInterface $search, FilterHelper $filterHelper, Filter $filterQuery, SearchResultFactory $searchResultFactory, - \Magento\Framework\EntityManager\MetadataPool $metadataPool + \Magento\Framework\EntityManager\MetadataPool $metadataPool, + \Magento\Search\Model\Search\PageSizeProvider $pageSize ) { $this->search = $search; $this->filterHelper = $filterHelper; $this->filterQuery = $filterQuery; $this->searchResultFactory = $searchResultFactory; $this->metadataPool = $metadataPool; + $this->pageSizeProvider = $pageSize; } /** * Return results of full text catalog search of given term, and will return filtered results if filter is specified * * @param SearchCriteriaInterface $searchCriteria + * @param ResolveInfo $info * @return SearchResult + * @throws \Exception */ public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $info) : SearchResult { @@ -79,7 +89,8 @@ public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $ $realPageSize = $searchCriteria->getPageSize(); $realCurrentPage = $searchCriteria->getCurrentPage(); // Current page must be set to 0 and page size to max for search to grab all ID's as temporary workaround - $searchCriteria->setPageSize(PHP_INT_MAX); + $pageSize = $this->pageSizeProvider->getMaxPageSize(); + $searchCriteria->setPageSize($pageSize); $searchCriteria->setCurrentPage(0); $itemsResults = $this->search->search($searchCriteria); diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 0cfaba845fd6a..3ce2639674d8b 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -271,4 +271,12 @@ </argument> </arguments> </type> + <type name="Magento\Search\Model\Search\PageSizeProvider"> + <arguments> + <argument name="pageSizeBySearchEngine" xsi:type="array"> + <item name="elasticsearch" xsi:type="number">2147483647</item> + <item name="elasticsearch5" xsi:type="number">2147483647</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index c4a0b55de9bfc..fecbf9c430f54 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,6 +108,7 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); + //\Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->critical($request->getContent()); $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; diff --git a/app/code/Magento/Search/Model/Search/PageSizeProvider.php b/app/code/Magento/Search/Model/Search/PageSizeProvider.php new file mode 100644 index 0000000000000..43e20aae8e697 --- /dev/null +++ b/app/code/Magento/Search/Model/Search/PageSizeProvider.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Search\Model\Search; + +/** + * Returns max page size by search engine name + */ +class PageSizeProvider +{ + /** + * @var \Magento\Search\Model\EngineResolver + */ + private $engineResolver; + + /** + * @var array + */ + private $pageSizeBySearchEngine; + + /** + * @param \Magento\Search\Model\EngineResolver $engineResolver + * @param array $pageSizeBySearchEngine + */ + public function __construct( + \Magento\Search\Model\EngineResolver $engineResolver, + array $pageSizeBySearchEngine = [] + ) { + $this->engineResolver = $engineResolver; + $this->pageSizeBySearchEngine = $pageSizeBySearchEngine; + } + + /** + * Returns max_page_size depends on engine + * + * @return integer + */ + public function getMaxPageSize() : int + { + $searchEngine = $this->engineResolver->getCurrentSearchEngine(); + + $pageSize = PHP_INT_MAX; + if (isset($this->pageSizeBySearchEngine[$searchEngine])) { + $pageSize = $this->pageSizeBySearchEngine[$searchEngine]; + } + + return (int)$pageSize; + } +} diff --git a/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php b/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php new file mode 100644 index 0000000000000..982d00bd9f648 --- /dev/null +++ b/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Search\Test\Unit\Model\Search; + +use Magento\Search\Model\Search\PageSizeProvider; + +class PageSizeProviderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var PageSizeProvider + */ + private $model; + + /** + * @var \Magento\Search\Model\EngineResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $pageSizeBySearchEngineMock; + + public function setUp() + { + $this->pageSizeBySearchEngineMock = $this->getMockBuilder(\Magento\Search\Model\EngineResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new PageSizeProvider( + + $this->pageSizeBySearchEngineMock, + ['search' => 10, + 'catalogSearch3' => 11 + ] + ); + } + + /** + * @param string $searchEngine + * @param int $size + * @dataProvider getPageSizeDataProvider + */ + public function testGetPageSize($searchEngine, $size) + { + $this->pageSizeBySearchEngineMock + ->expects($this->once()) + ->method('getCurrentSearchEngine') + ->willReturn($searchEngine); + $this->assertEquals($size, $this->model->getMaxPageSize()); + } + + public function getPageSizeDataProvider() + { + return [ + ['search', 10], + ['catalogSearch3', 11], + ['newSearch', PHP_INT_MAX] + ]; + } +} From 6f6fd69f1cf86976ed3dab7208d578c513deddfd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 19 Oct 2018 11:25:09 -0500 Subject: [PATCH 0680/1415] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- app/code/Magento/GraphQl/Controller/GraphQl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index fecbf9c430f54..d957f394ee714 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,7 +108,7 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); - //\Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->critical($request->getContent()); + $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; From 61453702309784edb31ec24b595986c5cf3d062e Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 19 Oct 2018 11:31:23 -0500 Subject: [PATCH 0681/1415] MQE-1187: Fix MFTF skipped tests - Removing AdminGWS features from actionGroup --- .../User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml index b1ac0820923d9..14f41cefa7d01 100644 --- a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml @@ -18,20 +18,15 @@ <actionGroup name="AdminCreateRole"> <arguments> <argument name="role" type="string" defaultValue=""/> - <argument name="resource" type="string" defaultValue="All"/> <argument name="scope" type="string" defaultValue="Custom"/> - <argument name="websites" type="string" defaultValue="Main Website"/> </arguments> <click selector="{{AdminCreateRoleSection.create}}" stepKey="clickToAddNewRole"/> <fillField selector="{{AdminCreateRoleSection.name}}" userInput="{{role.name}}" stepKey="setRoleName"/> <fillField stepKey="setPassword" selector="{{AdminCreateRoleSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> <click selector="{{AdminCreateRoleSection.roleResources}}" stepKey="clickToOpenRoleResources"/> <waitForPageLoad stepKey="waitForRoleResourcePage" time="5"/> - <click selector="{{AdminCreateRoleSection.roleResource}}" stepKey="clickToExpandResourceAccess"/> - <click selector="{{AdminCreateRoleSection.resourceValue(scope)}}" stepKey="clickToSelectResourceAccess"/> <click selector="{{AdminCreateRoleSection.roleScope}}" stepKey="clickToExpandScopeAccess"/> <click selector="{{AdminCreateRoleSection.scopeValue(resource)}}" stepKey="clickToSelectScopeAccess"/> - <click selector="{{AdminCreateRoleSection.website(websites)}}" stepKey="clickToSelectWebsite"/> <click selector="{{AdminCreateRoleSection.save}}" stepKey="clickToSaveRole"/> <waitForPageLoad stepKey="waitForPageLoad" time="10"/> <see userInput="You saved the role." stepKey="seeSuccessMessage" /> From 43f94172453d1b714884825431f6df9c9aba63d4 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 11:38:28 -0500 Subject: [PATCH 0682/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../etc/db_schema.xml | 10 +++++----- .../revisions/base_update/db_schema.xml | 8 ++++---- .../revisions/before_rollback/db_schema.xml | 2 +- .../column_modifications/db_schema.xml | 10 +++++----- .../revisions/column_removals/db_schema.xml | 10 +++++----- .../constraint_modifications/db_schema.xml | 18 +++++++++--------- .../revisions/drop_table/db_schema.xml | 2 +- .../foreign_key_interpreter/db_schema.xml | 2 +- .../revisions/old_diff/db_schema.xml | 8 ++++---- .../etc/db_schema.xml | 6 +++--- .../etc/db_schema.xml | 2 +- .../remove_title_column/db_schema.xml | 2 +- .../restore_title_column/db_schema.xml | 2 +- .../etc/db_schema.xml | 6 +++--- .../etc/db_schema.xml | 10 +++++----- .../db_schema.xml | 4 ++-- .../invalid_primary_key/db_schema.xml | 2 +- 17 files changed, 52 insertions(+), 52 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 5b8a4c8f37c99..1c4e7b6b6da97 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml index 7384c4ed7baab..af66686e77b42 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="reference_table" resource="default" comment="Reference table"> <column xsi:type="smallint" name="smallint_ref" padding="6" nullable="false" unsigned="false" identity="true" comment="Smallint"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="smallint_ref"/> </constraint> </table> @@ -22,14 +22,14 @@ <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> <column xsi:type="boolean" name="boolean" comment="Boolean"/> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="smallint" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <index name="TEST_TABLE_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_BIGINT" indexType="btree"> <column name="bigint"/> </index> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml index 4d3d51b9c0237..8c42f9efd129a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml @@ -20,7 +20,7 @@ <table name="store_owner" comment="Store owner information" engine="innodb" resource="default"> <column name="owner_id" xsi:type="smallint" nullable="false" unsigned="false" identity="true" /> <column name="store_owner_name" onCreate="migrateDataFrom(label)" xsi:type="varchar" length="255" comment="Store Owner Name" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="owner_id" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml index 0adcd5c52f962..4f9a5ab6d5a92 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="123" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" nullable="false" unsigned="false"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -29,7 +29,7 @@ <column xsi:type="int" name="int_auto_increment_with_nullable" padding="15" unsigned="true" nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -52,15 +52,15 @@ <column xsi:type="boolean" name="boolean" default="true"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml index 4b78f436eab37..a3c4fe010fd35 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml @@ -20,14 +20,14 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> <table name="auto_increment_test" resource="default"> <column xsi:type="int" name="int_auto_increment_with_nullable" identity="true" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -50,15 +50,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="false"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml index 68f2810e8eed7..93e6e13eb36f8 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml @@ -22,11 +22,11 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> <column name="smallint_ref"/> </constraint> - <constraint xsi:type="unique" name="REFERENCE_TABLE_SMALLINT_REF"> + <constraint xsi:type="unique" referenceId="REFERENCE_TABLE_SMALLINT_REF"> <column name="smallint_ref"/> </constraint> </table> @@ -35,7 +35,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -60,23 +60,23 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_FLOAT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_FLOAT"> <column name="smallint"/> <column name="float"/> </constraint> - <constraint xsi:type="unique" name="TEST_TABLE_DOUBLE"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_DOUBLE"> <column name="double"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key_new" column="smallint_main" table="test_table" + <constraint xsi:type="foreign" referenceId="some_foreign_key_new" column="smallint_main" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="FK_FB77604C299EB8612D01E4AF8D9931F2" + <constraint xsi:type="foreign" referenceId="FK_FB77604C299EB8612D01E4AF8D9931F2" column="integer_main" table="test_table" referenceTable="auto_increment_test" referenceColumn="int_auto_increment_with_nullable"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml index 0a0131e500641..8a73d9e225546 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml @@ -12,7 +12,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml index e4a5ca05d02fe..479c4c87f6143 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml @@ -12,7 +12,7 @@ </table> <table name="test_table" resource="default"> <column xsi:type="tinyint" name="tinyint" default="0" padding="7" nullable="true" unsigned="false"/> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref"/> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml index 6b92440ca92f5..1347a1ba8e3b1 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="reference_table" resource="default" comment="Reference table"> <column xsi:type="smallint" name="smallint_ref" padding="6" nullable="false" unsigned="false" identity="true" comment="Smallint"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="smallint_ref"/> </constraint> </table> @@ -22,14 +22,14 @@ <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> <column xsi:type="boolean" name="boolean" comment="Boolean"/> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="smallint" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <index name="TEST_TABLE_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_BIGINT" indexType="btree"> <column name="bigint"/> </index> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml index b6ff634e6ef1d..9bd6c438455b2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> <column xsi:type="int" name="some_integer" default="0" nullable="false" unsigned="false"/> <column xsi:type="varchar" name="for_patch_testing" comment="For patch testing" /> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="smallint" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml index 4520cd9e4d406..8082157524ad4 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml index 9d868c0168826..0eeff4174870a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml @@ -10,7 +10,7 @@ <table name="test_table" resource="default" comment="Test Table"> <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml index 4520cd9e4d406..8082157524ad4 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml index b6ff634e6ef1d..9bd6c438455b2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> <column xsi:type="int" name="some_integer" default="0" nullable="false" unsigned="false"/> <column xsi:type="varchar" name="for_patch_testing" comment="For patch testing" /> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="smallint" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml index 9263004c6e7f6..d6be9376cb4da 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml index e39f0a04bcf5f..1b7d0dcb93ce7 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml @@ -9,13 +9,13 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="test_table" resource="default" comment="Test Table"> <column xsi:type="int" name="page_id" nullable="false" unsigned="false" identity="true"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> </table> <table name="dependent" resource="default" comment="Lol"> <column xsi:type="int" name="page_id_on" nullable="true" unsigned="true"/> - <constraint xsi:type="foreign" name="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" referenceTable="test_table"/> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml index 4ecee62286418..b42d74aea06a1 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" identity="true" /> <column xsi:type="varchar" name="email" nullable="true" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> From 456b72e7be3b11d129300651668850442df113ad Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 19 Oct 2018 11:40:38 -0500 Subject: [PATCH 0683/1415] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- .../CatalogGraphQl/Model/Resolver/Products/Query/Search.php | 2 +- app/code/Magento/GraphQl/Controller/GraphQl.php | 1 - app/code/Magento/Search/Model/Search/PageSizeProvider.php | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php index 80d65e96625e8..f9b64f3a3c69b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -45,7 +45,7 @@ class Search private $metadataPool; /** - * @var \Magento\CatalogSearch\Model\Search\PageSizeProvider + * @var \Magento\Search\Model\Search\PageSizeProvider */ private $pageSizeProvider; diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index d957f394ee714..c4a0b55de9bfc 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,7 +108,6 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); - $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; diff --git a/app/code/Magento/Search/Model/Search/PageSizeProvider.php b/app/code/Magento/Search/Model/Search/PageSizeProvider.php index 43e20aae8e697..5572bac6addc3 100644 --- a/app/code/Magento/Search/Model/Search/PageSizeProvider.php +++ b/app/code/Magento/Search/Model/Search/PageSizeProvider.php @@ -9,6 +9,7 @@ /** * Returns max page size by search engine name + * @api */ class PageSizeProvider { From c366d477010c08e2c9ffdbe09edcd61b1082efa2 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 19 Oct 2018 19:59:59 +0300 Subject: [PATCH 0684/1415] GraphQL-174: Absolute image paths for Products --- .../Resolver/Product/ProductImage/Label.php | 27 ++++++++++++------- .../Resolver/Product/ProductImage/Url.php | 4 +-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php index 5b752e7184893..e9020c2df5333 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -62,24 +62,33 @@ public function resolve( /** @var Product $product */ $product = $value['model']; + $imageType = $value['image_type']; + $imagePath = $product->getData($imageType); + $productId = (int)$product->getEntityId(); + + // null if image is not set + if (null === $imagePath) { + return $this->getAttributeValue($productId, 'name'); + } + + $imageLabel = $this->getAttributeValue($productId, $imageType . '_label'); + if (null === $imageLabel) { + $imageLabel = $this->getAttributeValue($productId, 'name'); + } - $imageLabel = $this->getImageLabel((int)$product->getEntityId(), $value['image_type']); return $imageLabel; } /** * @param int $productId - * @param string $imageType - * @return string + * @param string $attributeCode + * @return null|string Null if attribute value is not exists */ - private function getImageLabel(int $productId, string $imageType): string + private function getAttributeValue(int $productId, string $attributeCode): ?string { $storeId = $this->storeManager->getStore()->getId(); - $imageLabel = $this->productResource->getAttributeRawValue($productId, $imageType . '_label', $storeId); - if (empty($imageLabel)) { - $imageLabel = $this->productResource->getAttributeRawValue($productId, 'name', $storeId); - } - return $imageLabel; + $value = $this->productResource->getAttributeRawValue($productId, $attributeCode, $storeId); + return is_array($value) && empty($value) ? null : $value; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php index d9136e742b178..c6659080ee9e9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -61,10 +61,10 @@ public function resolve( /** * @param string $imageType - * @param string $imagePath + * @param string|null $imagePath Null if image is not set * @return string */ - private function getImageUrl(string $imageType, string $imagePath): string + private function getImageUrl(string $imageType, ?string $imagePath): string { $image = $this->productImageFactory->create(); $image->setDestinationSubdir($imageType) From bc4800a0ae383ab5043078cf6e9c14608cb0b44d Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:13:12 -0500 Subject: [PATCH 0685/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../unpatterned_fk_name/db_schema.xml | 32 +++++++++++++++++++ dev/tests/setup-integration/phpunit.xml.dist | 6 ++-- .../Setup/DeclarativeInstallerTest.php | 21 ++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml new file mode 100644 index 0000000000000..f5b6d13c3cbe4 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default" comment="Test Table"> + <column xsi:type="int" name="page_id" nullable="false" unsigned="false" identity="true"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="page_id"/> + </constraint> + </table> + <table name="test_scope_table" resource="default" comment="Test Scope Table"> + <column xsi:type="int" name="scope_id" nullable="false" unsigned="false" identity="true"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="scope_id"/> + </constraint> + </table> + <table name="dependent" resource="default" comment="Lol"> + <column xsi:type="int" name="page_id_on" nullable="false" unsigned="false"/> + <column xsi:type="int" name="scope_id_on" nullable="false" unsigned="false"/> + <!-- Expected name in DB: DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID --> + <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + referenceTable="test_table"/> + <!-- Expected name in DB: DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID --> + <constraint xsi:type="foreign" referenceId="ScopeIDOnTOScopeTableAndScopeId" table="dependent" column="scope_id_on" referenceColumn="scope_id" + referenceTable="test_scope_table"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/phpunit.xml.dist b/dev/tests/setup-integration/phpunit.xml.dist index 7dd8609bdcadf..04f8872557e58 100644 --- a/dev/tests/setup-integration/phpunit.xml.dist +++ b/dev/tests/setup-integration/phpunit.xml.dist @@ -32,11 +32,11 @@ <includePath>testsuite</includePath> <ini name="date.timezone" value="America/Los_Angeles"/> <ini name="xdebug.max_nesting_level" value="200"/> - <const name="TESTS_INSTALL_CONFIG_FILE" value="{{local_config_file}}"/> + <const name="TESTS_INSTALL_CONFIG_FILE" value="etc/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="etc/config-global.php"/> <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <const name="TESTS_CLEANUP" value="{{tests_cleanup}}"/> - <const name="TESTS_MAGENTO_MODE" value="{{app_mode}}"/> + <const name="TESTS_CLEANUP" value="enabled"/> + <const name="TESTS_MAGENTO_MODE" value="developer"/> <const name="TESTS_ERROR_LOG_LISTENER_LEVEL" value="1"/> </php> <!-- Test listeners --> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 34d432e566fec..33f4b170637c2 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -296,4 +296,25 @@ public function testTableRename() ->from($this->resourceConnection->getTableName('some_table_renamed')); self::assertEquals([$dataToMigrate], $adapter->fetchAll($select)); } + + /** + * @moduleName Magento_TestSetupDeclarationModule8 + */ + public function testForeignKeyReferenceId() + { + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule8'] + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'unpatterned_fk_name', + 'db_schema.xml', + 'etc' + ); + $this->cliCommad->upgrade(); + $tableStatements = $this->describeTable->describeShard('default'); + $tableSql = $tableStatements['dependent']; + $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID`/', $tableSql); + $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID`/', $tableSql); + } } From bcd2f80e68cc86ac1aba0dd2a3e243f3b1fc591b Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Fri, 19 Oct 2018 12:24:08 -0500 Subject: [PATCH 0686/1415] MAGETWO-95636: Upload Extension Validation - Align messaging of exception with existing validation --- .../Magento/CatalogImportExport/Model/Import/Uploader.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index cca31b97e6b6d..087a12452bef4 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -177,9 +177,7 @@ public function move($fileName, $renameFileOff = false) $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION); if ($fileExtension && !$this->checkAllowedExtension($fileExtension)) { - throw new \Magento\Framework\Exception\LocalizedException( - __('File extension \'%1\' is not a supported upload type', $fileExtension) - ); + throw new \Magento\Framework\Exception\LocalizedException(__('Disallowed file type.')); } $fileName = preg_replace('/[^a-z0-9\._-]+/i', '', $fileName); From ff756d7ce6aa201017997ec9e4c16f64ca90021a Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:44:56 -0500 Subject: [PATCH 0687/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../revisions/unpatterned_fk_name/db_schema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml index f5b6d13c3cbe4..eebeb154adf43 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml @@ -23,7 +23,7 @@ <column xsi:type="int" name="page_id_on" nullable="false" unsigned="false"/> <column xsi:type="int" name="scope_id_on" nullable="false" unsigned="false"/> <!-- Expected name in DB: DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID --> - <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + <constraint xsi:type="foreign" referenceId="DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID" table="dependent" column="page_id_on" referenceColumn="page_id" referenceTable="test_table"/> <!-- Expected name in DB: DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID --> <constraint xsi:type="foreign" referenceId="ScopeIDOnTOScopeTableAndScopeId" table="dependent" column="scope_id_on" referenceColumn="scope_id" From 909d777526fed8378b33f08a99e2935d34dce9ab Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:46:42 -0500 Subject: [PATCH 0688/1415] MAGETWO-95595: Index names are ignored by declarative schema --- dev/tests/setup-integration/phpunit.xml.dist | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/setup-integration/phpunit.xml.dist b/dev/tests/setup-integration/phpunit.xml.dist index 04f8872557e58..7dd8609bdcadf 100644 --- a/dev/tests/setup-integration/phpunit.xml.dist +++ b/dev/tests/setup-integration/phpunit.xml.dist @@ -32,11 +32,11 @@ <includePath>testsuite</includePath> <ini name="date.timezone" value="America/Los_Angeles"/> <ini name="xdebug.max_nesting_level" value="200"/> - <const name="TESTS_INSTALL_CONFIG_FILE" value="etc/install-config-mysql.php"/> + <const name="TESTS_INSTALL_CONFIG_FILE" value="{{local_config_file}}"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="etc/config-global.php"/> <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <const name="TESTS_CLEANUP" value="enabled"/> - <const name="TESTS_MAGENTO_MODE" value="developer"/> + <const name="TESTS_CLEANUP" value="{{tests_cleanup}}"/> + <const name="TESTS_MAGENTO_MODE" value="{{app_mode}}"/> <const name="TESTS_ERROR_LOG_LISTENER_LEVEL" value="1"/> </php> <!-- Test listeners --> From 228660dea739c63288a26e3a8de431e8f1a5f44d Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 21:07:16 +0300 Subject: [PATCH 0689/1415] Cover \Magento\Email\Model\Template\SenderResolver class with Unit test --- .../Model/Template/SenderResolverTest.php | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php diff --git a/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php b/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php new file mode 100644 index 0000000000000..fb25290f9d27b --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\Test\Unit\Model\Template; + +use Magento\Email\Model\Template\SenderResolver; +use Magento\Framework\Exception\MailException; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * SenderResolverTest + */ +class SenderResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SenderResolver + */ + private $senderResolver; + + /** + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfig; + + /** + * @return void + */ + public function setUp(): void + { + $objectManager = new ObjectManager($this); + + $this->scopeConfig = $this->createMock(ScopeConfigInterface::class); + + $this->senderResolver = $objectManager->getObject( + SenderResolver::class, + [ + 'scopeConfig' => $this->scopeConfig + ] + ); + } + + /** + * Test returned information for given sender's name and email + * + * @return void + */ + public function testResolve(): void + { + $sender = 'general'; + $scopeId = null; + + $this->scopeConfig->expects($this->exactly(2)) + ->method('getValue') + ->willReturnMap([ + [ + 'trans_email/ident_' . $sender . '/name', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $scopeId, + 'Test Name' + ], + [ + 'trans_email/ident_' . $sender . '/email', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $scopeId, + 'test@email.com' + ] + ]); + + $result = $this->senderResolver->resolve($sender); + + $this->assertTrue(isset($result['name'])); + $this->assertEquals('Test Name', $result['name']); + + $this->assertTrue(isset($result['email'])); + $this->assertEquals('test@email.com', $result['email']); + } + + /** + * Test if exception is thrown in case there is no name or email in result + * + * @dataProvider dataProvidedSenderArray + * @param array $sender + * + * @return void + */ + public function testResolveThrowException(array $sender): void + { + $this->expectExceptionMessage('Invalid sender data'); + $this->expectException(MailException::class); + $this->senderResolver->resolve($sender); + } + + /** + * @return array + */ + public function dataProvidedSenderArray() + { + return [ + [ + ['name' => 'Name'] + ], + [ + ['email' => 'test@email.com'] + ] + ]; + } +} From 1872979e49cb60dd7ea3927dddd9a19ff29d52d3 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 09:51:12 +0300 Subject: [PATCH 0690/1415] Added Unit Test for WindowsSmtpConfig Plugin --- .../Model/Plugin/WindowsSmtpConfigTest.php | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php diff --git a/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php b/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php new file mode 100644 index 0000000000000..5f7c44b988c66 --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\Test\Unit\Model\Plugin; + +use Magento\Email\Model\Plugin\WindowsSmtpConfig; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\Mail\TransportInterface; +use Magento\Framework\OsInfo; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * WindowsSmtpConfigTest + */ +class WindowsSmtpConfigTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var WindowsSmtpConfig + */ + private $windowsSmtpConfig; + + /** + * @var OsInfo|\PHPUnit_Framework_MockObject_MockObject + */ + private $osInfoMock; + + /** + * @var ReinitableConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var TransportInterface + */ + private $transportMock; + + /** + * setUp + * + * @return void + */ + public function setUp(): void + { + $objectManager = new ObjectManager($this); + + $this->osInfoMock = $this->createMock(OsInfo::class); + $this->configMock = $this->createMock(ReinitableConfigInterface::class); + $this->transportMock = $this->createMock(TransportInterface::class); + + $this->windowsSmtpConfig = $objectManager->getObject( + WindowsSmtpConfig::class, + [ + 'config' => $this->configMock, + 'osInfo' => $this->osInfoMock + ] + ); + } + + /** + * Test if SMTP settings if windows server + * + * @return void + */ + public function testBeforeSendMessageOsWindows(): void + { + $this->osInfoMock->expects($this->once()) + ->method('isWindows') + ->willReturn(true); + + $this->configMock->expects($this->exactly(2)) + ->method('getValue') + ->willReturnMap([ + [WindowsSmtpConfig::XML_SMTP_HOST, '127.0.0.1'], + [WindowsSmtpConfig::XML_SMTP_PORT, '80'] + ]); + + $this->windowsSmtpConfig->beforeSendMessage($this->transportMock); + } + + /** + * Test if SMTP settings if not windows server + * + * @return void + */ + public function testBeforeSendMessageOsIsWindows(): void + { + $this->osInfoMock->expects($this->once()) + ->method('isWindows') + ->willReturn(false); + + $this->configMock->expects($this->never()) + ->method('getValue'); + + $this->windowsSmtpConfig->beforeSendMessage($this->transportMock); + } +} From fef2205724afcacfa8b9b4243a228d5b37c0f395 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 19 Oct 2018 13:30:11 -0500 Subject: [PATCH 0691/1415] Issue magento/magento2#17830: Add checkout_cart_product_add_before event - fixed broken unit test --- app/code/Magento/Checkout/Test/Unit/Model/CartTest.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php index a862fbb1306e9..bc66324c2986d 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php @@ -370,7 +370,7 @@ public function testAddProductException() ->method('getById') ->will($this->returnValue($product)); - $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + $this->eventManagerMock->expects($this->once())->method('dispatch')->with( 'checkout_cart_product_add_before', ['info' => 4, 'product' => $product] ); @@ -382,10 +382,6 @@ public function testAddProductException() ->method('getQuote') ->will($this->returnValue($this->quoteMock)); - $this->eventManagerMock->expects($this->never())->method('dispatch')->with( - 'checkout_cart_product_add_after', - ['quote_item' => 1, 'product' => $product] - ); $this->expectException(\Magento\Framework\Exception\LocalizedException::class); $this->cart->addProduct(4, 4); } From 0de795a668d63b89327b19cc8df43e97ee4a7cf7 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 19 Oct 2018 13:37:30 -0500 Subject: [PATCH 0692/1415] Issue magento/magento2#17830: Add checkout_cart_product_add_before event - fixed broken static test --- app/code/Magento/Checkout/Model/Cart.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index c43adde2f192a..eff07af0e6a3e 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -619,6 +619,8 @@ public function truncate() } /** + * Get product ids. + * * @return int[] */ public function getProductIds() From 2064e2417b53232257a4a49db18980f0d0c34d12 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 22:03:15 +0300 Subject: [PATCH 0693/1415] Cover \Magento\GiftMessage\Observer\SalesEventQuoteMerge with Unit test --- .../Observer/SalesEventQuoteMergeTest.php | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php diff --git a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php new file mode 100644 index 0000000000000..f82bc01c485e9 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\GiftMessage\Test\Unit\Observer; + +use Magento\GiftMessage\Observer\SalesEventQuoteMerge; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use \Magento\Framework\Event\Observer; +use Magento\Quote\Model\Quote; + +/** + * SalesEventQuoteMergeTest + */ +class SalesEventQuoteMergeTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var SalesEventQuoteMerge + */ + private $salesEventQuoteMerge; + + /** + * @return void + */ + public function setUp(): void + { + $objectManger = new ObjectManager($this); + $this->salesEventQuoteMerge = $objectManger->getObject(SalesEventQuoteMerge::class); + } + + /** + * @dataProvider dataProviderGiftMessageId + * + * @param null|int $giftMessageId + * + * @return void + */ + public function testExecute($giftMessageId): void + { + $sourceQuoteMock = $this->createPartialMock(Quote::class, ['getGiftMessageId']); + $sourceQuoteMock->expects($this->once()) + ->method('getGiftMessageId') + ->willReturn($giftMessageId); + + $targetQuoteMock = $this->createPartialMock(Quote::class, ['setGiftMessageId']); + + if ($giftMessageId) { + $targetQuoteMock->expects($this->once()) + ->method('setGiftMessageId'); + } else { + $targetQuoteMock->expects($this->never()) + ->method('setGiftMessageId'); + } + + $observer = $this->createMock(Observer::class); + $observer->expects($this->exactly(2)) + ->method('getData') + ->willReturnMap([ + ['quote', null, $targetQuoteMock], + ['source', null, $sourceQuoteMock] + ]); + + $this->salesEventQuoteMerge->execute($observer); + } + + /** + * @return array + */ + public function dataProviderGiftMessageId(): array + { + return [ + [null], + [1] + ]; + } +} From 860afbb9256608426cf024f114182b7b10ce59bb Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Fri, 19 Oct 2018 22:11:32 +0300 Subject: [PATCH 0694/1415] Covering the CategoryProductIndexer by Unit Test --- .../Observer/CategoryProductIndexerTest.php | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php new file mode 100644 index 0000000000000..adebee0d591ab --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Elasticsearch\Test\Unit\Observer; + +use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor; +use Magento\Elasticsearch\Model\Config; +use Magento\Elasticsearch\Observer\CategoryProductIndexer; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Class CategoryProductIndexerTest + */ +class CategoryProductIndexerTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var CategoryProductIndexer + */ + private $observer; + + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var Processor|\PHPUnit_Framework_MockObject_MockObject + */ + private $processorMock; + + /** + * @var Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * Set Up method + * + * @return void + */ + protected function setUp(): void + { + $this->configMock = $this->createMock(Config::class); + $this->processorMock = $this->createMock(Processor::class); + $this->observerMock = $this->createMock(Observer::class); + + $objectManager = new ObjectManagerHelper($this); + $this->observer = $objectManager->getObject( + CategoryProductIndexer::class, + [ + 'config' => $this->configMock, + 'processor' => $this->processorMock, + ] + ); + } + + /** + * Test if a category has changed products + * + * @return void + */ + public function testExecuteIfCategoryHasChangedProducts() + { + $this->getProductIdsWithEnabledElasticSearch(); + $this->processorMock->expects($this->once())->method('isIndexerScheduled')->willReturn(true); + $this->processorMock->expects($this->once())->method('markIndexerAsInvalid'); + $this->observer->execute($this->observerMock); + } + + /** + * Test if a category has changed products and not scheduled indexer + * + * @return void + */ + public function testExecuteIfCategoryHasChangedProductsAndNotScheduledIndexer(): void + { + $this->getProductIdsWithEnabledElasticSearch(); + $this->processorMock->expects($this->once())->method('isIndexerScheduled')->willReturn(false); + $this->processorMock->expects($this->never())->method('markIndexerAsInvalid'); + $this->observer->execute($this->observerMock); + } + + /** + * Test if a category has none changed products + * + * @return void + */ + public function testExecuteIfCategoryHasNoneChangedProducts(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(true); + + $eventMock->expects($this->once())->method('getProductIds')->willReturn([]); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock); + + $this->processorMock->expects($this->never())->method('isIndexerScheduled'); + $this->processorMock->expects($this->never())->method('markIndexerAsInvalid'); + + $this->observer->execute($this->observerMock); + } + + /** + * Test if ElasticSearch is disabled + * + * @return void + */ + public function testExecuteIfElasticSearchIsDisabled(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(false); + $eventMock->expects($this->never())->method('getProductIds')->willReturn([]); + $this->observer->execute($this->observerMock); + } + + /** + * Get product ids with enabled ElasticSearch + * + * @return void + */ + private function getProductIdsWithEnabledElasticSearch(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(true); + $eventMock->expects($this->once())->method('getProductIds')->willReturn([1]); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock); + } +} From 7051b70ea838191ebf1044b417cbcd58176f950e Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 19 Oct 2018 14:15:56 -0500 Subject: [PATCH 0695/1415] MQE-1187: Fix MFTF skipped tests - Fixing argument delta --- .../Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml index 14f41cefa7d01..d8a6a60299f8e 100644 --- a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminRoleActionGroup.xml @@ -18,7 +18,7 @@ <actionGroup name="AdminCreateRole"> <arguments> <argument name="role" type="string" defaultValue=""/> - <argument name="scope" type="string" defaultValue="Custom"/> + <argument name="resource" type="string" defaultValue="All"/> </arguments> <click selector="{{AdminCreateRoleSection.create}}" stepKey="clickToAddNewRole"/> <fillField selector="{{AdminCreateRoleSection.name}}" userInput="{{role.name}}" stepKey="setRoleName"/> From 8bd8b4dc938d1a2516dc3dc1084c0e29279fbddb Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 15:10:24 -0500 Subject: [PATCH 0696/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../foreign_key_interpreter_result.php | 2 +- .../fixture/valid_xml_revision_1.php | 10 +++---- .../Setup/DeclarativeInstallerTest.php | 26 +++++++++++++++---- .../Definition/Constraints/ForeignKey.php | 2 +- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php index 76fcf6b2fad11..e3068c1bd7625 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php @@ -33,7 +33,7 @@ 'constraint' => [ 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index cd42a1e8fc360..7271103e3e721 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -93,7 +93,7 @@ 'tinyint_ref' => 'tinyint_ref', ], 'type' => 'primary', - 'name' => 'tinyint_primary', + 'referenceId' => 'tinyint_primary', ], ], 'name' => 'reference_table', @@ -125,7 +125,7 @@ 'int_auto_increment_with_nullable' => 'int_auto_increment_with_nullable', ], 'type' => 'unique', - 'name' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', + 'referenceId' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', ], ], 'name' => 'auto_increment_test', @@ -231,11 +231,11 @@ 'bigint' => 'bigint', ], 'type' => 'unique', - 'name' => 'TEST_TABLE_SMALLINT_BIGINT', + 'referenceId' => 'TEST_TABLE_SMALLINT_BIGINT', ], 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -249,7 +249,7 @@ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'name' => 'TEST_TABLE_TINYINT_BIGINT', + 'referenceId' => 'TEST_TABLE_TINYINT_BIGINT', 'indexType' => 'btree', ], ], diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 34d432e566fec..856bdde4e98f3 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -79,8 +79,26 @@ public function testInstallation() //Second time installation should not find anything as we do not change anything self::assertNull($diff->getAll()); + $this->compareStructures(); + } + + /** + * Compare structure of DB and declared structure. + */ + private function compareStructures() + { $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + foreach ($this->getTrimmedData() as $tableName => $sql) { + $this->assertArrayHasKey($tableName, $shardData); + /** + * MySQL 8.0 and above does not provide information about the ON DELETE instruction + * if ON DELETE NO ACTION + */ + if (preg_match('#ON DELETE\s+NO ACTION#i', $shardData[$tableName] === 1)) { + preg_replace('#ON DELETE\s+NO ACTION#i', '', $sql); + self::assertEquals($sql, $shardData[$tableName]); + } + } } /** @@ -110,8 +128,7 @@ public function testInstallationWithColumnsModification() $this->schemaConfig->getDbConfig() ); self::assertNull($diff->getAll()); - $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + $this->compareStructures(); } /** @@ -156,8 +173,7 @@ public function testInstallationWithColumnsRemoval() $this->schemaConfig->getDbConfig() ); self::assertNull($diff->getAll()); - $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + $this->compareStructures(); } /** diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php index 1a9b42355f5e2..26bc2209d01ec 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php @@ -95,7 +95,7 @@ public function fromDefinition(array $data) 'column' => $match[2], 'referenceTable' => $match[5], 'referenceColumn' => $match[6], - 'onDelete' => isset($match[7]) ? $match[8] : '' + 'onDelete' => isset($match[7]) ? $match[8] : 'NO ACTION' ]; } } From e5539b4bcac7329f4248a02a6e7a8fa646e6654c Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 19 Oct 2018 15:35:55 -0500 Subject: [PATCH 0697/1415] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. - added functional test to cover the bug fix --- .../AdminCategoryBasicFieldSection.xml | 7 +++++ .../Mftf/Test/AdminCreateCategoryTest.xml | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml index 8b69a44993f17..9a0dd8f5b387d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml @@ -32,6 +32,13 @@ <element name="DesignTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Design']"/> <element name="LayoutDropdown" type="select" selector="select[name='page_layout']"/> </section> + <section name="CategoryDisplaySettingsSection"> + <element name="DisplaySettingTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Display Settings']"/> + <element name="layeredNavigationPriceInput" type="input" selector="input[name='filter_price_range']"/> + <element name="FieldError" type="text" selector=".admin__field-error[data-bind='attr: {for: {{field}}}, text: error']" parameterized="true"/> + <element name="filterPriceRangeUseConfig" type="checkbox" selector="input[name='use_config[filter_price_range]']"/> + <element name="RequiredFieldIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index={{arg1}}]>.admin__field-label span'), ':after').getPropertyValue('content');" parameterized="true"/> + </section> <section name="CatalogWYSIWYGSection"> <element name="ShowHideBtn" type="button" selector="#togglecategory_form_description"/> <element name="TinyMCE4" type="text" selector=".mce-branding-powered-by"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml index bfb9557910642..057a551e1e46a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml @@ -69,4 +69,34 @@ <waitForElementVisible selector="{{CategoryDesignSection.LayoutDropdown}}" stepKey="waitForLayoutDropDown" /> <seeOptionIsSelected selector="{{CategoryDesignSection.LayoutDropdown}}" userInput="2 columns with right bar" stepKey="see2ColumnsSelected" /> </test> + <test name="AdminCategoryFormDisplaySettingsUIValidationTest"> + <annotations> + <features value="Catalog"/> + <stories value="Default layout configuration MAGETWO-88793"/> + <title value="Category should not be saved once layered navigation price step field is left empty"/> + <description value="Once the Config setting is unchecked Category should not be saved with layered navigation price field left empty"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-95797"/> + <group value="category"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> + <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> + <click selector="{{CategoryDisplaySettingsSection.DisplaySettingTab}}" stepKey="clickOnDisplaySettingsTab"/> + <waitForElementVisible selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="wait"/> + <scrollTo selector="{{CategoryDisplaySettingsSection.layeredNavigationPriceInput}}" stepKey="scrollToLayeredNavigationField"/> + <uncheckOption selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="uncheckConfigSetting"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/> + <!-- Verify that the Layered navigation price step field has the required indicator --> + <executeJS function="{{CategoryDisplaySettingsSection.RequiredFieldIndicator('filter_price_range')}}" stepKey="getRequiredFieldIndicator"/> + <assertEquals expected='"*"' expectedType="string" actualType="variable" actual="getRequiredFieldIndicator" message="pass" stepKey="assertRequiredFieldIndicator1"/> + </test> </tests> From 0a253644a43f39d8ab40701011512534f4fc34bb Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 23:39:54 +0300 Subject: [PATCH 0698/1415] Fixed issue #4468 "Unable to insert multiple catalog product list widgets (with pager) in CMS page" --- .../Block/Product/ProductsList.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 5b9905e0c9d81..a0cfc08406189 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -198,7 +198,7 @@ public function getProductPriceHtml( ? $arguments['display_minimal_price'] : true; - /** @var \Magento\Framework\Pricing\Render $priceRender */ + /** @var \Magento\Framework\Pricing\Render $priceRender */ $priceRender = $this->getLayout()->getBlock('product.price.render.default'); if (!$priceRender) { $priceRender = $this->getLayout()->createBlock( @@ -347,7 +347,7 @@ public function getPagerHtml() if (!$this->pager) { $this->pager = $this->getLayout()->createBlock( \Magento\Catalog\Block\Product\Widget\Html\Pager::class, - 'widget.products.list.pager' + $this->getWidgetPagerBlockName() ); $this->pager->setUseContainer(true) @@ -408,4 +408,19 @@ private function getPriceCurrency() } return $this->priceCurrency; } + + /** + * @return string + */ + private function getWidgetPagerBlockName() + { + $pageName = $this->getData('page_var_name'); + $pagerBlockName = 'widget.products.list.pager'; + + if (!$pageName) { + return $pagerBlockName; + } + + return $pagerBlockName . '.' . $pageName; + } } From efc348b2c90bd12d5184f6f9f7d5abb4b9ba8564 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 19 Oct 2018 16:18:58 -0500 Subject: [PATCH 0699/1415] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. - addressing CR comments --- .../Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml index 057a551e1e46a..8806612c0f5de 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml @@ -82,9 +82,9 @@ <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> - <after> - <actionGroup ref="logout" stepKey="logout"/> - </after> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> @@ -96,6 +96,7 @@ <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> <see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/> <!-- Verify that the Layered navigation price step field has the required indicator --> + <comment userInput="Check if Layered navigation price field has required indictor icon" stepKey="comment" /> <executeJS function="{{CategoryDisplaySettingsSection.RequiredFieldIndicator('filter_price_range')}}" stepKey="getRequiredFieldIndicator"/> <assertEquals expected='"*"' expectedType="string" actualType="variable" actual="getRequiredFieldIndicator" message="pass" stepKey="assertRequiredFieldIndicator1"/> </test> From 5df1c200106f2794a0f3a23692628197a3cb6fbd Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 17:13:48 -0500 Subject: [PATCH 0700/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 72 +++++++++++++------ .../etc/db_schema.xml | 6 +- .../TablesWhitelistGenerateCommandTest.php | 2 + 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index b30edc0c7976f..1832cfce7f158 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -10,7 +10,10 @@ use Magento\Framework\Component\ComponentRegistrar; use Magento\Framework\Config\FileResolverByModule; use Magento\Framework\Module\Dir; +use Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder; use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; +use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; +use Magento\Framework\Setup\Declaration\Schema\Dto\SchemaFactory; use Magento\Framework\Setup\JsonPersistor; use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; use Symfony\Component\Console\Command\Command; @@ -50,22 +53,38 @@ class TablesWhitelistGenerateCommand extends Command */ private $primaryDbSchema; + /** + * @var SchemaFactory + */ + private $schemaFactory; + + /** + * @var SchemaBuilder + */ + private $schemaBuilder; + /** * @param ComponentRegistrar $componentRegistrar * @param ReaderComposite $readerComposite * @param JsonPersistor $jsonPersistor + * @param SchemaFactory $schemaFactory + * @param SchemaBuilder $schemaBuilder * @param string|null $name */ public function __construct( ComponentRegistrar $componentRegistrar, ReaderComposite $readerComposite, JsonPersistor $jsonPersistor, + SchemaFactory $schemaFactory, + SchemaBuilder $schemaBuilder, $name = null ) { parent::__construct($name); $this->componentRegistrar = $componentRegistrar; $this->readerComposite = $readerComposite; $this->jsonPersistor = $jsonPersistor; + $this->schemaFactory = $schemaFactory; + $this->schemaBuilder = $schemaBuilder; } /** @@ -98,6 +117,7 @@ protected function configure() * * @param string $moduleName * @return void + * @throws \Magento\Framework\Setup\Exception */ private function persistModule($moduleName) { @@ -113,15 +133,20 @@ private function persistModule($moduleName) $content = json_decode(file_get_contents($whiteListFileName), true); } - $newContent = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + $schema = $this->schemaFactory->create(); + $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + if (isset($data['table'])) { + $this->schemaBuilder->addTablesData($data['table']); + $schema = $this->schemaBuilder->build($schema); - //Do merge between what we have before, and what we have now and filter to only certain attributes. - $content = array_replace_recursive( - $content, - $this->filterAttributeNames($newContent) - ); - if (!empty($content)) { - $this->jsonPersistor->persist($content, $whiteListFileName); + //Do merge between what we have before, and what we have now and filter to only certain attributes. + $content = array_replace_recursive( + $content, + $this->getDeclaredContent($schema) + ); + if (!empty($content)) { + $this->jsonPersistor->persist($content, $whiteListFileName); + } } } @@ -149,27 +174,30 @@ protected function execute(InputInterface $input, OutputInterface $output) : int } /** - * Filter attribute names + * Convert Schema into a whitelist structure. * * As for whitelist we do not need any specific attributes like nullable or indexType, we need to choose only names. * - * @param array $content + * @param Schema $schema * @return array */ - private function filterAttributeNames(array $content) : array + private function getDeclaredContent(Schema $schema) : array { $names = []; - $types = ['column', 'index', 'constraint']; - - foreach ($content['table'] as $tableName => $tableContent) { - foreach ($types as $type) { - if (isset($tableContent[$type])) { - //Add elements to whitelist - foreach (array_keys($tableContent[$type]) as $elementName) { - //Depends on flag column will be whitelisted or not - $names[$tableName][$type][$elementName] = true; - } - } + foreach ($schema->getTables() as $tableName => $table) { + $columns = array_keys($table->getColumns()); + if ($columns) { + $names[$tableName]['column'] = array_fill_keys($columns, true); + } + + $indexes = array_keys($table->getIndexes()); + if ($indexes) { + $names[$tableName]['index'] = array_fill_keys($indexes, true); + } + + $constraints = array_keys($table->getConstraints()); + if ($constraints) { + $names[$tableName]['constraint'] = array_fill_keys($constraints, true); } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 1c4e7b6b6da97..ae6c98e4627d2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php index 77f2d741fc6b5..ef745d9e6fa4a 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php @@ -65,6 +65,7 @@ public function setUp() * * @moduleName Magento_TestSetupDeclarationModule1 * @dataProvider contentsDataProvider + * @throws \Exception */ public function testExecute(array $expectedWhitelistContent) { @@ -119,6 +120,7 @@ public function contentsDataProvider(): array 'constraint' => [ 'tinyint_primary' => true, + 'PRIMARY' => true, ], ], 'auto_increment_test' => From c9a8c738b0da805042275036a7cabd44db181b5b Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Sat, 20 Oct 2018 00:33:55 -0500 Subject: [PATCH 0701/1415] MAGETWO-71660: "Recently Ordered" widget conatins no more 5 products if qty of products > 5 - fix static test failures --- .../Magento/Sales/CustomerData/LastOrderedItemsTest.php | 2 ++ .../_files/order_with_customer_and_multiple_order_items.php | 1 + .../Magento/Sales/_files/order_with_multiple_items.php | 1 + 3 files changed, 4 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php index d0c2144c951e9..7800d2363b364 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\CustomerData; use Magento\Framework\ObjectManagerInterface; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php index 06d3667f4d057..08c54844f2749 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); include __DIR__ . '/order_with_multiple_items.php'; include __DIR__ . '/../../../Magento/Customer/_files/customer.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php index 4fa84e4e28f01..ae0523d34fd2f 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require 'order.php'; /** @var \Magento\Catalog\Model\Product $product */ From 19fa9e312cf53113931c7fdc3e779d0aa95ef707 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Sat, 20 Oct 2018 10:08:15 -0500 Subject: [PATCH 0702/1415] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 04115ccdcc480..e0898065a9d67 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,6 +17,9 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> + <skip> + <issueId value="MAGETWO-95799"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 80669e3c52cd94ce60f5ee2e31eda78584bba97e Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 20 Oct 2018 18:31:29 +0300 Subject: [PATCH 0703/1415] graphQl-44: added ProductTextAttributeInput --- .../Resolver/Product/ProductTextAttribute.php | 6 ++-- .../ProductTextAttribute/FormatList.php | 13 +++++-- .../Product/ProductTextAttribute/Html.php | 2 +- .../CatalogGraphQl/etc/schema.graphqls | 34 ++++++++++++++----- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 7649464e2e1ca..2ff6faa0a74ee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -39,7 +39,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve( Field $field, @@ -55,8 +55,8 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? $this->defaultFormat; - $format = $this->formatList->create($formatIdentifier); + $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; + $format = $this->formatList->getFormatByIdentifier($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; return $result; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 2e2f21d643092..39f2074ed7592 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -7,8 +7,13 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\ObjectManagerInterface; +/** + * Class FormatList + * @package Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute + */ class FormatList { /** @@ -37,10 +42,12 @@ public function __construct( * @param string $formatIdentifier * @return FormatInterface */ - public function create(string $formatIdentifier) : FormatInterface + public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->get($formatClassName); + if (!isset($this->formats[$formatIdentifier])) { + throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); + } + $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); return $formatInstance; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 75c29a3f78fac..830fbf28e3373 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -44,4 +44,4 @@ public function getContent( ): string { return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 944cae6537bb0..a7d9ab5483d46 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -557,9 +557,25 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextAttribute { - content ( - format: String @doc(description: "The format of content") -): String @doc(description: "The format of content") - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") +type ProductTextAttribute @doc(description: "Product text attribute.") { + content: String +} + +input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { + format: String @doc(description: "Format of the content") + eq: String @doc(description: "Equals") + finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") + from: String @doc(description: "From. Must be used with 'to'") + gt: String @doc(description: "Greater than") + gteq: String @doc(description: "Greater than or equal to") + in: [String] @doc(description: "In. The value can contain a set of comma-separated values") + like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") + lt: String @doc(description: "Less than") + lteq: String @doc(description: "Less than or equal to") + moreq: String @doc(description: "More than or equal to") + neq: String @doc(description: "Not equal to") + notnull: String @doc(description: "Not null") + null: String @doc(description: "Is null") + to: String@doc(description: "To. Must be used with 'from'") + nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") } From ed6a2fba850caa5e2402663fee133d4f56545200 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Sat, 20 Oct 2018 12:11:28 -0400 Subject: [PATCH 0704/1415] Prevent exception when option text converts to false The function would incorrectly through an exception when the option text was set to a string that would evaluate to false such as "0" Fixes #13083 --- .../Magento/Eav/Model/Entity/Attribute/OptionManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php b/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php index 4e4e146208a47..3c3bc083fdf8f 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php @@ -141,7 +141,7 @@ public function getItems($entityType, $attributeCode) */ protected function validateOption($attribute, $optionId) { - if (!$attribute->getSource()->getOptionText($optionId)) { + if ($attribute->getSource()->getOptionText($optionId) === false) { throw new NoSuchEntityException( __( 'The "%1" attribute doesn\'t include an option with "%2" ID.', From 8bea285e9a51e5b759256c25d18b4c34fe7648ce Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Sat, 20 Oct 2018 22:52:03 +0300 Subject: [PATCH 0705/1415] Set fallback values for email and _website columns to avoid 'undefined index' error in CustomerComposite.php CLA will be signed --- .../CustomerImportExport/Model/Import/CustomerComposite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php b/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php index 956c9695623bb..2086f41d27fa6 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php @@ -299,8 +299,8 @@ public function validateData() $rows = []; foreach ($source as $row) { $rows[] = [ - Address::COLUMN_EMAIL => $row[Customer::COLUMN_EMAIL], - Address::COLUMN_WEBSITE => $row[Customer::COLUMN_WEBSITE], + Address::COLUMN_EMAIL => $row[Customer::COLUMN_EMAIL] ?? null, + Address::COLUMN_WEBSITE => $row[Customer::COLUMN_WEBSITE] ?? null ]; } $source->rewind(); From 76a7243995ce3d6ba205df8386da6c6d392b71dd Mon Sep 17 00:00:00 2001 From: Ronak Patel <ronak2ram@gmail.com> Date: Sun, 21 Oct 2018 12:45:04 +0530 Subject: [PATCH 0706/1415] Fixed - Total pages field returns null in category query --- .../CatalogGraphQl/Model/Resolver/Category/Products.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..7a41f8fc94e74 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -92,7 +92,8 @@ public function resolve( 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), - 'current_page' => $currentPage + 'current_page' => $currentPage, + 'total_pages' => $maxPages ] ]; return $data; From 111bc284c94d56327ad8a5d3dc997a70fde84bae Mon Sep 17 00:00:00 2001 From: Nikita Titov <nekit94-08@mail.ru> Date: Sun, 21 Oct 2018 14:40:36 +0300 Subject: [PATCH 0707/1415] Updated links in README --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c292f1100f336..979e60a167748 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting-edge, feature-rich eCommerce solution that gets results. ## Magento system requirements -[Magento system requirements](http://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html). +[Magento system requirements](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html). ## Install Magento -* [Installation guide](http://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). +* [Installation guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). <h2>Contributing to the Magento 2 code base</h2> Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions. @@ -21,10 +21,10 @@ To learn about issues, click [here][2]. To open an issue, click [here][3]. To suggest documentation improvements, click [here][4]. -[1]: <http://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html> -[2]: <http://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#report> +[1]: <https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html> +[2]: <https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#report> [3]: <https://github.com/magento/magento2/issues> -[4]: <http://devdocs.magento.com> +[4]: <https://devdocs.magento.com> <h3>Community Maintainers</h3> The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks these Community Maintainers for their valuable contributions. @@ -53,9 +53,9 @@ Stay up-to-date on the latest security news and patches for Magento by signing u Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license. -http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) -Please see LICENSE.txt for the full text of the OSL 3.0 license or contact license@magentocommerce.com for a copy. +[Open Software License (OSL 3.0)](https://opensource.org/licenses/osl-3.0.php). +Please see [LICENSE.txt](https://github.com/magento/magento2/blob/2.3-develop/LICENSE.txt) for the full text of the OSL 3.0 license or contact license@magentocommerce.com for a copy. Subject to Licensee's payment of fees and compliance with the terms and conditions of the MEE License, the MEE License supersedes the OSL 3.0 license for each source file. -Please see LICENSE_EE.txt for the full text of the MEE License or visit http://magento.com/legal/terms/enterprise. +Please see LICENSE_EE.txt for the full text of the MEE License or visit https://magento.com/legal/terms/enterprise. From 1b6ce27459ece1d6ddd2f1b3ef69114f004aeb68 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim <gy741.kim@gmail.com> Date: Sun, 21 Oct 2018 21:45:51 +0900 Subject: [PATCH 0708/1415] Fix Useless use of Cat --- dev/travis/before_script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 1dccc310c7a20..dbd9d1cd4fec1 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -72,7 +72,7 @@ case $TEST_SUITE in --base-path="$TRAVIS_BUILD_DIR" \ --repo='https://github.com/magento/magento2.git' \ --branch="$TRAVIS_BRANCH" - cat "$changed_files_ce" | sed 's/^/ + including /' + sed 's/^/ + including /' "$changed_files_ce" cd ../../.. ;; From c34e734c061209a766ad83d686b42ffa41378b27 Mon Sep 17 00:00:00 2001 From: Manuele Menozzi <mmenozzi@webgriffe.com> Date: Sun, 21 Oct 2018 17:20:28 +0200 Subject: [PATCH 0709/1415] Prevent MAGE_DIRS overwrite in pub/index.php --- pub/index.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pub/index.php b/pub/index.php index 457b83c529488..90b4778265447 100644 --- a/pub/index.php +++ b/pub/index.php @@ -25,12 +25,15 @@ } $params = $_SERVER; -$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = [ - DirectoryList::PUB => [DirectoryList::URL_PATH => ''], - DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], - DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], - DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], -]; +$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( + $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], + [ + DirectoryList::PUB => [DirectoryList::URL_PATH => ''], + DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], + DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], + DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], + ] +); $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params); /** @var \Magento\Framework\App\Http $app */ $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); From 19a2d2f2a2156b96733fadc88e16d07e871aadf7 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 21 Oct 2018 20:58:29 +0300 Subject: [PATCH 0710/1415] Sections less mixins: fix the issue with missing rules and incorrect default variables #18729 --- lib/web/css/source/lib/_sections.less | 15 +++++++++------ lib/web/css/source/lib/variables/_sections.less | 7 +++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/web/css/source/lib/_sections.less b/lib/web/css/source/lib/_sections.less index 372008d061580..b73e317835955 100644 --- a/lib/web/css/source/lib/_sections.less +++ b/lib/web/css/source/lib/_sections.less @@ -49,16 +49,16 @@ @_tab-control-color: @tab-control__color, @_tab-control-text-decoration: @tab-control__text-decoration, - @_tab-control-color-visited: @tab-control__color, - @_tab-control-text-decoration-visited: @tab-control__text-decoration, + @_tab-control-color-visited: @tab-control__visited__color, + @_tab-control-text-decoration-visited: @tab-control__visited__text-decoration, @_tab-control-background-color-hover: @tab-control__hover__background-color, @_tab-control-color-hover: @tab-control__hover__color, - @_tab-control-text-decoration-hover: @tab-control__text-decoration, + @_tab-control-text-decoration-hover: @tab-control__hover__text-decoration, @_tab-control-background-color-active: @tab-control__active__background-color, @_tab-control-color-active: @tab-control__active__color, - @_tab-control-text-decoration-active: @tab-control__text-decoration, + @_tab-control-text-decoration-active: @tab-control__active__text-decoration, @_tab-control-height: @tab-control__height, @_tab-control-margin-right: @tab-control__margin-right, @@ -121,6 +121,7 @@ &.active > .switch:hover { .lib-css(background, @_tab-control-background-color-active); .lib-css(color, @_tab-control-color-active); + .lib-css(text-decoration, @_tab-control-text-decoration-active); } &.active > .switch, @@ -200,8 +201,8 @@ @_accordion-control-color: @accordion-control__color, @_accordion-control-text-decoration: @accordion-control__text-decoration, - @_accordion-control-color-visited: @accordion-control__color, - @_accordion-control-text-decoration-visited: @accordion-control__text-decoration, + @_accordion-control-color-visited: @accordion-control__visited__color, + @_accordion-control-text-decoration-visited: @accordion-control__visited__text-decoration, @_accordion-control-background-color-hover: @accordion-control__hover__background-color, @_accordion-control-color-hover: @accordion-control__hover__color, @@ -275,6 +276,8 @@ &.active > .switch:focus, &.active > .switch:hover { .lib-css(background, @_accordion-control-background-color-active); + .lib-css(color, @_accordion-control-color-active); + .lib-css(text-decoration, @_accordion-control-text-decoration-active); .lib-css(padding-bottom, @_accordion-control-padding-bottom); } } diff --git a/lib/web/css/source/lib/variables/_sections.less b/lib/web/css/source/lib/variables/_sections.less index 7d961077e6f59..0868ce73c49ef 100644 --- a/lib/web/css/source/lib/variables/_sections.less +++ b/lib/web/css/source/lib/variables/_sections.less @@ -40,6 +40,9 @@ @tab-control__active__color: @text__color; @tab-control__active__text-decoration: @tab-control__text-decoration; +@tab-control__visited__color: @accordion-control__color; +@tab-control__visited__text-decoration: @accordion-control__text-decoration; + @tab-content__background-color: @tab-control__active__background-color; @tab-content__border-top-status: false; @tab-content__border: @tab-control__border-width solid @tab-control__border-color; @@ -72,8 +75,8 @@ @accordion-control__padding-bottom: @tab-control__padding-bottom; @accordion-control__padding-left: @accordion-control__padding-right; -@accordion-control__visited__color: @accordion-control__color; -@accordion-control__visited__text-decoration: @accordion-control__text-decoration; +@accordion-control__visited__color: @tab-control__visited__color; +@accordion-control__visited__text-decoration: @tab-control__visited__text-decoration; @accordion-control__hover__background-color: @tab-control__hover__background-color; @accordion-control__hover__color: @tab-control__hover__color; From 310afd896e0c3cc82d81e50f92dff928c231f2bc Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 21 Oct 2018 21:36:13 +0300 Subject: [PATCH 0711/1415] Fix a typo in variable name #18730 --- lib/web/css/source/lib/variables/_sections.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/css/source/lib/variables/_sections.less b/lib/web/css/source/lib/variables/_sections.less index 0868ce73c49ef..05226d8aa3a3c 100644 --- a/lib/web/css/source/lib/variables/_sections.less +++ b/lib/web/css/source/lib/variables/_sections.less @@ -40,8 +40,8 @@ @tab-control__active__color: @text__color; @tab-control__active__text-decoration: @tab-control__text-decoration; -@tab-control__visited__color: @accordion-control__color; -@tab-control__visited__text-decoration: @accordion-control__text-decoration; +@tab-control__visited__color: @tab-control__color; +@tab-control__visited__text-decoration: @tab-control__text-decoration; @tab-content__background-color: @tab-control__active__background-color; @tab-content__border-top-status: false; From a4b5cc1106f69325ab21774c0b5d86653101a2a0 Mon Sep 17 00:00:00 2001 From: Pratik Oza <pratik.oza@krishtechnolabs.com> Date: Mon, 22 Oct 2018 01:19:55 +0530 Subject: [PATCH 0712/1415] Correct a typo in the reference to ISO language codes --- app/code/Magento/Deploy/Console/DeployStaticOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Deploy/Console/DeployStaticOptions.php b/app/code/Magento/Deploy/Console/DeployStaticOptions.php index 9a73dd5d65fc7..89cb3e4b30345 100644 --- a/app/code/Magento/Deploy/Console/DeployStaticOptions.php +++ b/app/code/Magento/Deploy/Console/DeployStaticOptions.php @@ -240,7 +240,7 @@ private function getBasicOptions() new InputArgument( self::LANGUAGES_ARGUMENT, InputArgument::IS_ARRAY, - 'Space-separated list of ISO-636 language codes for which to output static view files.' + 'Space-separated list of ISO-639 language codes for which to output static view files.' ), ]; } From 4662ca91833b95662b8f7098718026153c290d05 Mon Sep 17 00:00:00 2001 From: vprohorov <vitaliy_prokharau@epam.com> Date: Mon, 22 Oct 2018 14:25:06 +0300 Subject: [PATCH 0713/1415] MAGETWO-91537: Search synonyms results missing for words including hyphen and numbers - Fixing test --- .../Magento/Catalog/Test/Repository/CatalogProductSimple.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml index 721b0ff570079..e90ca6bf7868a 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml @@ -41,7 +41,7 @@ <field name="attribute_set_id" xsi:type="array"> <item name="dataset" xsi:type="string">default</item> </field> - <field name="name" xsi:type="string">Product \'!@#$%^&*()+:;\\|}{][?=-~` %isolation%</field> + <field name="name" xsi:type="string">Product \'!@#$%^&*()+:;\\|}{][?=~` %isolation%</field> <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> <field name="is_virtual" xsi:type="string">No</field> <field name="product_has_weight" xsi:type="string">This item has weight</field> From 65dac5da0815119255b15e9dcec1fe4f955571a6 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 22 Oct 2018 14:56:47 +0300 Subject: [PATCH 0714/1415] MAGETWO-95654: Constraint removal is not treated as destructive operation - Added foreign key for 'magento_bulk' table; --- app/code/Magento/AsynchronousOperations/etc/db_schema.xml | 2 ++ .../AsynchronousOperations/etc/db_schema_whitelist.json | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 342326e6666f1..95bd9bdcab283 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -27,6 +27,8 @@ <constraint xsi:type="unique" name="MAGENTO_BULK_UUID"> <column name="uuid"/> </constraint> + <constraint xsi:type="foreign" name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" table="magento_bulk" + column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> <index name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> <column name="user_id"/> </index> diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json index 423b7553ced2a..9b6c0709e1916 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json @@ -15,7 +15,8 @@ }, "constraint": { "PRIMARY": true, - "MAGENTO_BULK_UUID": true + "MAGENTO_BULK_UUID": true, + "MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID": true } }, "magento_operation": { From fe600f2d231ef8146837cc6172b8f92e96234ffd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 15:34:12 +0200 Subject: [PATCH 0715/1415] Minor code style fixes --- .../GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php index f82bc01c485e9..7a3000f7c0743 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php @@ -10,7 +10,7 @@ use Magento\GiftMessage\Observer\SalesEventQuoteMerge; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use \Magento\Framework\Event\Observer; +use Magento\Framework\Event\Observer; use Magento\Quote\Model\Quote; /** From bb7044698dce2e18fad007aa65d7e0c4a39b1e4c Mon Sep 17 00:00:00 2001 From: vprohorov <vitaliy_prokharau@epam.com> Date: Mon, 22 Oct 2018 16:43:34 +0300 Subject: [PATCH 0716/1415] MAGETWO-95825: [Magento cloud] - Images revert to default placeholder on import - Removing invalid image attributes from row --- app/code/Magento/CatalogImportExport/Model/Import/Product.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 7c56c266a64ef..f69b2def609e9 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1782,6 +1782,7 @@ protected function _saveProducts() if ($uploadedFile) { $uploadedImages[$columnImage] = $uploadedFile; } else { + unset($rowData[$column]); $this->addRowError( ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE, $rowNum, From 93c6073eca8f6611ad3702b17861dd4aee7a9364 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 15:55:02 +0200 Subject: [PATCH 0717/1415] Attempt to determine why GraphQl test modules are not present in the env --- dev/travis/before_script.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index c27e65d3897c7..52fd44c2826cc 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,6 +152,9 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" + php bin/magento module:status # DEBUG + php bin/magento setup:upgrade # DEBUG + echo "Enabling production mode" php bin/magento deploy:mode:set production From f9a7b81238135a51f964ef861e26c9ec6aa557e9 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 16:17:31 +0200 Subject: [PATCH 0718/1415] Temporarily disable all other tests except api-fucntional --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index f5a25bc63543d..930172a9ea6e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: - - TEST_SUITE=unit - - TEST_SUITE=static - - TEST_SUITE=js GRUNT_COMMAND=spec - - TEST_SUITE=js GRUNT_COMMAND=static - - TEST_SUITE=integration INTEGRATION_INDEX=1 - - TEST_SUITE=integration INTEGRATION_INDEX=2 - - TEST_SUITE=integration INTEGRATION_INDEX=3 - - TEST_SUITE=functional +# - TEST_SUITE=unit +# - TEST_SUITE=static +# - TEST_SUITE=js GRUNT_COMMAND=spec +# - TEST_SUITE=js GRUNT_COMMAND=static +# - TEST_SUITE=integration INTEGRATION_INDEX=1 +# - TEST_SUITE=integration INTEGRATION_INDEX=2 +# - TEST_SUITE=integration INTEGRATION_INDEX=3 +# - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: From c954022c288af8703c888ceb0dcb492f52cac97f Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 22 Oct 2018 09:47:33 -0500 Subject: [PATCH 0719/1415] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - stabilize test --- .../Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 9 ++++++--- .../Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 04115ccdcc480..9d3b498dc6ce6 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -20,14 +20,16 @@ </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + <magentoCLI command="config:set cms/wysiwyg/enabled enabled" stepKey="enableWYSIWYG"/> <!-- Choose TinyMCE3 as the default WYSIWYG editor--> - <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> + <!--<actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/>--> + <magentoCLI command="config:set cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter" stepKey="enableTinyMCE3"/> </before> <after> <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> - <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> + <!--<actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/>--> + <magentoCLI command="config:set cms/wysiwyg/editor mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter" stepKey="enableTinyMCE4"/> <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> @@ -36,6 +38,7 @@ <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> <seeElement selector="{{TinyMCESection.TinyMCE3}}" stepKey="seeTinyMCE3" /> + <wait time="3" stepKey="waiting"/> <comment userInput="Click Insert image button" stepKey="clickImageButton"/> <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> <waitForPageLoad stepKey="waitForiFrameToLoad" /> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 2d784842ea46a..307999ce48e4d 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -28,6 +28,7 @@ <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigurationSuccessMessage"/> </actionGroup> <actionGroup name="DisabledWYSIWYG"> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> From bca0e5e9e9117b28d69ae24161a690644ab4dac2 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Sun, 21 Oct 2018 22:38:05 -0500 Subject: [PATCH 0720/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 169 +----------- .../Declaration/Schema/WhitelistGenerator.php | 258 ++++++++++++++++++ .../Schema/Declaration/SchemaBuilder.php | 72 +---- .../TableElement/ElementNameResolver.php | 190 +++++++++++++ .../Schema/Dto/Factories/Foreign.php | 34 +-- .../Schema/Dto/Factories/Index.php | 40 ++- .../Schema/Dto/Factories/Unique.php | 32 +-- .../Setup/Declaration/Schema/Dto/Table.php | 16 +- .../Setup/Declaration/Schema/etc/index.xsd | 2 +- .../Setup/Declaration/Schema/etc/schema.xsd | 31 ++- 10 files changed, 569 insertions(+), 275 deletions(-) create mode 100644 app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php create mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 1832cfce7f158..9e1f9252c84b6 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -7,15 +7,9 @@ namespace Magento\Developer\Console\Command; -use Magento\Framework\Component\ComponentRegistrar; +use Magento\Developer\Model\Setup\Declaration\Schema\WhitelistGenerator; use Magento\Framework\Config\FileResolverByModule; -use Magento\Framework\Module\Dir; -use Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder; -use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; -use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; -use Magento\Framework\Setup\Declaration\Schema\Dto\SchemaFactory; -use Magento\Framework\Setup\JsonPersistor; -use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; +use Magento\Framework\Exception\ConfigurationMismatchException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -34,57 +28,20 @@ class TablesWhitelistGenerateCommand extends Command const MODULE_NAME_KEY = 'module-name'; /** - * @var ComponentRegistrar + * @var WhitelistGenerator */ - private $componentRegistrar; + private $whitelistGenerator; /** - * @var ReaderComposite - */ - private $readerComposite; - - /** - * @var JsonPersistor - */ - private $jsonPersistor; - - /** - * @var array - */ - private $primaryDbSchema; - - /** - * @var SchemaFactory - */ - private $schemaFactory; - - /** - * @var SchemaBuilder - */ - private $schemaBuilder; - - /** - * @param ComponentRegistrar $componentRegistrar - * @param ReaderComposite $readerComposite - * @param JsonPersistor $jsonPersistor - * @param SchemaFactory $schemaFactory - * @param SchemaBuilder $schemaBuilder + * @param WhitelistGenerator $whitelistGenerator * @param string|null $name */ public function __construct( - ComponentRegistrar $componentRegistrar, - ReaderComposite $readerComposite, - JsonPersistor $jsonPersistor, - SchemaFactory $schemaFactory, - SchemaBuilder $schemaBuilder, + WhitelistGenerator $whitelistGenerator, $name = null ) { + $this->whitelistGenerator = $whitelistGenerator; parent::__construct($name); - $this->componentRegistrar = $componentRegistrar; - $this->readerComposite = $readerComposite; - $this->jsonPersistor = $jsonPersistor; - $this->schemaFactory = $schemaFactory; - $this->schemaBuilder = $schemaBuilder; } /** @@ -112,44 +69,6 @@ protected function configure() parent::configure(); } - /** - * Update whitelist tables for all modules that are enabled on the moment. - * - * @param string $moduleName - * @return void - * @throws \Magento\Framework\Setup\Exception - */ - private function persistModule($moduleName) - { - $content = []; - $modulePath = $this->componentRegistrar->getPath('module', $moduleName); - $whiteListFileName = $modulePath - . DIRECTORY_SEPARATOR - . Dir::MODULE_ETC_DIR - . DIRECTORY_SEPARATOR - . Diff::GENERATED_WHITELIST_FILE_NAME; - //We need to load whitelist file and update it with new revision of code. - if (file_exists($whiteListFileName)) { - $content = json_decode(file_get_contents($whiteListFileName), true); - } - - $schema = $this->schemaFactory->create(); - $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); - if (isset($data['table'])) { - $this->schemaBuilder->addTablesData($data['table']); - $schema = $this->schemaBuilder->build($schema); - - //Do merge between what we have before, and what we have now and filter to only certain attributes. - $content = array_replace_recursive( - $content, - $this->getDeclaredContent($schema) - ); - if (!empty($content)) { - $this->jsonPersistor->persist($content, $whiteListFileName); - } - } - } - /** * @inheritdoc */ @@ -158,80 +77,14 @@ protected function execute(InputInterface $input, OutputInterface $output) : int $moduleName = $input->getOption(self::MODULE_NAME_KEY); try { - if ($moduleName === FileResolverByModule::ALL_MODULES) { - foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) { - $this->persistModule($moduleName); - } - } else { - $this->persistModule($moduleName); - } + $this->whitelistGenerator->generate($moduleName); + } catch (ConfigurationMismatchException $e) { + $output->writeln("<info>". $e . "</info>"); + return \Magento\Framework\Console\Cli::RETURN_FAILURE; } catch (\Exception $e) { return \Magento\Framework\Console\Cli::RETURN_FAILURE; } - //If script comes here, that we sucessfully write whitelist configuration return \Magento\Framework\Console\Cli::RETURN_SUCCESS; } - - /** - * Convert Schema into a whitelist structure. - * - * As for whitelist we do not need any specific attributes like nullable or indexType, we need to choose only names. - * - * @param Schema $schema - * @return array - */ - private function getDeclaredContent(Schema $schema) : array - { - $names = []; - foreach ($schema->getTables() as $tableName => $table) { - $columns = array_keys($table->getColumns()); - if ($columns) { - $names[$tableName]['column'] = array_fill_keys($columns, true); - } - - $indexes = array_keys($table->getIndexes()); - if ($indexes) { - $names[$tableName]['index'] = array_fill_keys($indexes, true); - } - - $constraints = array_keys($table->getConstraints()); - if ($constraints) { - $names[$tableName]['constraint'] = array_fill_keys($constraints, true); - } - } - - return $names; - } - - /** - * Load db_schema content from the primary scope app/etc/db_schema.xml. - * - * @return array - */ - private function getPrimaryDbSchema() - { - if (!$this->primaryDbSchema) { - $this->primaryDbSchema = $this->readerComposite->read('primary'); - } - return $this->primaryDbSchema; - } - - /** - * Filter tables from module db_schema.xml as they should not contain the primary system tables. - * - * @param array $moduleDbSchema - * @return array - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - private function filterPrimaryTables(array $moduleDbSchema) - { - $primaryDbSchema = $this->getPrimaryDbSchema(); - if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) { - foreach ($primaryDbSchema['table'] as $tableNameKey => $tableContents) { - unset($moduleDbSchema['table'][$tableNameKey]); - } - } - return $moduleDbSchema; - } } diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php new file mode 100644 index 0000000000000..af20619934d68 --- /dev/null +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -0,0 +1,258 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Developer\Model\Setup\Declaration\Schema; + +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Framework\Config\FileResolverByModule; +use Magento\Framework\Exception\ConfigurationMismatchException; +use Magento\Framework\Module\Dir; +use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; +use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; +use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; +use Magento\Framework\Setup\Declaration\Schema\SchemaConfig; +use Magento\Framework\Setup\JsonPersistor; + +/** + * Generate whitelist declaration declarative schema. + */ +class WhitelistGenerator +{ + /** + * @var SchemaConfig + */ + private $schemaConfig; + + /** + * @var ComponentRegistrar + */ + private $componentRegistrar; + + /** + * @var JsonPersistor + */ + private $jsonPersistor; + + /** + * @var ReaderComposite + */ + private $readerComposite; + + /** + * @var array + */ + private $primaryDbSchema; + + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + + /** + * @var DeploymentConfig + */ + private $deploymentConfig; + + /** + * @param ComponentRegistrar $componentRegistrar + * @param JsonPersistor $jsonPersistor + * @param SchemaConfig $schemaConfig + * @param ReaderComposite $readerComposite + * @param ElementNameResolver $elementNameResolver + * @param DeploymentConfig $deploymentConfig + */ + public function __construct( + ComponentRegistrar $componentRegistrar, + JsonPersistor $jsonPersistor, + SchemaConfig $schemaConfig, + ReaderComposite $readerComposite, + ElementNameResolver $elementNameResolver, + DeploymentConfig $deploymentConfig + ) { + $this->componentRegistrar = $componentRegistrar; + $this->jsonPersistor = $jsonPersistor; + $this->schemaConfig = $schemaConfig; + $this->readerComposite = $readerComposite; + $this->elementNameResolver = $elementNameResolver; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * Generate whitelist declaration. + * + * @param string $moduleName + * @throws ConfigurationMismatchException + */ + public function generate(string $moduleName) + { + $this->checkMagentoInstallation(); + $schema = $this->schemaConfig->getDeclarationConfig(); + if ($moduleName === FileResolverByModule::ALL_MODULES) { + foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) { + $this->persistModule($schema, $moduleName); + } + } else { + $this->persistModule($schema, $moduleName); + } + } + + /** + * Check the configuration of the installed instance. + * + * @throws ConfigurationMismatchException + */ + private function checkMagentoInstallation() + { + $tablePrefixLength = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_PREFIX); + if ($tablePrefixLength) { + throw new ConfigurationMismatchException( + __('Magento was installed with a table prefix. Please re-install without prefix.') + ); + } + } + + /** + * Update whitelist tables for all modules that are enabled on the moment. + * + * @param Schema $schema + * @param string $moduleName + * @return void + */ + private function persistModule(Schema $schema, string $moduleName) + { + $content = []; + $modulePath = $this->componentRegistrar->getPath('module', $moduleName); + $whiteListFileName = $modulePath + . DIRECTORY_SEPARATOR + . Dir::MODULE_ETC_DIR + . DIRECTORY_SEPARATOR + . Diff::GENERATED_WHITELIST_FILE_NAME; + + //We need to load whitelist file and update it with new revision of code. + if (file_exists($whiteListFileName)) { + $content = json_decode(file_get_contents($whiteListFileName), true); + } + + $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + if (!empty($data['table'])) { + foreach ($data['table'] as $tableName => $tabledata) { + //Do merge between what we have before, and what we have now and filter to only certain attributes. + $content = array_replace_recursive( + $content, + [$tableName => $this->getElementsWithFixedName($tabledata)], + [$tableName => $this->getElementsWithAutogeneratedName( + $schema, + $tableName, + $tabledata + )] + ); + } + if (!empty($content)) { + $this->jsonPersistor->persist($content, $whiteListFileName); + } + } + } + + /** + * Provides immutable names of the table elements. + * + * @param array $tableData + * @return array + */ + private function getElementsWithFixedName(array $tableData): array + { + $declaredStructure = []; + if (!empty($tableData['column'])) { + $declaredColumns = array_keys($tableData['column']); + $declaredStructure['column'] = array_fill_keys($declaredColumns, true); + } + return $declaredStructure; + } + + /** + * Provides autogenerated names of the table elements. + * + * @param Schema $schema + * @param string $tableName + * @param array $tableData + * @return array + */ + private function getElementsWithAutogeneratedName(Schema $schema, string $tableName, array $tableData) : array + { + $declaredStructure = []; + $table = $schema->getTableByName($tableName); + + $elementType = 'index'; + if (!empty($tableData[$elementType])) { + foreach ($tableData[$elementType] as $tableElementData) { + $indexName = $this->elementNameResolver->getFullIndexName( + $table, + $tableElementData['column'], + $tableElementData['indexType'] ?? null + ); + $declaredStructure[$elementType][$indexName] = true; + } + } + + $elementType = 'constraint'; + if (!empty($tableData[$elementType])) { + foreach ($tableData[$elementType] as $tableElementData) { + if ($tableElementData['type'] === 'foreign') { + $referenceTable = $schema->getTableByName($tableElementData['referenceTable']); + $constraintName = $this->elementNameResolver->getFullFKName( + $table, + $table->getColumnByName($tableElementData['column']), + $referenceTable, + $referenceTable->getColumnByName($tableElementData['referenceColumn']) + ); + } else { + $constraintName = $this->elementNameResolver->getFullIndexName( + $table, + $tableElementData['column'], + $tableElementData['type'] + ); + } + $declaredStructure[$elementType][$constraintName] = true; + } + } + + return $declaredStructure; + } + + /** + * Load db_schema content from the primary scope app/etc/db_schema.xml. + * + * @return array + */ + private function getPrimaryDbSchema(): array + { + if (!$this->primaryDbSchema) { + $this->primaryDbSchema = $this->readerComposite->read('primary'); + } + return $this->primaryDbSchema; + } + + /** + * Filter tables from module database schema as they should not contain the primary system tables. + * + * @param array $moduleDbSchema + * @return array + */ + private function filterPrimaryTables(array $moduleDbSchema): array + { + $primaryDbSchema = $this->getPrimaryDbSchema(); + if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) { + foreach (array_keys($primaryDbSchema['table']) as $tableNameKey) { + unset($moduleDbSchema['table'][$tableNameKey]); + } + } + return $moduleDbSchema; + } +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 735b8273019f7..34a99f26a4ef1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -7,9 +7,8 @@ namespace Magento\Framework\Setup\Declaration\Schema\Declaration; -use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Phrase; -use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Stdlib\BooleanUtils; use Magento\Framework\Setup\Exception; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; @@ -70,9 +69,9 @@ class SchemaBuilder private $resourceConnection; /** - * @var TableNameResolver + * @var ElementNameResolver */ - private $tableNameResolver; + private $elementNameResolver; /** * SchemaBuilder constructor. @@ -82,8 +81,7 @@ class SchemaBuilder * @param Sharding $sharding * @param ValidationComposite $validationComposite * @param \Magento\Framework\App\ResourceConnection $resourceConnection - * @param TableNameResolver $tableNameResolver - * @internal param array $tablesData + * @param ElementNameResolver $elementNameResolver */ public function __construct( ElementFactory $elementFactory, @@ -91,14 +89,14 @@ public function __construct( Sharding $sharding, ValidationComposite $validationComposite, \Magento\Framework\App\ResourceConnection $resourceConnection, - TableNameResolver $tableNameResolver + ElementNameResolver $elementNameResolver ) { $this->sharding = $sharding; $this->elementFactory = $elementFactory; $this->booleanUtils = $booleanUtils; $this->validationComposite = $validationComposite; $this->resourceConnection = $resourceConnection; - $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** @@ -291,33 +289,6 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table): return $columns; } - /** - * Provides the full index name based on the prefix value. - * - * @param Table $table - * @param array $columns - * @param string $type - * @return string - */ - private function getFullIndexName( - Table $table, - array $columns, - string $type = AdapterInterface::INDEX_TYPE_INDEX - ): string { - if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { - return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); - } - - $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); - - return $this->resourceConnection - ->getIdxName( - $tableName, - $columns, - $type - ); - } - /** * Convert and instantiate index objects. * @@ -339,19 +310,10 @@ private function processIndexes(array $tableData, string $resource, Table $table continue; } - /** - * Temporary solution. - * @see MAGETWO-91365 - */ - $indexType = AdapterInterface::INDEX_TYPE_INDEX; - if (isset($indexData['indexType']) && $indexData['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { - $indexType = $indexData['indexType']; - } - - $indexData['name'] = $this->getFullIndexName( + $indexData['name'] = $this->elementNameResolver->getFullIndexName( $table, $indexData['column'], - $indexType + $indexData['indexType'] ?? null ); $indexData = $this->processGenericData($indexData, $resource, $table); $indexData['columns'] = $this->convertColumnNamesToObjects($indexData['column'], $table); @@ -411,20 +373,16 @@ private function processConstraints(array $tableData, string $resource, Schema $ $constraintData['referenceColumn'], $constraintData['referenceTable'] ); - /** - * Calculation of the full name of Foreign Key based on the prefix value. - */ - $constraintData['name'] = $this->resourceConnection - ->getFkName( - $this->tableNameResolver->getNameOfOriginTable($table->getName()), - $constraintData['column']->getName(), - $constraintData['referenceTable']->getName(), - $constraintData['referenceColumn']->getName() - ); + $constraintData['name'] = $this->elementNameResolver->getFullFKName( + $table, + $constraintData['column'], + $constraintData['referenceTable'], + $constraintData['referenceColumn'] + ); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; } else { - $constraintData['name'] = $this->getFullIndexName( + $constraintData['name'] = $this->elementNameResolver->getFullIndexName( $table, $constraintData['column'], $constraintData['type'] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php new file mode 100644 index 0000000000000..a3e66b9cf39c5 --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php @@ -0,0 +1,190 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Column; +use Magento\Framework\Setup\Declaration\Schema\Dto\Table; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; + +/** + * Provides names of table elements with autogenerated names. + */ +class ElementNameResolver +{ + /** + * @var TableNameResolver + */ + private $tableNameResolver; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @param TableNameResolver $tableNameResolver + * @param ResourceConnection $resourceConnection + */ + public function __construct(TableNameResolver $tableNameResolver, ResourceConnection $resourceConnection) + { + $this->tableNameResolver = $tableNameResolver; + $this->resourceConnection = $resourceConnection; + } + + /** + * Provides the full index name based on the prefix value. + * + * @param Table $table + * @param string[] $columns + * @param string $type + * @return string + */ + public function getFullIndexName( + Table $table, + array $columns, + ?string $type = AdapterInterface::INDEX_TYPE_INDEX + ): string { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); + } + + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + if ($type + && !array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ) + ) { + $type = AdapterInterface::INDEX_TYPE_INDEX; + } + + $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); + + return $this->resourceConnection + ->getIdxName( + $tableName, + $columns, + $type + ); + } + + /** + * Provides the index name without prefix value. + * + * @param string $name + * @param Table $table + * @param string[] $columns + * @param string $type + * @return string + */ + public function getIndexNameWithoutPrefix( + string $name, + Table $table, + array $columns, + ?string $type = AdapterInterface::INDEX_TYPE_INDEX + ): string { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); + } + + $nameWithoutPrefix = $name; + + if ($this->resourceConnection->getTablePrefix()) { + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + if ($type + && !array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ) + ) { + $type = AdapterInterface::INDEX_TYPE_INDEX; + } + + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($table->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $table->getNameWithoutPrefix() + ), + $columns, + $type + ); + } + + return $nameWithoutPrefix; + } + + /** + * Provides the full foreign key name based on the prefix value. + * + * @param Table $table + * @param Column $column + * @param Table $referenceTable + * @param Column $referenceColumn + * @return string + */ + public function getFullFKName( + Table $table, + Column $column, + Table $referenceTable, + Column $referenceColumn + ): string { + $fkName = $this->resourceConnection + ->getFkName( + $this->tableNameResolver->getNameOfOriginTable($table->getName()), + $column->getName(), + $referenceTable->getName(), + $referenceColumn->getName() + ); + + return $fkName; + } + + /** + * Provides the foreign key name without prefix value. + * + * @param string $name + * @param Table $table + * @param Column $column + * @param Table $referenceTable + * @param Column $referenceColumn + * @return string + */ + public function getFKNameWithoutPrefix( + string $name, + Table $table, + Column $column, + Table $referenceTable, + Column $referenceColumn + ): string { + $nameWithoutPrefix = $name; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($table->getResource()) + ->getForeignKeyName( + $this->tableNameResolver->getNameOfOriginTable( + $table->getNameWithoutPrefix() + ), + $column->getName(), + $referenceTable->getNameWithoutPrefix(), + $referenceColumn->getName() + ); + } + + return $nameWithoutPrefix; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php index 0e1ad0768c4da..040549a5611ca 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php @@ -7,6 +7,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -39,28 +40,36 @@ class Foreign implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { @@ -68,22 +77,13 @@ public function create(array $data) $data['onDelete'] = self::DEFAULT_ON_DELETE; } - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getForeignKeyName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column']->getName(), - $data['referenceTable']->getNameWithoutPrefix(), - $data['referenceColumn']->getName() - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getFKNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['referenceTable'], + $data['referenceColumn'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php index dd2acd7608867..715f98c4177c0 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php @@ -8,6 +8,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -40,28 +41,36 @@ class Index implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Index::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { @@ -69,29 +78,12 @@ public function create(array $data) $data['indexType'] = self::DEFAULT_INDEX_TYPE; } - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - /** - * Temporary solution. - * @see MAGETWO-91365 - */ - $indexType = AdapterInterface::INDEX_TYPE_INDEX; - if ($data['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { - $indexType = $data['indexType']; - } - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getIndexName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column'], - $indexType - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getIndexNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['indexType'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php index 57e5270b0c82e..141e4a7083200 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php @@ -7,6 +7,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -34,46 +35,45 @@ class Unique implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Internal::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getIndexName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column'], - $data['type'] - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getIndexNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['type'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php index 4f020b1a0320f..11111ea524212 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php @@ -87,11 +87,11 @@ class Table extends GenericElement implements * @param string $engine * @param string $charset * @param string $collation + * @param string $onCreate * @param string|null $comment * @param array $columns * @param array $indexes * @param array $constraints - * @param string $onCreate * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -123,6 +123,7 @@ public function __construct( /** * Return different table constraints. + * * It can be constraint like unique key or reference to another table, etc * * @return Constraint[] @@ -133,6 +134,8 @@ public function getConstraints() } /** + * Provides constraint by name. + * * @param string $name * @return Constraint | bool */ @@ -191,6 +194,8 @@ public function getInternalConstraints() : array } /** + * Provides index by name. + * * @param string $name * @return Index | bool */ @@ -201,6 +206,7 @@ public function getIndexByName($name) /** * Return all columns. + * * Note, table always must have columns * * @return Column[] @@ -280,6 +286,7 @@ public function getColumnByName($nameOrId) /** * Retrieve elements by specific type + * * Allowed types: columns, constraints, indexes... * * @param string $type @@ -296,6 +303,7 @@ public function getElementsByType($type) /** * This is workaround, as any DTO object couldnt be changed after instantiation. + * * However there is case, when we depends on column definition we need modify our indexes * * @param array $indexes @@ -314,6 +322,8 @@ public function getElementType() } /** + * Retrieve engine name. + * * @return string */ public function getEngine(): string @@ -356,6 +366,8 @@ public function getCollation() : string } /** + * Retrieve the table name which is calculated without table prefix. + * * @return string */ public function getNameWithoutPrefix(): string @@ -364,6 +376,8 @@ public function getNameWithoutPrefix(): string } /** + * Retrieve table comment. + * * @return null|string */ public function getComment() diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd index d6436204a32e5..cd08e3f43ad43 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd @@ -19,7 +19,7 @@ </xs:sequence> <xs:attribute name="indexType" type="indexType" /> - <xs:attribute name="referenceId" type="referenceIdType" /> + <xs:attribute name="referenceId" type="referenceIdType" use="required" /> <xs:attribute name="disabled" type="xs:boolean" /> </xs:complexType> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd index 54c8f19753070..a2f8611c4bd33 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd @@ -39,9 +39,38 @@ <xs:element name="schema"> <xs:complexType> <xs:sequence minOccurs="0" maxOccurs="unbounded"> - <xs:element name="table" type="table"/> + <xs:element name="table" type="table"> + <xs:unique name="uniqueColumnName"> + <xs:annotation> + <xs:documentation>Column name be unique for each table</xs:documentation> + </xs:annotation> + <xs:selector xpath="column" /> + <xs:field xpath="@name" /> + </xs:unique> + <xs:unique name="uniqueIndexReferenceId"> + <xs:annotation> + <xs:documentation>Reference ID should be unique for indexes</xs:documentation> + </xs:annotation> + <xs:selector xpath="index" /> + <xs:field xpath="@referenceId" /> + </xs:unique> + <xs:unique name="uniqueConstraintReferenceId"> + <xs:annotation> + <xs:documentation>Reference ID should be unique for constraints</xs:documentation> + </xs:annotation> + <xs:selector xpath="constraint" /> + <xs:field xpath="@referenceId" /> + </xs:unique> + </xs:element> </xs:sequence> </xs:complexType> + <xs:unique name="uniqueTableName"> + <xs:annotation> + <xs:documentation>Table name should be unique for each module</xs:documentation> + </xs:annotation> + <xs:selector xpath="table" /> + <xs:field xpath="@name" /> + </xs:unique> </xs:element> <xs:complexType name="table"> From e17662c47d6cd51a21cdecd0064564ef0560575d Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 22 Oct 2018 10:53:34 -0500 Subject: [PATCH 0721/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../revisions/whitelist_upgrade/db_schema.xml | 60 ++++++ .../revisions/whitelist_upgrade/db_schema.xml | 28 +++ .../TablesWhitelistGenerateCommandTest.php | 172 +++++------------- .../db_schema_whitelist.json | 80 ++++++++ .../db_schema_whitelist.json | 20 ++ 5 files changed, 238 insertions(+), 122 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml create mode 100644 dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json create mode 100644 dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml new file mode 100644 index 0000000000000..90eaf91b10743 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="reference_table" resource="default"> + <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> + <column xsi:type="tinyint" name="tinyint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="bigint" name="bigint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="smallint" name="smallint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="int" name="integer_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="smallint" name="smallint_with_big_padding" padding="254" default="0" nullable="false" + unsigned="false"/> + <column xsi:type="smallint" name="smallint_without_default" padding="2" nullable="true" unsigned="false"/> + <column xsi:type="int" name="int_without_unsigned" padding="2" nullable="true"/> + <column xsi:type="int" name="int_unsigned" padding="2" nullable="true" unsigned="true"/> + <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" + unsigned="true"/> + <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> + <constraint xsi:type="primary" referenceId="tinyint_primary"> + <column name="tinyint_ref"/> + </constraint> + </table> + <table name="test_table" resource="default"> + <!--Columns--> + <column xsi:type="smallint" identity="true" name="smallint" padding="3" nullable="true"/> + <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> + <column xsi:type="bigint" name="bigint" default="0" padding="13" nullable="true" unsigned="false"/> + <column xsi:type="float" name="float" default="0" scale="4" precision="12"/> + <column xsi:type="decimal" name="double" default="11111111.111111" precision="14" scale="6"/> + <column xsi:type="decimal" name="decimal" default="0" scale="4" precision="15"/> + <column xsi:type="date" name="date"/> + <column xsi:type="timestamp" name="timestamp" default="CURRENT_TIMESTAMP" on_update="true"/> + <column xsi:type="datetime" name="datetime" default="0"/> + <column xsi:type="longtext" name="longtext"/> + <column xsi:type="mediumtext" name="mediumtext"/> + <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> + <column xsi:type="mediumblob" name="mediumblob"/> + <column xsi:type="blob" name="blob"/> + <column xsi:type="boolean" name="boolean"/> + <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> + <!--Constraints--> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> + <column name="smallint"/> + <column name="bigint"/> + </constraint> + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" + column="tinyint" table="test_table" + referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> + <!--Indexes--> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> + <column name="tinyint"/> + <column name="bigint"/> + </index> + </table> +</schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml new file mode 100644 index 0000000000000..05ce3318ef73b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="reference_test" resource="default"> + <column xsi:type="smallint" identity="true" name="entity_id" padding="3" nullable="true"/> + <column xsi:type="smallint" identity="true" name="product_id" padding="3" nullable="true"/> + <index referenceId="ENTITY_ID_INDEX" indexType="btree"> + <column name="entity_id"/> + </index> + <constraint xsi:type="unique" referenceId="UNIQUE_PAIR"> + <column name="entity_id"/> + <column name="product_id"/> + </constraint> + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" + column="entity_id" table="reference_test" + referenceTable="test_table" referenceColumn="smallint" onDelete="NO ACTION"/> + </table> + <table name="auto_increment_test" resource="default"> + <column xsi:type="int" name="int_counter" padding="12" unsigned="true" + nullable="true"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php index ef745d9e6fa4a..434c99cb98765 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php @@ -11,6 +11,7 @@ use Magento\TestFramework\TestCase\SetupTestCase; use Magento\Framework\Console\Cli; use Magento\TestFramework\Deploy\CliCommand; +use Magento\TestFramework\Deploy\TestModuleManager; /** * The purpose of this test is to verify the declaration:generate:whitelist command. @@ -42,6 +43,11 @@ class TablesWhitelistGenerateCommandTest extends SetupTestCase */ private $cliCommand; + /** + * @var TestModuleManager + */ + private $moduleManager; + /** * {@inheritdoc} */ @@ -56,21 +62,43 @@ public function setUp() ); $this->cliCommand = $this->objectManager->get(CliCommand::class); $this->tester = new CommandTester($this->command); + $this->moduleManager = $this->objectManager->get(TestModuleManager::class); } /** - * Execute generate command for whitelist on module Magento_TestSetupDeclarationModule1. - * - * @param array $expectedWhitelistContent + * Execute generate command for whitelist. * * @moduleName Magento_TestSetupDeclarationModule1 - * @dataProvider contentsDataProvider + * @moduleName Magento_TestSetupDeclarationModule8 * @throws \Exception */ - public function testExecute(array $expectedWhitelistContent) + public function testExecute() + { + $modules = [ + 'Magento_TestSetupDeclarationModule1', + 'Magento_TestSetupDeclarationModule8', + ]; + + $this->cliCommand->install($modules); + foreach ($modules as $moduleName) { + $this->moduleManager->updateRevision( + $moduleName, + 'whitelist_upgrade', + 'db_schema.xml', + 'etc' + ); + } + + foreach ($modules as $moduleName) { + $this->checkWhitelistFile($moduleName); + } + } + + /** + * @param string $moduleName + */ + private function checkWhitelistFile(string $moduleName) { - $moduleName = 'Magento_TestSetupDeclarationModule1'; - $this->cliCommand->install([$moduleName]); $modulePath = $this->componentRegistrar->getPath('module', $moduleName); $whiteListFileName = $modulePath . DIRECTORY_SEPARATOR @@ -80,125 +108,25 @@ public function testExecute(array $expectedWhitelistContent) //run bin/magento declaration:generate:whitelist Magento_TestSetupDeclarationModule1 command. $this->tester->execute(['--module-name' => $moduleName], ['interactive' => false]); - $this->assertSame(Cli::RETURN_SUCCESS, $this->tester->getStatusCode()); $this->assertFileExists($whiteListFileName); $this->assertContains('', $this->tester->getDisplay()); - $whitelistContent = json_decode(file_get_contents($whiteListFileName), true); - $this->assertEquals($expectedWhitelistContent, $whitelistContent); - } - - /** - * Data provider for whitelist contents. - * - * @return array - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function contentsDataProvider(): array - { - return [ - [ - 'content' => [ - 'reference_table' => - [ - 'column' => - [ - 'tinyint_ref' => true, - 'tinyint_without_padding' => true, - 'bigint_without_padding' => true, - 'integer_without_padding' => true, - 'smallint_with_big_padding' => true, - 'smallint_without_default' => true, - 'int_without_unsigned' => true, - 'int_unsigned' => true, - 'bigint_default_nullable' => true, - 'bigint_not_default_not_nullable' => true, - 'smallint_without_padding' => true, - ], - 'constraint' => - [ - 'tinyint_primary' => true, - 'PRIMARY' => true, - ], - ], - 'auto_increment_test' => - [ - 'column' => - [ - 'int_auto_increment_with_nullable' => true, - 'int_disabled_auto_increment' => true, - ], - 'constraint' => - [ - 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE' => true, - ], - ], - 'test_table' => - [ - 'column' => - [ - 'smallint' => true, - 'tinyint' => true, - 'bigint' => true, - 'float' => true, - 'double' => true, - 'decimal' => true, - 'date' => true, - 'timestamp' => true, - 'datetime' => true, - 'longtext' => true, - 'mediumtext' => true, - 'varchar' => true, - 'mediumblob' => true, - 'blob' => true, - 'boolean' => true, - 'varbinary_rename' => true, - ], - 'index' => - [ - 'TEST_TABLE_TINYINT_BIGINT' => true, - ], - 'constraint' => - [ - 'TEST_TABLE_SMALLINT_BIGINT' => true, - 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => true, - ], - ], - 'store' => - [ - 'column' => - [ - 'store_owner_id' => true, - 'store_owner' => true, - ], - 'constraint' => - [ - 'STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID' => true, - ], - ], - 'store_owner' => - [ - 'column' => - [ - 'owner_id' => true, - 'label' => true, - ], - 'constraint' => - [ - '' => true, - ], - ], - 'some_table' => - [ - 'column' => - [ - 'some_column' => true, - ], - ], - ], - ], - ]; + $whitelistFileContent = file_get_contents($whiteListFileName); + $expectedWhitelistContent = file_get_contents( + dirname(__DIR__, 2) + . DIRECTORY_SEPARATOR + . implode( + DIRECTORY_SEPARATOR, + [ + '_files', + 'WhitelistGenerate', + str_replace('Magento_', '', $moduleName), + 'db_schema_whitelist.json' + ] + ) + ); + $this->assertEquals($expectedWhitelistContent, $whitelistFileContent); } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json new file mode 100644 index 0000000000000..55005b82ab8b5 --- /dev/null +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json @@ -0,0 +1,80 @@ +{ + "reference_table": { + "column": { + "tinyint_ref": true, + "tinyint_without_padding": true, + "bigint_without_padding": true, + "integer_without_padding": true, + "smallint_with_big_padding": true, + "smallint_without_default": true, + "int_without_unsigned": true, + "int_unsigned": true, + "bigint_default_nullable": true, + "bigint_not_default_not_nullable": true, + "smallint_without_padding": true + }, + "constraint": { + "tinyint_primary": true, + "PRIMARY": true + } + }, + "auto_increment_test": { + "column": { + "int_auto_increment_with_nullable": true, + "int_disabled_auto_increment": true + }, + "constraint": { + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true + } + }, + "test_table": { + "column": { + "smallint": true, + "tinyint": true, + "bigint": true, + "float": true, + "double": true, + "decimal": true, + "date": true, + "timestamp": true, + "datetime": true, + "longtext": true, + "mediumtext": true, + "varchar": true, + "mediumblob": true, + "blob": true, + "boolean": true, + "varbinary_rename": true + }, + "index": { + "TEST_TABLE_TINYINT_BIGINT": true + }, + "constraint": { + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true + } + }, + "store": { + "column": { + "store_owner_id": true, + "store_owner": true + }, + "constraint": { + "STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID": true + } + }, + "store_owner": { + "column": { + "owner_id": true, + "label": true + }, + "constraint": { + "": true + } + }, + "some_table": { + "column": { + "some_column": true + } + } +} \ No newline at end of file diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json new file mode 100644 index 0000000000000..b4209edfe471a --- /dev/null +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json @@ -0,0 +1,20 @@ +{ + "reference_test": { + "column": { + "entity_id": true, + "product_id": true + }, + "index": { + "REFERENCE_TEST_ENTITY_ID": true + }, + "constraint": { + "REFERENCE_TEST_ENTITY_ID_PRODUCT_ID": true, + "REFERENCE_TEST_ENTITY_ID_TEST_TABLE_SMALLINT": true + } + }, + "auto_increment_test": { + "column": { + "int_counter": true + } + } +} \ No newline at end of file From e97e0e08bff18bc84f01ce0e9ad6aee7ef70860a Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Mon, 22 Oct 2018 17:46:44 +0300 Subject: [PATCH 0722/1415] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../web/js/model/shipping-rates-validator.js | 16 +++++++++------- .../view/frontend/web/js/view/billing-address.js | 9 +++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index d31c0dca38116..ca11fec7cd5a0 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -35,7 +35,6 @@ define([ var checkoutConfig = window.checkoutConfig, validators = [], observedElements = [], - postcodeElement = null, postcodeElementName = 'postcode'; validators.push(defaultValidator); @@ -79,7 +78,11 @@ define([ } $.each(elements, function (index, field) { - uiRegistry.async(formPath + '.' + field)(self.doElementBinding.bind(self)); + var elementBinding = self.doElementBinding.bind(self), + fullPath = formPath + '.' + field, + func = uiRegistry.async(fullPath); + + func(elementBinding); }); }, @@ -101,7 +104,6 @@ define([ if (element.index === postcodeElementName) { this.bindHandler(element, delay); - postcodeElement = element; } }, @@ -136,7 +138,7 @@ define([ if (!formPopUpState.isVisible()) { clearTimeout(self.validateAddressTimeout); self.validateAddressTimeout = setTimeout(function () { - self.postcodeValidation(); + self.postcodeValidation(element); self.validateFields(); }, delay); } @@ -148,7 +150,7 @@ define([ /** * @return {*} */ - postcodeValidation: function () { + postcodeValidation: function (postcodeElement) { var countryId = $('select[name="country_id"]').val(), validationResult, warnMessage; @@ -178,8 +180,8 @@ define([ */ validateFields: function () { var addressFlat = addressConverter.formDataProviderToFlatData( - this.collectObservedData(), - 'shippingAddress' + this.collectObservedData(), + 'shippingAddress' ), address; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6b5d08c2641cc..6a2f329d095d6 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -17,7 +17,8 @@ define([ 'Magento_Customer/js/customer-data', 'Magento_Checkout/js/action/set-billing-address', 'Magento_Ui/js/model/messageList', - 'mage/translate' + 'mage/translate', + 'Magento_Checkout/js/model/shipping-rates-validator' ], function ( ko, @@ -33,7 +34,8 @@ function ( customerData, setBillingAddressAction, globalMessageList, - $t + $t, + shippingRatesValidator ) { 'use strict'; @@ -71,6 +73,9 @@ function ( quote.paymentMethod.subscribe(function () { checkoutDataResolver.resolveBillingAddress(); }, this); + shippingRatesValidator.initFields( + 'checkout.steps.billing-step.payment.payments-list.checkmo-form.form-fields' + ); }, /** From a8094985b44a5ece2c020021f040ef1aa7b535d1 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Mon, 22 Oct 2018 11:19:22 -0500 Subject: [PATCH 0723/1415] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../db_schema.xml | 13 ++++++++++ .../Setup/DeclarativeInstallerTest.php | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml new file mode 100644 index 0000000000000..a064678394e1a --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" disabled="1"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 33f4b170637c2..4145584f6e48f 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -317,4 +317,29 @@ public function testForeignKeyReferenceId() $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID`/', $tableSql); $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID`/', $tableSql); } + + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @moduleName Magento_TestSetupDeclarationModule8 + */ + public function testDisableIndexByExternalModule() + { + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule1', 'Magento_TestSetupDeclarationModule8'] + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'db_schema.xml', + 'etc' + ); + $this->cliCommad->upgrade(); + $tableStatements = $this->describeTable->describeShard('default'); + $tableSql = $tableStatements['test_table']; + $this->assertNotRegExp( + '/KEY\s+`TEST_TABLE_TINYINT_BIGINT`\s+\(`tinyint`,`bigint`\)/', + $tableSql, + 'Index is not being disabled by external module' + ); + } } From 4e7ad4e90b5d8e031ab8b9e8a7bcbf153eeba4e6 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 22 Oct 2018 11:28:41 -0500 Subject: [PATCH 0724/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../TestModuleDefaultHydrator/etc/db_schema.xml | 4 ++-- .../fixture/valid_xml_revision_1.php | 12 ++++++------ .../Db/MySQL/Definition/Constraints/ForeignKey.php | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml b/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml index d9bba3ca5dbe8..3c71e2fde48fa 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml @@ -11,10 +11,10 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="true"/> <column xsi:type="int" name="customer_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="varchar" name="value" nullable="true" length="255"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_EXTENSION_ATTR_ENTT_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EXTENSION_ATTR_ENTT_CSTR_ID_CSTR_ENTT_ENTT_ID" table="testmodule_default_hydrator_extension_attribute_entity" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index 7271103e3e721..a064d096f6d38 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -225,17 +225,17 @@ ], ], 'constraint' => [ - 'TEST_TABLE_SMALLINT_BIGINT' => [ + 'TEST_TABLE_UNIQUE' => [ 'column' => [ 'smallint' => 'smallint', 'bigint' => 'bigint', ], 'type' => 'unique', - 'referenceId' => 'TEST_TABLE_SMALLINT_BIGINT', + 'referenceId' => 'TEST_TABLE_UNIQUE', ], - 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ + 'TEST_TABLE_TINYINT_REFERENCE' => [ 'type' => 'foreign', - 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -244,12 +244,12 @@ ], ], 'index' => [ - 'TEST_TABLE_TINYINT_BIGINT' => [ + 'TEST_TABLE_INDEX' => [ 'column' => [ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'referenceId' => 'TEST_TABLE_TINYINT_BIGINT', + 'referenceId' => 'TEST_TABLE_INDEX', 'indexType' => 'btree', ], ], diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php index 26bc2209d01ec..6d11542bb49d3 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php @@ -43,7 +43,6 @@ public function __construct(ResourceConnection $resourceConnection) } /** - * @param Reference $foreignKey * @inheritdoc */ public function toDefinition(ElementInterface $foreignKey) From 0225c686065f219a4db02c4000cf5c0562b08874 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 22 Oct 2018 11:48:33 -0500 Subject: [PATCH 0725/1415] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - stabilize test --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 793af65be9d66..9d3b498dc6ce6 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,9 +17,6 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> - <skip> - <issueId value="MAGETWO-95799"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From d76cc54ef23c9f2eec8cc6c832ab16dbb23a6f17 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Mon, 22 Oct 2018 11:50:00 -0500 Subject: [PATCH 0726/1415] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../etc/db_schema.xml | 3 ++ .../revisions/index_to_disable/db_schema.xml | 30 +++++++++++++++++++ .../db_schema.xml | 2 +- .../db_schema_whitelist.json | 7 +++++ .../module.xml | 14 +++++++++ .../Setup/DeclarativeInstallerTest.php | 20 ++++++++++++- 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index ae6c98e4627d2..30cb5b4d166ad 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -65,5 +65,8 @@ <column name="tinyint"/> <column name="bigint"/> </index> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" indexType="btree"> + <column name="varchar"/> + </index> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml new file mode 100644 index 0000000000000..e10803af248c2 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default"> + <!--Columns--> + <column xsi:type="smallint" identity="true" name="smallint" padding="3" nullable="true"/> + <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> + <column xsi:type="bigint" name="bigint" default="0" padding="13" nullable="true" unsigned="false"/> + <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> + <!--Constraints--> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> + <column name="smallint"/> + <column name="bigint"/> + </constraint> + <!--Indexes--> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> + <column name="tinyint"/> + <column name="bigint"/> + </index> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" indexType="btree"> + <column name="varchar"/> + </index> + </table> +</schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml index a064678394e1a..f8860731aa808 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml @@ -8,6 +8,6 @@ <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="test_table" resource="default"> - <index referenceId="TEST_TABLE_TINYINT_BIGINT" disabled="1"/> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" disabled="1"/> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json new file mode 100644 index 0000000000000..a65bb6aab1c43 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json @@ -0,0 +1,7 @@ +{ + "test_table": { + "index": { + "TEST_TABLE_VARCHAR": true + } + } +} diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml new file mode 100644 index 0000000000000..a0b9bbe483bcf --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_TestSetupDeclarationModule8"> + <sequence> + <module name="Magento_TestSetupDeclarationModule1" /> + </sequence> + </module> +</config> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index bf50a5a29821e..f6497e8e4b162 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -343,17 +343,35 @@ public function testDisableIndexByExternalModule() $this->cliCommad->install( ['Magento_TestSetupDeclarationModule1', 'Magento_TestSetupDeclarationModule8'] ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'index_to_disable', + 'db_schema.xml', + 'etc' + ); $this->moduleManager->updateRevision( 'Magento_TestSetupDeclarationModule8', 'disable_index_by_external_module', 'db_schema.xml', 'etc' ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'db_schema_whitelist.json', + 'etc' + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'module.xml', + 'etc' + ); $this->cliCommad->upgrade(); $tableStatements = $this->describeTable->describeShard('default'); $tableSql = $tableStatements['test_table']; $this->assertNotRegExp( - '/KEY\s+`TEST_TABLE_TINYINT_BIGINT`\s+\(`tinyint`,`bigint`\)/', + '/KEY\s+`TEST_TABLE_VARCHAR`\s+\(`varchar`\)/', $tableSql, 'Index is not being disabled by external module' ); From 4526732b81bd6f7dc17894b270ab1ef76360a1a0 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Thu, 18 Oct 2018 11:30:29 +0300 Subject: [PATCH 0727/1415] MAGETWO-94052: CAPTCHA does not appear in "Log in" popup window - Added validation if response is undefined --- .../Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php | 7 ++++--- .../Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php | 2 +- .../view/frontend/web/js/view/checkout/loginCaptcha.js | 7 ++++--- .../view/frontend/web/js/view/authentication-popup.js | 1 - 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php index c67211be31659..f04e9ac8611bc 100644 --- a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php +++ b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php @@ -104,7 +104,7 @@ public function aroundExecute( if (!$captchaModel->isCorrect($captchaString)) { $this->sessionManager->setUsername($username); $captchaModel->logAttempt($username); - return $this->returnJsonError(__('Incorrect CAPTCHA')); + return $this->returnJsonError(__('Incorrect CAPTCHA'), true); } } @@ -118,11 +118,12 @@ public function aroundExecute( * Gets Json response. * * @param \Magento\Framework\Phrase $phrase + * @param bool $isCaptchaRequired * @return Json */ - private function returnJsonError(\Magento\Framework\Phrase $phrase): Json + private function returnJsonError(\Magento\Framework\Phrase $phrase, bool $isCaptchaRequired = false): Json { $resultJson = $this->resultJsonFactory->create(); - return $resultJson->setData(['errors' => true, 'message' => $phrase]); + return $resultJson->setData(['errors' => true, 'message' => $phrase, 'captcha' => $isCaptchaRequired]); } } diff --git a/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php b/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php index ec2a49f3fc566..0764ea36897d1 100644 --- a/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php @@ -158,7 +158,7 @@ public function testAroundExecuteIncorrectCaptcha() $this->resultJsonMock ->expects($this->once()) ->method('setData') - ->with(['errors' => true, 'message' => __('Incorrect CAPTCHA')]) + ->with(['errors' => true, 'message' => __('Incorrect CAPTCHA'), 'captcha' => true]) ->will($this->returnSelf()); $closure = function () { diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js index e017ca6fe274c..a8efd0865bbb8 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js @@ -4,11 +4,12 @@ */ define([ + 'underscore', 'Magento_Captcha/js/view/checkout/defaultCaptcha', 'Magento_Captcha/js/model/captchaList', 'Magento_Customer/js/action/login' ], - function (defaultCaptcha, captchaList, loginAction) { + function (_, defaultCaptcha, captchaList, loginAction) { 'use strict'; return defaultCaptcha.extend({ @@ -25,11 +26,11 @@ define([ this.setCurrentCaptcha(currentCaptcha); loginAction.registerLoginCallback(function (loginData, response) { - if (!response.errors) { + if (!loginData['captcha_form_id'] || loginData['captcha_form_id'] !== self.formId) { return; } - if (!loginData['captcha_form_id'] || loginData['captcha_form_id'] !== self.formId) { + if (_.isUndefined(response) || !response.errors) { return; } diff --git a/app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js b/app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js index c14a59af49706..37bd3a19df638 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js +++ b/app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js @@ -84,7 +84,6 @@ define([ if (formElement.validation() && formElement.validation('isValid') ) { - this.isLoading(true); loginAction(loginData); } From 27fef74756ce331b5ab5da8457d3edd55ba71a63 Mon Sep 17 00:00:00 2001 From: Patrick Maguire <p.maguire@sumoheavy.com> Date: Mon, 22 Oct 2018 13:10:11 -0400 Subject: [PATCH 0728/1415] language cleanup on customer actions --- app/code/Magento/Customer/i18n/en_US.csv | 4 ++-- .../Customer/view/adminhtml/ui_component/customer_listing.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/i18n/en_US.csv b/app/code/Magento/Customer/i18n/en_US.csv index bf73d6361d4c7..578267984f985 100644 --- a/app/code/Magento/Customer/i18n/en_US.csv +++ b/app/code/Magento/Customer/i18n/en_US.csv @@ -506,10 +506,10 @@ Strong,Strong "Rebuild Customer grid index","Rebuild Customer grid index" Group,Group "Add New Customer","Add New Customer" -"Are you sure to delete selected customers?","Are you sure to delete selected customers?" +"Are you sure you want to delete the selected customers?","Are you sure you want to delete the selected customers?" "Delete items","Delete items" "Subscribe to Newsletter","Subscribe to Newsletter" -"Are you sure to unsubscribe selected customers from newsletter?","Are you sure to unsubscribe selected customers from newsletter?" +"Are you sure you want to unsubscribe the selected customers from the newsletter?","Are you sure you want to unsubscribe the selected customers from the newsletter?" "Unsubscribe from Newsletter","Unsubscribe from Newsletter" "Assign a Customer Group","Assign a Customer Group" Phone,Phone diff --git a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml index f8aa078f45e4d..6b479ad1cb290 100644 --- a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml +++ b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml @@ -49,7 +49,7 @@ <action name="delete"> <settings> <confirm> - <message translate="true">Are you sure to delete selected customers?</message> + <message translate="true">Are you sure you want to delete the selected customers?</message> <title translate="true">Delete items @@ -67,7 +67,7 @@ - Are you sure to unsubscribe selected customers from newsletter? + Are you sure you want to unsubscribe the selected customers from the newsletter? Unsubscribe from Newsletter From 97b519cafff9638d9455d9dc2e0aaca3704d805b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Mon, 22 Oct 2018 19:19:21 +0200 Subject: [PATCH 0729/1415] Introduced cart address resolver and data provider --- .../Resolver/Address/AddressDataProvider.php | 70 +++++++++++++++ .../Model/Resolver/CartAddress.php | 87 +++++++++++++++++++ .../SetShippingMethodsOnCart.php | 6 +- .../Magento/QuoteGraphQl/etc/schema.graphqls | 22 ++--- 4 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php new file mode 100644 index 0000000000000..d401f296cb465 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php @@ -0,0 +1,70 @@ +dataObjectConverter = $dataObjectConverter; + } + + /** + * Collect and return information about shipping and billing addresses + * + * @param CartInterface $cart + * @return array + */ + public function getCartAddresses(CartInterface $cart): array + { + $addressData = []; + $shippingAddress = $cart->getShippingAddress(); + $billingAddress = $cart->getBillingAddress(); + + if ($shippingAddress) { + $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); + $shippingData['address_type'] = 'SHIPPING'; + $shippingData['selected_shipping_method'] = [ + 'code' => $shippingAddress->getShippingMethod(), + 'label' => $shippingAddress->getShippingDescription(), + 'free_shipping' => $shippingAddress->getFreeShipping(), + ]; + $shippingData['items_weight'] = $shippingAddress->getWeight(); + $shippingData['customer_notes'] = $shippingAddress->getCustomerNotes(); + $addressData[] = $shippingData; + } + + if ($billingAddress) { + $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); + $billingData['address_type'] = 'BILLING'; + $addressData[] = $billingData; + } + + return $addressData; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php new file mode 100644 index 0000000000000..f83a112ba5ba8 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -0,0 +1,87 @@ +maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->cartRepository = $cartRepository; + $this->addressDataProvider = $addressDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['cart_id'])) { + // TODO: consider the possibility to pass quote model instead od quote ID + throw new LocalizedException(__('"cart_id" value should be specified')); + } + + try { + $quoteId = $this->maskedQuoteIdToQuoteId->execute($value['cart_id']); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $value['cart_id']]) + ); + } + + // TODO: should we check customer permissions here as well? + + try { + $quote = $this->cartRepository->get($quoteId); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%quote_id"', ['quote_id' => $quoteId]) + ); + } + + return $this->addressDataProvider->getCartAddresses($quote); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index c2d14668a2e70..1f35f37d9cf23 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -158,6 +158,10 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__($exception->getMessage())); } - return 'Success!'; // TODO we should return cart here + return [ + 'cart' => [ + 'cart_id' => $maskedCartId + ] + ]; } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 730a54377b370..cbc56bfaea66f 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -67,7 +67,7 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: String #TODO: temp placeholder, should be Cart! + cart: Cart! } # If no address is provided, the system get address assigned to a quote @@ -92,28 +92,28 @@ type ApplyCouponToCartOutput { } type Cart { + cart_id: String items: [CartItemInterface] applied_coupon: AppliedCoupon - addresses: [CartAddress]! + addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddress") } type CartAddress { - firstname: String! - lastname: String! + firstname: String + lastname: String company: String - street: [String!]! - city: String! + street: [String] + city: String region: CartAddressRegion postcode: String - country: CartAddressCountry! - telephone: String! - address_type: AdressTypeEnum! + country: CartAddressCountry + telephone: String + address_type: AdressTypeEnum selected_shipping_method: CheckoutShippingMethod - available_shipping_methods: [CheckoutShippingMethod]! + available_shipping_methods: [CheckoutShippingMethod] items_weight: Float customer_notes: String cart_items: [CartItemQuantity] - applied_coupon: AppliedCoupon } type CartItemQuantity { From 78accc5569841afc37788f45847f11b52c0526c7 Mon Sep 17 00:00:00 2001 From: Mahesh Singh Date: Mon, 22 Oct 2018 23:36:21 +0530 Subject: [PATCH 0730/1415] issue #18655 fixed --- app/code/Magento/Integration/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 5abec8efbfdd6..fe80fe105493a 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -54,7 +54,7 @@ Maximum Number of authentication failures to lock out account. - + Period of time in seconds after which account will be unlocked. From b9af73aac043f0f19786ce5959c464aa857f2044 Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 13:52:55 -0500 Subject: [PATCH 0731/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../Declaration/Schema/WhitelistGenerator.php | 2 +- .../TablesWhitelistGenerateCommandTest.php | 425 ------------------ .../Schema/Config/ConverterTest.php | 6 +- .../Schema/Db/SchemaBuilderTest.php | 8 +- .../Schema/Dto/Factories/ForeignTest.php | 187 -------- 5 files changed, 9 insertions(+), 619 deletions(-) delete mode 100644 app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php delete mode 100644 lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php index af20619934d68..b57abaf816f19 100644 --- a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -255,4 +255,4 @@ private function filterPrimaryTables(array $moduleDbSchema): array } return $moduleDbSchema; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php b/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php deleted file mode 100644 index 5bfc5686b05fb..0000000000000 --- a/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php +++ /dev/null @@ -1,425 +0,0 @@ -componentRegistrarMock = $this->getMockBuilder(ComponentRegistrar::class) - ->disableOriginalConstructor() - ->getMock(); - $this->readerCompositeMock = $this->getMockBuilder(ReaderComposite::class) - ->disableOriginalConstructor() - ->getMock(); - $this->jsonPersistorMock = $this->getMockBuilder(JsonPersistor::class) - ->getMock(); - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $this->objectManagerHelper->getObject( - TablesWhitelistGenerateCommand::class, - [ - 'componentRegistrar' => $this->componentRegistrarMock, - 'readerComposite' => $this->readerCompositeMock, - 'jsonPersistor' => $this->jsonPersistorMock - ] - ); - } - - /** - * @return array - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function whitelistTableProvider() - { - return [ - [ - 'moduleName' => 'SomeModule', - 'whitelist' => [ - 'primary' => [ - 'table' => - [ - 'patch_list' => - [ - 'column' => - [ - 'patch_id' => - [ - 'type' => 'int', - 'name' => 'patch_id', - 'identity' => 'true', - 'comment' => 'Patch Auto Increment', - ], - 'patch_name' => - [ - 'type' => 'varchar', - 'name' => 'patch_name', - 'length' => '1024', - 'nullable' => 'false', - 'comment' => 'Patch Class Name', - ], - ], - 'constraint' => - [ - 'PRIMARY' => - [ - 'column' => - [ - 'patch_id' => 'patch_id', - ], - 'type' => 'primary', - 'name' => 'PRIMARY', - ], - ], - 'name' => 'patch_list', - 'resource' => 'default', - 'comment' => 'List of data/schema patches', - ], - ], - ], - 'SomeModule' => [ - 'table' => [ - 'first_table' => [ - 'disabled' => false, - 'name' => 'first_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'first_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ], - ], - 'expected' => [ - 'SomeModule' => [ - 'first_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ] - ] - ], - [ - 'moduleName' => false, - 'whitelist' => [ - 'primary' => [ - 'table' => - [ - 'patch_list' => - [ - 'column' => - [ - 'patch_id' => - [ - 'type' => 'int', - 'name' => 'patch_id', - 'identity' => 'true', - 'comment' => 'Patch Auto Increment', - ], - 'patch_name' => - [ - 'type' => 'varchar', - 'name' => 'patch_name', - 'length' => '1024', - 'nullable' => 'false', - 'comment' => 'Patch Class Name', - ], - ], - 'constraint' => - [ - 'PRIMARY' => - [ - 'column' => - [ - 'patch_id' => 'patch_id', - ], - 'type' => 'primary', - 'name' => 'PRIMARY', - ], - ], - 'name' => 'patch_list', - 'resource' => 'default', - 'comment' => 'List of data/schema patches', - ], - ], - ], - 'SomeModule' => [ - 'table' => [ - 'first_table' => [ - 'disabled' => false, - 'name' => 'first_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'first_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ], - 'Module2' => [ - 'table' => [ - 'second_table' => [ - 'disabled' => false, - 'name' => 'second_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'second_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ] - ], - 'expected' => [ - 'SomeModule' => [ - 'first_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ], - 'Module2' => [ - 'second_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ] - ] - ] - ]; - } - - /** - * @dataProvider whitelistTableProvider - * @param string $moduleName - * @param array $whiteListTables - * @param array $expected - */ - public function testCommand($moduleName, array $whiteListTables, array $expected) - { - $commandTester = new CommandTester($this->model); - $options = !$moduleName ? [] : ['--module-name' => $moduleName]; - - if (!$moduleName) { - $this->componentRegistrarMock->expects(self::once()) - ->method('getPaths') - ->willReturn(['SomeModule' => 1, 'Module2' => 2]); - $this->readerCompositeMock->expects(self::exactly(3)) - ->method('read') - ->withConsecutive(['SomeModule'], ['primary'], ['Module2']) - ->willReturnOnConsecutiveCalls( - $whiteListTables['SomeModule'], - $whiteListTables['primary'], - $whiteListTables['Module2'] - ); - $this->jsonPersistorMock->expects(self::exactly(2)) - ->method('persist') - ->withConsecutive( - [ - $expected['SomeModule'], - '/etc/db_schema_whitelist.json' - ], - [ - $expected['Module2'], - '/etc/db_schema_whitelist.json' - ] - ); - } else { - $this->readerCompositeMock->expects(self::exactly(2)) - ->method('read') - ->withConsecutive([$moduleName], ['primary']) - ->willReturnOnConsecutiveCalls($whiteListTables['SomeModule'], $whiteListTables['primary']); - $this->jsonPersistorMock->expects(self::once()) - ->method('persist') - ->with( - $expected['SomeModule'], - '/etc/db_schema_whitelist.json' - ); - } - $commandTester->execute($options); - } -} diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php index 2bb4bbcdb8d06..80b0517f7bfd3 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php @@ -46,7 +46,7 @@ public function testConvert() - +
    @@ -74,12 +74,12 @@ public function testConvert() ], ], 'constraint' => [ - 'PRIMARY' => [ + 'PRIMARY_INDEX' => [ 'column' => [ 'id' => 'id', ], 'type' => 'primary', - 'name' => 'PRIMARY', + 'referenceId' => 'PRIMARY_INDEX', ], ], 'name' => 'test_table', diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 15dfcc746407e..88cf36eded3ed 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -299,9 +299,6 @@ public function testBuild(array $columns, array $references, array $constraints, * @param array $references * @param array $constraints * @param array $indexes - * @expectedException \Exception - * @expectedExceptionMessage - * User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table */ public function testBuildUnknownIndexColumn(array $columns, array $references, array $constraints, array $indexes) { @@ -315,6 +312,11 @@ public function testBuildUnknownIndexColumn(array $columns, array $references, a Schema::class, ['resourceConnection' => $resourceConnectionMock] ); + $this->expectException(\PHPUnit\Framework\Exception::class); + $this->expectExceptionCode(E_USER_WARNING); + $this->expectExceptionMessage( + 'User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table.' + ); $this->model->build($schema); } diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php deleted file mode 100644 index ee4331e7bfc5b..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php +++ /dev/null @@ -1,187 +0,0 @@ -objectManagerHelper = new ObjectManagerHelper($this); - $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->adapterMock = $this->getMockBuilder(AdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tableNameResolver = $this->getMockBuilder(TableNameResolver::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->foreignFactory = $this->objectManagerHelper->getObject( - Foreign::class, - [ - 'objectManager' => $this->objectManagerMock, - 'resourceConnection' => $this->resourceConnectionMock, - 'tableNameResolver' => $this->tableNameResolver, - ] - ); - } - - /** - * @param string $prefix - * @dataProvider createDataProvider - */ - public function testCreate(string $prefix) - { - $resource = 'default'; - $tableNameWithoutPrefix = 'table_name'; - $tableName = $prefix . $tableNameWithoutPrefix; - - $columnName = 'entity_id'; - $referenceTableName = 'second_table'; - $referenceColumnName = 'website_id'; - - $foreignKeyNameWithoutPrefix = 'table_name_field_name'; - $foreignKeyName = $prefix . $foreignKeyNameWithoutPrefix; - - $table = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => [ - 'resource' => $resource, - 'name' => $tableName, - 'name_without_prefix' => $tableNameWithoutPrefix, - ], - ] - ); - - $columnMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name' => $columnName], - ] - ); - - $referenceTableMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name_without_prefix' => $referenceTableName], - ] - ); - - $referenceColumnMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name' => $referenceColumnName], - ] - ); - - $data = [ - 'name' => $foreignKeyName, - 'table' => $table, - 'column' => $columnMock, - 'referenceTable' => $referenceTableMock, - 'referenceColumn' => $referenceColumnMock, - ]; - - $expectedData = array_merge( - $data, - [ - 'onDelete' => Foreign::DEFAULT_ON_DELETE, - 'nameWithoutPrefix' => $foreignKeyNameWithoutPrefix, - ] - ); - - $this->resourceConnectionMock - ->method('getTablePrefix') - ->willReturn($prefix); - - $this->resourceConnectionMock - ->method('getConnection') - ->with($resource) - ->willReturn($this->adapterMock); - - $this->tableNameResolver - ->method('getNameOfOriginTable') - ->with($tableNameWithoutPrefix) - ->willReturn($tableNameWithoutPrefix); - - $this->adapterMock - ->method('getForeignKeyName') - ->with($tableNameWithoutPrefix, $columnName, $referenceTableName, $referenceColumnName) - ->willReturn($foreignKeyNameWithoutPrefix); - - $this->objectManagerMock - ->expects($this->once()) - ->method('create') - ->with(Reference::class, $expectedData); - - $this->foreignFactory->create($data); - } - - /** - * @return array - */ - public function createDataProvider(): array - { - return [ - 'Prefix is defined' => [ - 'pref_', - ], - 'Prefix is not defined' => [ - '', - ], - ]; - } -} From 9b99850eda727c39cd8ea074da673b84919ce026 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 14:08:24 -0500 Subject: [PATCH 0732/1415] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../Magento/TestSetupDeclarationModule1/etc/db_schema.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 30cb5b4d166ad..ae6c98e4627d2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -65,8 +65,5 @@ - - - From 1c137111db27932fcfc5f7743f9996b2bd273904 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 14:28:44 -0500 Subject: [PATCH 0733/1415] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 18927b5f4ecca..7d5a097eeea3f 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -10,6 +10,7 @@ "magento/module-authorization": "*", "magento/module-backend": "*", "magento/module-ui": "*", + "magento/module-user": "*", "php": "~7.1.3||~7.2.0" }, "suggest": { From d6b614fc94c1f738700e76830f6bfde774582f08 Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 14:53:43 -0500 Subject: [PATCH 0734/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 2 +- .../Declaration/Schema/WhitelistGenerator.php | 4 +-- .../Declaration/Schema/Config/Converter.php | 2 +- .../TableElement/ElementNameResolver.php | 32 +++++++++---------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 9e1f9252c84b6..2155efa017093 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -79,7 +79,7 @@ protected function execute(InputInterface $input, OutputInterface $output) : int try { $this->whitelistGenerator->generate($moduleName); } catch (ConfigurationMismatchException $e) { - $output->writeln("". $e . ""); + $output->writeln($e->getMessage()); return \Magento\Framework\Console\Cli::RETURN_FAILURE; } catch (\Exception $e) { return \Magento\Framework\Console\Cli::RETURN_FAILURE; diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php index b57abaf816f19..5cdcc6eb99af5 100644 --- a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -161,7 +161,7 @@ private function persistModule(Schema $schema, string $moduleName) } /** - * Provides immutable names of the table elements. + * Provide immutable names of the table elements. * * @param array $tableData * @return array @@ -177,7 +177,7 @@ private function getElementsWithFixedName(array $tableData): array } /** - * Provides autogenerated names of the table elements. + * Provide autogenerated names of the table elements. * * @param Schema $schema * @param string $tableName diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php index 3882afb9f4360..149ad996a5fc4 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php @@ -75,7 +75,7 @@ private function recursiveConvert(\Traversable $source): array } /** - * Provides the value of the ID attribute for each element. + * Provide the value of the ID attribute for each element. * * @param \DOMElement $element * @return string diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php index a3e66b9cf39c5..fe7d1a822dae1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php @@ -14,7 +14,7 @@ use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** - * Provides names of table elements with autogenerated names. + * Provide names of table elements with autogenerated names. */ class ElementNameResolver { @@ -39,7 +39,7 @@ public function __construct(TableNameResolver $tableNameResolver, ResourceConnec } /** - * Provides the full index name based on the prefix value. + * Provide the full index name based on the prefix value. * * @param Table $table * @param string[] $columns @@ -59,12 +59,11 @@ public function getFullIndexName( * Temporary solution. * @see MAGETWO-91365 */ - if ($type - && !array_search( - $type, - [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] - ) - ) { + $isIndexTypeOutOfList = false === array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ); + if ($type && $isIndexTypeOutOfList) { $type = AdapterInterface::INDEX_TYPE_INDEX; } @@ -79,7 +78,7 @@ public function getFullIndexName( } /** - * Provides the index name without prefix value. + * Provide the index name without prefix value. * * @param string $name * @param Table $table @@ -104,12 +103,11 @@ public function getIndexNameWithoutPrefix( * Temporary solution. * @see MAGETWO-91365 */ - if ($type - && !array_search( - $type, - [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] - ) - ) { + $isIndexTypeOutOfList = false === array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ); + if ($type && $isIndexTypeOutOfList) { $type = AdapterInterface::INDEX_TYPE_INDEX; } @@ -128,7 +126,7 @@ public function getIndexNameWithoutPrefix( } /** - * Provides the full foreign key name based on the prefix value. + * Provide the full foreign key name based on the prefix value. * * @param Table $table * @param Column $column @@ -154,7 +152,7 @@ public function getFullFKName( } /** - * Provides the foreign key name without prefix value. + * Provide the foreign key name without prefix value. * * @param string $name * @param Table $table From 1d65e1253bcc6b1f3f979414292a1f1803598a72 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Mon, 22 Oct 2018 15:30:43 -0500 Subject: [PATCH 0735/1415] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env - fix test --- .../Checkout/frontend/js/model/error-processor.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js index 3a6cd6d60d38b..772250eb7c66a 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js @@ -15,7 +15,8 @@ define([ 'mage/url': { /** Method stub. */ build: jasmine.createSpy() - } + }, + 'Magento_Ui/js/model/messageList': jasmine.createSpy('globalList') }, model; @@ -58,6 +59,7 @@ define([ it('check on failed status', function () { var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + spyOn(window.location, 'replace').and.callFake(function () {}); model.process({ status: 401, responseText: '' From 1e9ea2e60bc5959a34347177c2654b34c2cbb443 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 22 Oct 2018 15:31:16 -0500 Subject: [PATCH 0736/1415] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - removed commented out lines --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 9d3b498dc6ce6..11bf03c1d5ee9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -22,13 +22,11 @@ - - From f39dec6732843170b0f43a34bf1ab58b7400093c Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 16:06:07 -0500 Subject: [PATCH 0737/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 88cf36eded3ed..4e0c129204012 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -312,8 +312,7 @@ public function testBuildUnknownIndexColumn(array $columns, array $references, a Schema::class, ['resourceConnection' => $resourceConnectionMock] ); - $this->expectException(\PHPUnit\Framework\Exception::class); - $this->expectExceptionCode(E_USER_WARNING); + $this->expectException(\Exception::class); $this->expectExceptionMessage( 'User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table.' ); From ea6b86b3571890bcaa96ead4f059afebf3489712 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 16:23:37 -0500 Subject: [PATCH 0738/1415] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/etc/db_schema.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 95bd9bdcab283..342326e6666f1 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -27,8 +27,6 @@ - From 622a9a71f7af247a478b603eeab363dee99ac4c4 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 16:33:34 -0500 Subject: [PATCH 0739/1415] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 7d5a097eeea3f..18927b5f4ecca 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -10,7 +10,6 @@ "magento/module-authorization": "*", "magento/module-backend": "*", "magento/module-ui": "*", - "magento/module-user": "*", "php": "~7.1.3||~7.2.0" }, "suggest": { From 3ed1819168cd16b995ddcd652d0aa2b3c07fde17 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim Date: Tue, 23 Oct 2018 09:15:11 +0900 Subject: [PATCH 0740/1415] Remove Duplicate field --- dev/tests/js/jasmine/assets/gallery/config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/js/jasmine/assets/gallery/config.json b/dev/tests/js/jasmine/assets/gallery/config.json index d1d8e94d7f220..72c36293bc152 100644 --- a/dev/tests/js/jasmine/assets/gallery/config.json +++ b/dev/tests/js/jasmine/assets/gallery/config.json @@ -59,8 +59,7 @@ "arrows": "false", "thumbwidth": "90", "thumbheight": "90", - "ratio": "1", - "allowfullscreen": true + "ratio": "1" }, "fullscreen": { "nav": false From 1d4b1610d6b2b6d72e591cef3f7c315b316e390f Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" Date: Tue, 23 Oct 2018 09:44:58 +0300 Subject: [PATCH 0741/1415] MAGETWO-94427: [2.3] Mini cart not getting updated if product disabled from backed --- .../Section/StorefrontMiniCartSection.xml | 16 ++ .../MarkQuotesRecollectMassDisabled.php | 55 +++++++ .../Quote/Model/Quote/TotalsCollector.php | 11 +- .../ResourceModel/Quote/Item/Collection.php | 143 ++++++++++++------ ...atusProductUsingProductGridActionGroup.xml | 33 ++++ .../Mftf/Section/AdminProductGridSection.xml | 14 ++ ...efrontGuestCheckoutDisabledProductTest.xml | 123 +++++++++++++++ app/code/Magento/Quote/etc/di.xml | 3 + 8 files changed, 350 insertions(+), 48 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml create mode 100644 app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php create mode 100644 app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml create mode 100644 app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml create mode 100644 app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml new file mode 100644 index 0000000000000..ff2e5f2f36015 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -0,0 +1,16 @@ + + + + +
    + + + +
    +
    diff --git a/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php b/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php new file mode 100644 index 0000000000000..f18bb46fa63fb --- /dev/null +++ b/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php @@ -0,0 +1,55 @@ +quoteResource = $quoteResource; + } + + /** + * Clean quote items after mass disabling product + * + * @param \Magento\Catalog\Model\Product\Action $subject + * @param \Magento\Catalog\Model\Product\Action $result + * @param int[] $productIds + * @param int[] $attrData + * @param int $storeId + * @return \Magento\Catalog\Model\Product\Action + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterUpdateAttributes( + ProductAction $subject, + ProductAction $result, + $productIds, + $attrData, + $storeId + ): ProductAction { + if (isset($attrData['status']) && $attrData['status'] === Status::STATUS_DISABLED) { + $this->quoteResource->markQuotesRecollect($productIds); + } + + return $result; + } +} diff --git a/app/code/Magento/Quote/Model/Quote/TotalsCollector.php b/app/code/Magento/Quote/Model/Quote/TotalsCollector.php index 8fa03232a0e8d..9442cf2f5f1cb 100644 --- a/app/code/Magento/Quote/Model/Quote/TotalsCollector.php +++ b/app/code/Magento/Quote/Model/Quote/TotalsCollector.php @@ -103,6 +103,8 @@ public function __construct( } /** + * Collect quote totals. + * * @param \Magento\Quote\Model\Quote $quote * @return Address\Total */ @@ -115,6 +117,8 @@ public function collectQuoteTotals(\Magento\Quote\Model\Quote $quote) } /** + * Collect quote. + * * @param \Magento\Quote\Model\Quote $quote * @return \Magento\Quote\Model\Quote\Address\Total */ @@ -172,6 +176,8 @@ public function collect(\Magento\Quote\Model\Quote $quote) } /** + * Validate coupon code. + * * @param \Magento\Quote\Model\Quote $quote * @return $this */ @@ -203,11 +209,12 @@ protected function _validateCouponCode(\Magento\Quote\Model\Quote $quote) */ protected function _collectItemsQtys(\Magento\Quote\Model\Quote $quote) { + $quoteItems = $quote->getAllVisibleItems(); $quote->setItemsCount(0); $quote->setItemsQty(0); $quote->setVirtualItemsQty(0); - foreach ($quote->getAllVisibleItems() as $item) { + foreach ($quoteItems as $item) { if ($item->getParentItem()) { continue; } @@ -231,6 +238,8 @@ protected function _collectItemsQtys(\Magento\Quote\Model\Quote $quote) } /** + * Collect address total. + * * @param \Magento\Quote\Model\Quote $quote * @param Address $address * @return Address\Total diff --git a/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php b/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php index 4ca7d75af9e37..abecec395865d 100644 --- a/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php +++ b/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php @@ -3,9 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Model\ResourceModel\Quote\Item; -use \Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Item as QuoteItem; +use Magento\Quote\Model\ResourceModel\Quote\Item as ResourceQuoteItem; /** * Quote item resource collection @@ -50,6 +57,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\VersionContro */ private $storeManager; + /** + * @var bool $recollectQuote + */ + private $recollectQuote = false; + /** * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger @@ -102,7 +114,7 @@ public function __construct( */ protected function _construct() { - $this->_init(\Magento\Quote\Model\Quote\Item::class, \Magento\Quote\Model\ResourceModel\Quote\Item::class); + $this->_init(QuoteItem::class, ResourceQuoteItem::class); } /** @@ -110,7 +122,7 @@ protected function _construct() * * @return int */ - public function getStoreId() + public function getStoreId(): int { // Fallback to current storeId if no quote is provided // (see https://github.com/magento/magento2/commit/9d3be732a88884a66d667b443b3dc1655ddd0721) @@ -119,12 +131,12 @@ public function getStoreId() } /** - * Set Quote object to Collection + * Set Quote object to Collection. * - * @param \Magento\Quote\Model\Quote $quote + * @param Quote $quote * @return $this */ - public function setQuote($quote) + public function setQuote($quote): self { $this->_quote = $quote; $quoteId = $quote->getId(); @@ -138,13 +150,15 @@ public function setQuote($quote) } /** - * Reset the collection and join it to quotes table. Optionally can select items with specified product id only. + * Reset the collection and inner join it to quotes table. + * + * Optionally can select items with specified product id only * * @param string $quotesTableName * @param int $productId * @return $this */ - public function resetJoinQuotes($quotesTableName, $productId = null) + public function resetJoinQuotes($quotesTableName, $productId = null): self { $this->getSelect()->reset()->from( ['qi' => $this->getResource()->getMainTable()], @@ -161,11 +175,11 @@ public function resetJoinQuotes($quotesTableName, $productId = null) } /** - * After load processing + * After load processing. * * @return $this */ - protected function _afterLoad() + protected function _afterLoad(): self { parent::_afterLoad(); @@ -194,11 +208,11 @@ protected function _afterLoad() } /** - * Add options to items + * Add options to items. * * @return $this */ - protected function _assignOptions() + protected function _assignOptions(): self { $itemIds = array_keys($this->_items); $optionCollection = $this->_itemOptionCollectionFactory->create()->addItemFilter($itemIds); @@ -212,12 +226,12 @@ protected function _assignOptions() } /** - * Add products to items and item options + * Add products to items and item options. * * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function _assignProducts() + protected function _assignProducts(): self { \Magento\Framework\Profiler::start('QUOTE:' . __METHOD__, ['group' => 'QUOTE', 'method' => __METHOD__]); $productCollection = $this->_productCollectionFactory->create()->setStoreId( @@ -239,46 +253,30 @@ protected function _assignProducts() ['collection' => $productCollection] ); - $recollectQuote = false; foreach ($this as $item) { + /** @var ProductInterface $product */ $product = $productCollection->getItemById($item->getProductId()); - if ($product) { + $isValidProduct = $this->isValidProduct($product); + $qtyOptions = []; + if ($isValidProduct) { $product->setCustomOptions([]); - $qtyOptions = []; - $optionProductIds = []; - foreach ($item->getOptions() as $option) { - /** - * Call type-specific logic for product associated with quote item - */ - $product->getTypeInstance()->assignProductToOption( - $productCollection->getItemById($option->getProductId()), - $option, - $product - ); - - if (is_object($option->getProduct()) && $option->getProduct()->getId() != $product->getId()) { - $optionProductIds[$option->getProduct()->getId()] = $option->getProduct()->getId(); - } - } - - if ($optionProductIds) { - foreach ($optionProductIds as $optionProductId) { - $qtyOption = $item->getOptionByCode('product_qty_' . $optionProductId); - if ($qtyOption) { - $qtyOptions[$optionProductId] = $qtyOption; - } + $optionProductIds = $this->getOptionProductIds($item, $product, $productCollection); + foreach ($optionProductIds as $optionProductId) { + $qtyOption = $item->getOptionByCode('product_qty_' . $optionProductId); + if ($qtyOption) { + $qtyOptions[$optionProductId] = $qtyOption; } } - - $item->setQtyOptions($qtyOptions)->setProduct($product); } else { $item->isDeleted(true); - $recollectQuote = true; + $this->recollectQuote = true; + } + if (!$item->isDeleted()) { + $item->setQtyOptions($qtyOptions)->setProduct($product); + $item->checkData(); } - $item->checkData(); } - - if ($recollectQuote && $this->_quote) { + if ($this->recollectQuote && $this->_quote) { $this->_quote->collectTotals(); } \Magento\Framework\Profiler::stop('QUOTE:' . __METHOD__); @@ -286,6 +284,57 @@ protected function _assignProducts() return $this; } + /** + * Get product Ids from option. + * + * @param QuoteItem $item + * @param ProductInterface $product + * @param ProductCollection $productCollection + * @return array + */ + private function getOptionProductIds( + QuoteItem $item, + ProductInterface $product, + ProductCollection $productCollection + ): array { + $optionProductIds = []; + foreach ($item->getOptions() as $option) { + /** + * Call type-specific logic for product associated with quote item + */ + $product->getTypeInstance()->assignProductToOption( + $productCollection->getItemById($option->getProductId()), + $option, + $product + ); + + if (is_object($option->getProduct()) && $option->getProduct()->getId() != $product->getId()) { + $isValidProduct = $this->isValidProduct($option->getProduct()); + if (!$isValidProduct && !$item->isDeleted()) { + $item->isDeleted(true); + $this->recollectQuote = true; + continue; + } + $optionProductIds[$option->getProduct()->getId()] = $option->getProduct()->getId(); + } + } + + return $optionProductIds; + } + + /** + * Check is valid product. + * + * @param ProductInterface $product + * @return bool + */ + private function isValidProduct(ProductInterface $product): bool + { + $result = ($product && (int)$product->getStatus() !== ProductStatus::STATUS_DISABLED); + + return $result; + } + /** * Prevents adding stock status filter to the collection of products. * @@ -294,7 +343,7 @@ protected function _assignProducts() * * @see \Magento\CatalogInventory\Helper\Stock::addIsInStockFilterToCollection */ - private function skipStockStatusFilter(ProductCollection $productCollection) + private function skipStockStatusFilter(ProductCollection $productCollection): void { $productCollection->setFlag('has_stock_status_filter', true); } @@ -304,7 +353,7 @@ private function skipStockStatusFilter(ProductCollection $productCollection) * * @return void */ - private function removeItemsWithAbsentProducts() + private function removeItemsWithAbsentProducts(): void { if (count($this->_productIds) === 0) { return; diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml new file mode 100644 index 0000000000000..dba4a94f3db2a --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml new file mode 100644 index 0000000000000..32ac73aca7c03 --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml @@ -0,0 +1,14 @@ + + + + +
    + +
    +
    diff --git a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml new file mode 100644 index 0000000000000..ab0db2dac643e --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml @@ -0,0 +1,123 @@ + + + + + + + + + <description value="Remove item from cart if simple or configurable product is disabled"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95857"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create the configurable product based on the data in the /data folder --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Make the configurable product have two options, that are children of the default attribute set --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the 2 children that will be a part of the configurable product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Assign the two products to the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + <!-- Step 1: Add simple product to shopping cart --> + <amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.name$$)}}" stepKey="amOnSimpleProductPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="AddSimpleProductToCart" stepKey="cartAddSimpleProductToCart"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <amOnPage url="{{StorefrontProductPage.url($$createConfigProduct.custom_attributes[url_key]$$)}}" stepKey="goToConfigProductPage"/> + <waitForPageLoad stepKey="waitForStoreFrontLoad"/> + <selectOption selector="{{StorefrontProductInfoMainSection.productAttributeOptionsSelectButton}}" userInput="$$getConfigAttributeOption1.value$$" stepKey="selectOption"/> + <click selector="{{StorefrontProductInfoMainSection.AddToCart}}" stepKey="clickAddToCart" /> + <waitForElement selector="{{StorefrontMessagesSection.messageProductAddedToCart($$createConfigProduct.name$$)}}" time="30" stepKey="assertMessage"/> + <!--Disabled via admin panel--> + <openNewTab stepKey="openNewTab"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!-- Find the first simple product that we just created using the product grid and go to its page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductGridLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <waitForPageLoad stepKey="waitForFiltersToBeApplied"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <!-- Disabled child configurable product --> + <click selector="{{AdminProductFormSection.enableProductAttributeLabel}}" stepKey="clickDisableProduct"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForProductPageSaved"/> + <!-- Disabled simple product from grid --> + <actionGroup ref="ChangeStatusProductUsingProductGridActionGroup" stepKey="disabledProductFromGrid"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="status" value="Disable"/> + </actionGroup> + <closeTab stepKey="closeTab"/> + <!--Check cart--> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForCheckoutPageReload2"/> + <click selector="{{StorefrontMiniCartSection.show}}" stepKey="clickMiniCart"/> + <dontSeeElement selector="{{StorefrontMiniCartSection.quantity}}" stepKey="dontSeeCartItem"/> + </test> +</tests> diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index bc131b2987a8c..cd5e62307fdca 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -98,6 +98,9 @@ <plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/> <plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/> </type> + <type name="Magento\Catalog\Model\Product\Action"> + <plugin name="quoteProductMassChange" type="Magento\Quote\Model\Product\Plugin\MarkQuotesRecollectMassDisabled"/> + </type> <type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite"> <arguments> <argument name="validationRules" xsi:type="array"> From 937f5bcde4130966fc440df17a2a45e14717126d Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 13:59:25 +0530 Subject: [PATCH 0742/1415] Replace intval() function by using direct type casting to (int) --- .../Quote/Api/CartTotalRepositoryTest.php | 30 +++++++++---------- .../Mtf/Util/Generate/Fixture/SchemaXml.php | 2 +- .../Constraint/AssertProductDuplicateForm.php | 2 +- .../Handler/CatalogProductSimple/Curl.php | 2 +- ...AssertConfigurableProductDuplicateForm.php | 2 +- .../Store/Test/Handler/StoreGroup/Curl.php | 2 +- .../Store/Test/Handler/Website/Curl.php | 2 +- .../Edit/Tab/View/PersonalInfoTest.php | 4 +-- pub/errors/processor.php | 2 +- .../Magento/Setup/Model/PhpReadinessCheck.php | 8 ++--- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php index 609ae1cfe094c..a001cae645434 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php @@ -162,22 +162,22 @@ protected function getQuoteItemTotalsData(\Magento\Quote\Model\Quote $quote) $item = array_shift($items); return [ ItemTotals::KEY_ITEM_ID => $item->getItemId(), - ItemTotals::KEY_PRICE => intval($item->getPrice()), - ItemTotals::KEY_BASE_PRICE => intval($item->getBasePrice()), + ItemTotals::KEY_PRICE => (int)$item->getPrice(), + ItemTotals::KEY_BASE_PRICE => (int)$item->getBasePrice(), ItemTotals::KEY_QTY => $item->getQty(), - ItemTotals::KEY_ROW_TOTAL => intval($item->getRowTotal()), - ItemTotals::KEY_BASE_ROW_TOTAL => intval($item->getBaseRowTotal()), - ItemTotals::KEY_ROW_TOTAL_WITH_DISCOUNT => intval($item->getRowTotalWithDiscount()), - ItemTotals::KEY_TAX_AMOUNT => intval($item->getTaxAmount()), - ItemTotals::KEY_BASE_TAX_AMOUNT => intval($item->getBaseTaxAmount()), - ItemTotals::KEY_TAX_PERCENT => intval($item->getTaxPercent()), - ItemTotals::KEY_DISCOUNT_AMOUNT => intval($item->getDiscountAmount()), - ItemTotals::KEY_BASE_DISCOUNT_AMOUNT => intval($item->getBaseDiscountAmount()), - ItemTotals::KEY_DISCOUNT_PERCENT => intval($item->getDiscountPercent()), - ItemTotals::KEY_PRICE_INCL_TAX => intval($item->getPriceInclTax()), - ItemTotals::KEY_BASE_PRICE_INCL_TAX => intval($item->getBasePriceInclTax()), - ItemTotals::KEY_ROW_TOTAL_INCL_TAX => intval($item->getRowTotalInclTax()), - ItemTotals::KEY_BASE_ROW_TOTAL_INCL_TAX => intval($item->getBaseRowTotalInclTax()), + ItemTotals::KEY_ROW_TOTAL => (int)$item->getRowTotal(), + ItemTotals::KEY_BASE_ROW_TOTAL => (int)$item->getBaseRowTotal(), + ItemTotals::KEY_ROW_TOTAL_WITH_DISCOUNT => (int)$item->getRowTotalWithDiscount(), + ItemTotals::KEY_TAX_AMOUNT => (int)$item->getTaxAmount(), + ItemTotals::KEY_BASE_TAX_AMOUNT => (int)$item->getBaseTaxAmount(), + ItemTotals::KEY_TAX_PERCENT => (int)$item->getTaxPercent(), + ItemTotals::KEY_DISCOUNT_AMOUNT => (int)$item->getDiscountAmount(), + ItemTotals::KEY_BASE_DISCOUNT_AMOUNT => (int)$item->getBaseDiscountAmount(), + ItemTotals::KEY_DISCOUNT_PERCENT => (int)$item->getDiscountPercent(), + ItemTotals::KEY_PRICE_INCL_TAX => (int)$item->getPriceInclTax(), + ItemTotals::KEY_BASE_PRICE_INCL_TAX => (int)$item->getBasePriceInclTax(), + ItemTotals::KEY_ROW_TOTAL_INCL_TAX => (int)$item->getRowTotalInclTax(), + ItemTotals::KEY_BASE_ROW_TOTAL_INCL_TAX => (int)$item->getBaseRowTotalInclTax(), ItemTotals::KEY_WEEE_TAX_APPLIED_AMOUNT => $item->getWeeeTaxAppliedAmount(), ItemTotals::KEY_WEEE_TAX_APPLIED => $item->getWeeeTaxApplied(), ItemTotals::KEY_NAME => $item->getName(), diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php b/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php index aa85299deea44..6d1d5b6f4b349 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php +++ b/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php @@ -145,7 +145,7 @@ protected function generateFixtureXml(array $config) foreach ($fields as $fieldName => $fieldValue) { $field = $this->dom->createElement('field'); $field->setAttribute('name', $fieldName); - $field->setAttribute('is_required', intval($fieldValue['is_required'])); + $field->setAttribute('is_required', (int)$fieldValue['is_required']); $fixture->appendChild($field); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php index f65aa33ff93e3..d5cf5d918817d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php @@ -116,7 +116,7 @@ function (&$item, $key, $formattingOptions) { protected function prepareUrlKey($urlKey) { preg_match("~\d+$~", $urlKey, $matches); - $key = intval($matches[0]) + 1; + $key = (int)$matches[0] + 1; return str_replace($matches[0], $key, $urlKey); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php index c75112fee8605..2a23903a697b3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php @@ -411,7 +411,7 @@ protected function prepareQuantityAndStockStatus() : ['is_in_stock' => 'In Stock']; if (!isset($quantityAndStockStatus['is_in_stock'])) { - $qty = isset($quantityAndStockStatus['qty']) ? intval($quantityAndStockStatus['qty']) : null; + $qty = isset($quantityAndStockStatus['qty']) ? (int)$quantityAndStockStatus['qty'] : null; $quantityAndStockStatus['is_in_stock'] = 0 === $qty ? 'Out of Stock' : 'In Stock'; } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php index 02cb304325c24..c50f0e338c20f 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php @@ -70,7 +70,7 @@ protected function prepareFixtureData(array $data, array $sortFields = []) protected function prepareUrlKey($urlKey) { preg_match("~\d+$~", $urlKey, $matches); - $key = intval($matches[0]) + 1; + $key = (int)$matches[0] + 1; return str_replace($matches[0], $key, $urlKey); } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php index 10ebd2b6d5f66..0c1017410961f 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php @@ -65,7 +65,7 @@ protected function getStoreGroupIdByGroupName($storeName) throw new \Exception('Cannot find store group id'); } - return intval($matches[1]); + return (int)$matches[1]; } /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php index ab0b1f2096808..0b738c5e159cd 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php @@ -119,7 +119,7 @@ protected function getWebSiteIdByWebsiteName($websiteName) throw new \Exception('Cannot find website id.'); } - return intval($matches[1]); + return (int)$matches[1]; } /** diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php index 8d82ad94dfab4..161734f47bfd7 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php @@ -110,9 +110,9 @@ public function testGetCustomer() \Magento\Customer\Api\Data\CustomerInterface::class ); foreach ($expectedCustomerData as $property => $value) { - $expectedValue = is_numeric($value) ? intval($value) : $value; + $expectedValue = is_numeric($value) ? (int)$value : $value; $actualValue = isset($actualCustomerData[$property]) ? $actualCustomerData[$property] : null; - $actualValue = is_numeric($actualValue) ? intval($actualValue) : $actualValue; + $actualValue = is_numeric($actualValue) ? (int)$actualValue : $actualValue; $this->assertEquals($expectedValue, $actualValue); } } diff --git a/pub/errors/processor.php b/pub/errors/processor.php index e64956dce17c2..ee8c9331097f7 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -466,7 +466,7 @@ protected function _setReportData($reportData) public function saveReport($reportData) { $this->reportData = $reportData; - $this->reportId = abs(intval(microtime(true) * random_int(100, 1000))); + $this->reportId = abs((int)(microtime(true) * random_int(100, 1000))); $this->_reportFile = $this->_reportDir . '/' . $this->reportId; $this->_setReportData($reportData); diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index 2c4967c4c2ffd..98da6cb7a5e0f 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -192,7 +192,7 @@ public function checkMemoryLimit() $currentMemoryLimit = ini_get('memory_limit'); - $currentMemoryInteger = intval($currentMemoryLimit); + $currentMemoryInteger = (int)$currentMemoryLimit; if ($currentMemoryInteger > 0 && $this->dataSize->convertSizeToBytes($currentMemoryLimit) @@ -244,7 +244,7 @@ private function checkXDebugNestedLevel() $currentExtensions = $this->phpInformation->getCurrent(); if (in_array('xdebug', $currentExtensions)) { - $currentXDebugNestingLevel = intval(ini_get('xdebug.max_nesting_level')); + $currentXDebugNestingLevel = (int)ini_get('xdebug.max_nesting_level'); $minimumRequiredXDebugNestedLevel = $this->phpInformation->getRequiredMinimumXDebugNestedLevel(); if ($minimumRequiredXDebugNestedLevel > $currentXDebugNestingLevel) { @@ -286,7 +286,7 @@ private function checkPopulateRawPostSetting() $data = []; $error = false; - $iniSetting = intval(ini_get('always_populate_raw_post_data')); + $iniSetting = (int)ini_get('always_populate_raw_post_data'); $checkVersionConstraint = $this->versionParser->parseConstraints('~5.6.0'); $normalizedPhpVersion = $this->getNormalizedCurrentPhpVersion(PHP_VERSION); @@ -302,7 +302,7 @@ private function checkPopulateRawPostSetting() Please open your php.ini file and set always_populate_raw_post_data to -1. If you need more help please call your hosting provider.', PHP_VERSION, - intval(ini_get('always_populate_raw_post_data')) + (int)ini_get('always_populate_raw_post_data') ); $data['always_populate_raw_post_data'] = [ From a9035918c120cba9dc139ad5240f78bc9c31ff29 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 23 Oct 2018 13:19:03 +0300 Subject: [PATCH 0743/1415] magento-engcom/magento2ce#2262: Code style fixes --- .../AdminNotification/Block/Window.php | 2 ++ .../Braintree/Controller/Paypal/Review.php | 5 +++- .../Magento/Framework/App/Config/Value.php | 8 +++--- .../Framework/App/Config/ValueInterface.php | 7 +++--- pub/errors/processor.php | 25 +++++++++++++------ 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Window.php b/app/code/Magento/AdminNotification/Block/Window.php index 90a0a1d21d865..e9b4bfa44893d 100644 --- a/app/code/Magento/AdminNotification/Block/Window.php +++ b/app/code/Magento/AdminNotification/Block/Window.php @@ -8,6 +8,8 @@ namespace Magento\AdminNotification\Block; /** + * Admin notification window block + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index e6a1dcbc34559..14ec829d98024 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -12,11 +12,12 @@ use Magento\Braintree\Gateway\Config\PayPal\Config; use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Class Review */ -class Review extends AbstractAction +class Review extends AbstractAction implements HttpPostActionInterface { /** * @var QuoteUpdater @@ -91,6 +92,8 @@ public function execute() } /** + * Validate request data + * * @param array $requestData * @return boolean */ diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 7ba4225ce2fb8..9326fa4fa3f72 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -113,9 +113,9 @@ public function getFieldsetDataValue($key) } /** - * {@inheritdoc} + * @inheritdoc * - * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches + * @inheritdoc. In addition, it sets status 'invalidate' for config caches * * @return $this */ @@ -129,9 +129,9 @@ public function afterSave() } /** - * {@inheritdoc} + * @inheritdoc * - * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches + * @inheritdoc. In addition, it sets status 'invalidate' for config caches * * @return $this */ diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 37e821f026869..6f2b6f37aca72 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,9 +9,9 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * - * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going - * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new interface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface @@ -23,6 +23,7 @@ interface ValueInterface /** * Check if config data value was changed + * * @todo this method should be make as protected * @return bool */ diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 2a7785f532f76..32fab8d0b0780 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -257,13 +257,7 @@ public function getHostUrl() /** * Define server http host */ - if (!empty($_SERVER['HTTP_HOST'])) { - $host = $_SERVER['HTTP_HOST']; - } elseif (!empty($_SERVER['SERVER_NAME'])) { - $host = $_SERVER['SERVER_NAME']; - } else { - $host = 'localhost'; - } + $host = $this->resolveHostName(); $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] !== 'off') || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); @@ -278,6 +272,23 @@ public function getHostUrl() return $url; } + /** + * Resolve hostname + * + * @return string + */ + private function resolveHostName() : string + { + if (!empty($_SERVER['HTTP_HOST'])) { + $host = $_SERVER['HTTP_HOST']; + } elseif (!empty($_SERVER['SERVER_NAME'])) { + $host = $_SERVER['SERVER_NAME']; + } else { + $host = 'localhost'; + } + return $host; + } + /** * Retrieve base URL * From c3b3864118cccc1529e58e76bc25e5a3c42e6365 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 23 Oct 2018 16:03:16 +0300 Subject: [PATCH 0744/1415] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Fix statics. --- .../Model/Product/Gallery/GalleryManagement.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4be4bb09efc98..4a6cc09d11920 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,13 +7,15 @@ namespace Magento\Catalog\Model\Product\Gallery; use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface; -use Magento\Catalog\Api\Data\ProductInterface as Product; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; use Magento\Framework\Api\ImageContentValidatorInterface; /** + * Class GalleryManagement + * Provides implementation of api interface ProductAttributeMediaGalleryManagementInterface + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface @@ -44,7 +45,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) { @@ -84,7 +85,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) } /** - * {@inheritdoc} + * @inheritdoc */ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) { @@ -125,7 +126,7 @@ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) } /** - * {@inheritdoc} + * @inheritdoc */ public function remove($sku, $entryId) { @@ -155,7 +156,7 @@ public function remove($sku, $entryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function get($sku, $entryId) { @@ -176,7 +177,7 @@ public function get($sku, $entryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { From 413120a87e73dabfe9f7bfefa989f6aa72e805fd Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Tue, 23 Oct 2018 16:48:05 +0300 Subject: [PATCH 0745/1415] MAGETWO-95539: [2.3] Moving Category generate duplicate url_rewrite when 4th level category exist and is translated - Fixed url rewrites regeneration after category moving --- .../CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php | 1 - .../Test/Unit/Model/Category/Plugin/Category/MoveTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php index fcdc21bedc5f8..f3984bf7d62ab 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php @@ -64,7 +64,6 @@ public function afterChangeParent( Category $newParent, $afterCategoryId ) { - $categoryStoreId = $category->getStoreId(); foreach ($category->getStoreIds() as $storeId) { $category->setStoreId($storeId); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php index b69aabe76c35e..85e8837027151 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php @@ -69,7 +69,7 @@ protected function setUp() ->getMock(); $this->categoryMock = $this->getMockBuilder(Category::class) ->disableOriginalConstructor() - ->setMethods(['getResource', 'setUrlPath', 'getStoreIds']) + ->setMethods(['getResource', 'setUrlPath', 'getStoreIds', 'getStoreId', 'setStoreId']) ->getMock(); $this->plugin = $this->objectManager->getObject( CategoryMovePlugin::class, From c30ab0c9103860e29db5d1cac843d1d748bd8ebe Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 23 Oct 2018 17:05:28 +0300 Subject: [PATCH 0746/1415] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Fix statics. --- .../Magento/Catalog/Model/Product/Gallery/GalleryManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4a6cc09d11920..0e08b0af92862 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -14,6 +14,7 @@ /** * Class GalleryManagement + * * Provides implementation of api interface ProductAttributeMediaGalleryManagementInterface * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) From f66d26afbbe9e44afb800a6255213e11ae8fab72 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:01:19 +0200 Subject: [PATCH 0747/1415] Added debug information for checking tests modules are deployed --- dev/tests/integration/framework/deployTestModules.php | 4 +++- dev/travis/before_script.sh | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index 4c894d80f9800..f7be2b8414d23 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -1,4 +1,4 @@ -<?php +x<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. @@ -38,3 +38,5 @@ foreach ($files as $file) { include $file; } + +echo "\n\n TEST MODULES WERE DEPLOYED \n\n"; // DEBUG diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 52fd44c2826cc..c27e65d3897c7 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,9 +152,6 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" - php bin/magento module:status # DEBUG - php bin/magento setup:upgrade # DEBUG - echo "Enabling production mode" php bin/magento deploy:mode:set production From 2736ff910b56784ffe8513dec151d31b854dba65 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Tue, 23 Oct 2018 10:11:20 -0500 Subject: [PATCH 0748/1415] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Added MFTF case to cover the scenario MAGETWO-95213. Associated with Zephyr test MAGETWO-59361 --- .../ActionGroup/AdminProductActionGroup.xml | 21 +++ .../Catalog/Test/Mftf/Data/ProductData.xml | 30 ++++ .../Section/AdminProductFiltersSection.xml | 2 + .../Mftf/Section/AdminProductGridSection.xml | 1 + ...sUpdateProductStatusStoreViewScopeTest.xml | 151 ++++++++++++++++++ .../AdminFilterStoreViewActionGroup.xml | 21 +++ 6 files changed, 226 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml create mode 100644 app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9f8d827b20849..f06cc816e8595 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -277,4 +277,25 @@ <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> + <!--Create a Simple Product--> + <actionGroup name="createSimpleProductAndAddToWebsite"> + <arguments> + <argument name="product"/> + <argument name="website" type="string"/> + </arguments> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToCatalogProductGrid"/> + <waitForPageLoad stepKey="waitForProductGrid"/> + <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> + <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> + <fillField userInput="{{product.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillProductName"/> + <fillField userInput="{{product.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillProductSKU"/> + <fillField userInput="{{product.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillProductPrice"/> + <fillField userInput="{{product.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillProductQuantity"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openProductInWebsites"/> + <click selector="{{ProductInWebsitesSection.website(website)}}" stepKey="selectWebsite"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSave"/> + <waitForLoadingMaskToDisappear stepKey="waitForProductPageSave"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessage"/> + </actionGroup> + </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 7c0cc03186c6e..494335dd56f13 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -420,4 +420,34 @@ <data key="status">1</data> <requiredEntity type="product_extension_attribute">EavStock100</requiredEntity> </entity> + <entity name="simpleProductForMassUpdate" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">massUpdateProductName</data> + <data key="keyword">massUpdateProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">masstesturlkey</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> + <entity name="simpleProductForMassUpdate2" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">massUpdateProductName</data> + <data key="keyword">massUpdateProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">masstesturlkey</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml index 7a9de9670f216..06ff54b2a3997 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml @@ -28,5 +28,7 @@ <element name="priceOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> <element name="AllProductsNotOfBundleType" type="text" selector="//td[5]/div[text() != 'Bundle Product']"/> <element name="attributeSetOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> + <element name="storeViewDropDown" type="multiselect" selector="//select[@name='store_id']" timeout="30"/> + <element name="storeViewOption" type="multiselect" selector="//select[@name='store_id']/option[contains(text(),'{{var1}}')]" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml index a7e20e22f1ddc..d12233206ce41 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml @@ -28,6 +28,7 @@ <element name="firstRow" type="button" selector="tr.data-row:nth-of-type(1)"/> <element name="productGridCheckboxOnRow" type="checkbox" selector="//*[@id='container']//tr[{{row}}]/td[1]//input" parameterized="true"/> <element name="productGridNameProduct" type="input" selector="//tbody//tr//td//div[contains(., '{{var1}}')]" parameterized="true" timeout="30"/> + <element name="productGridContentsOnRow" type="checkbox" selector="//*[@id='container']//tr[{{row}}]/td" parameterized="true"/> <element name="selectRowBasedOnName" type="input" selector="//td/div[text()='{{var1}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml new file mode 100644 index 0000000000000..6d1f266f4c66b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMassUpdateProductStatusStoreViewScopeTest"> + <annotations> + <features value="Catalog"/> + <stories value="Mass update product status"/> + <title value="Admin should be able to mass update product statuses in store view scope"/> + <description value="Admin should be able to mass update product statuses in store view scope"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-59361"/> + <group value="Catalog"/> + <group value="Product Attributes"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + + <!--Create Website --> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + + <!--Create Store --> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + + <!--Create Store view --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <waitForPageLoad stepKey="waitForSystemStorePage"/> + <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <waitForElementVisible selector="//legend[contains(., 'Store View Information')]" stepKey="waitForNewStorePageToOpen"/> + <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> + <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> + <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="1" stepKey="enableStoreViewStatus"/> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2" time="180" /> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" time="150" stepKey="waitForPageReolad"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + + <!--Create a Simple Product 1 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct1"> + <argument name="product" value="simpleProductForMassUpdate"/> + <argument name="website" value="Second Website"/> + </actionGroup> + + <!--Create a Simple Product 2 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct2"> + <argument name="product" value="simpleProductForMassUpdate2"/> + <argument name="website" value="Second Website"/> + </actionGroup> + </before> + <after> + <!--Delete website --> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + + <!--Delete Products --> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct1"> + <argument name="productName" value="simpleProductForMassUpdate.name"/> + </actionGroup> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct2"> + <argument name="productName" value="simpleProductForMassUpdate2.name"/> + </actionGroup> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Search and select products --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="searchProductGridByKeyword2" stepKey="searchByKeyword"> + <argument name="keyword" value="{{simpleProductForMassUpdate.keyword}}"/> + </actionGroup> + <actionGroup ref="sortProductsByIdDescending" stepKey="sortProductsByIdDescending"/> + + <!-- Filter to Second Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterStoreView" > + <argument name="customStore" value="'Second Store View'" /> + </actionGroup> + + <!-- Select Product 2 --> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckbox2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOption"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabled"/> + <waitForPageLoad stepKey="waitForBulkUpdatePage"/> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabled"/> + + <!-- Filter to Default Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterDefaultStoreView"> + <argument name="customStore" value="'Default'" /> + </actionGroup> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct2IsEnabled"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> + <argument name="name" value="{{simpleProductForMassUpdate.keyword}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> + <see userInput="2 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + + <!-- Enable the product in Default store view --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex2"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad2"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('1')}}" stepKey="clickCheckboxDefaultStoreView"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckboxDefaultStoreView2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdownDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOptionDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabledDefaultStoreView"/> + <waitForPageLoad stepKey="waitForBulkUpdatePageDefaultStoreView"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabledDefaultStoreView"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault2"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault2"> + <argument name="name" value="{{simpleProductForMassUpdate.name}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault2"/> + <see userInput="We can't find any items matching these search criteria." selector="{{StorefrontCatalogSearchAdvancedResultMainSection.message}}" stepKey="seeInDefault2"/> + </test> +</tests> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml new file mode 100644 index 0000000000000..e4cb26ea6ff7a --- /dev/null +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminFilterStoreViewActionGroup"> + <arguments> + <argument name="StoreGroup" defaultValue="_defaultStoreGroup"/> + <argument name="customStore" defaultValue="customStore.name"/> + </arguments> + <click selector="{{AdminProductFiltersSection.filter}}" stepKey="ClickOnFilter"/> + <click selector="{{AdminProductFiltersSection.storeViewDropDown}}" stepKey="ClickOnStoreViewDropDown"/> + <click selector="{{AdminProductFiltersSection.storeViewOption(customStore)}}" stepKey="ClickOnStoreViewOption"/> + <click selector="{{AdminProductFiltersSection.applyFilters}}" stepKey="ClickOnApplyFilters"/> + </actionGroup> +</actionGroups> From 66329bbd41a6aac1d454c73c4e826e547dc81a02 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:43:50 +0200 Subject: [PATCH 0749/1415] More details in debug information about deployed modules --- dev/tests/integration/framework/deployTestModules.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index f7be2b8414d23..6e57d748a55eb 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -25,6 +25,7 @@ mkdir($targetDir, 0755, true); } copy($source, $destination); + echo "\n\nDestination $destination\n\n"; // DEBUG } } unset($iterator, $file); @@ -38,5 +39,3 @@ foreach ($files as $file) { include $file; } - -echo "\n\n TEST MODULES WERE DEPLOYED \n\n"; // DEBUG From 29cb28b41987ae4199fbc8ac14c3640d2224ec23 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:58:54 +0200 Subject: [PATCH 0750/1415] Remove debug info --- dev/tests/integration/framework/deployTestModules.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index 6e57d748a55eb..f4fb881d3ed70 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -25,7 +25,6 @@ mkdir($targetDir, 0755, true); } copy($source, $destination); - echo "\n\nDestination $destination\n\n"; // DEBUG } } unset($iterator, $file); From 4fdc63807fff721244e7ccff31064b634904075b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 18:04:52 +0200 Subject: [PATCH 0751/1415] removed accidentally added char --- dev/tests/integration/framework/deployTestModules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index f4fb881d3ed70..4c894d80f9800 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -1,4 +1,4 @@ -x<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. From cf6c3952630de4306384f49e0474e880d844cbec Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 23 Oct 2018 11:51:05 -0500 Subject: [PATCH 0752/1415] MAGETWO-95595: Index names are ignored by declarative schema --- .../Setup/Declaration/Schema/Operations/AddColumn.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php index 9a42090ad31db..71a1e2f92dfd8 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php @@ -110,7 +110,7 @@ private function getTemporaryIndexHistory(Column $column) Index::TYPE, [ 'name' => self::TEMPORARY_KEY, - 'column' => $column->getName(), + 'column' => [$column->getName()], 'columns' => [$column], 'table' => $column->getTable() ] @@ -119,7 +119,7 @@ private function getTemporaryIndexHistory(Column $column) } /** - * {@inheritdoc} + * @inheritdoc */ public function getOperationName() { @@ -127,7 +127,7 @@ public function getOperationName() } /** - * @return bool + * @inheritdoc */ public function isOperationDestructive() { @@ -187,7 +187,7 @@ private function setupTriggersIfExists(Statement $statement, ElementHistory $ele } /** - * {@inheritdoc} + * @inheritdoc */ public function doOperation(ElementHistory $elementHistory) { From a8c77686312a61ab151eb4c9a7a79a5f8127b3dd Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 13:46:53 -0500 Subject: [PATCH 0753/1415] Fix docblocks --- .../Timezone/LocalizedDateToUtcConverterInterface.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php index 277900c46badf..edc07bee164be 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -7,11 +7,16 @@ namespace Magento\Framework\Stdlib\DateTime\Timezone; +/* + * Interface for converting localized date to UTC + */ interface LocalizedDateToUtcConverterInterface { /** + * Convert localized date to UTC + * * @param string $data * @return string */ public function convertLocalizedDateToUtc($date); -} \ No newline at end of file +} From a18a08792acf1d251c491894d0889783d3b73c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 23 Oct 2018 22:48:01 +0300 Subject: [PATCH 0754/1415] graphQl-44: added html content resolver --- .../Resolver/Product/ProductTextAttribute.php | 64 ------------------- .../ProductTextAttribute/FormatInterface.php | 23 ------- .../ProductTextAttribute/FormatList.php | 54 ---------------- .../Product/ProductTextAttribute/Html.php | 47 -------------- .../ProductTextAttribute/HtmlContent.php | 56 ++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 29 ++------- 6 files changed, 61 insertions(+), 212 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php deleted file mode 100644 index 2ff6faa0a74ee..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Resolve rendered content for attributes where HTML content is allowed - */ -class ProductTextAttribute implements ResolverInterface -{ - /** - * @var FormatList - */ - private $formatList; - - /** - * @var string - */ - private $defaultFormat = 'html'; - - /** - * @param FormatList $formatList - */ - public function __construct( - FormatList $formatList - ) { - $this->formatList = $formatList; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $field->getName(); - $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; - $format = $this->formatList->getFormatByIdentifier($formatIdentifier); - $result = ['content' => $format->getContent($product, $fieldName)]; - - return $result; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php deleted file mode 100644 index 2cf702bf18466..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Catalog\Model\Product as ModelProduct; - -interface FormatInterface -{ - /** - * @param ModelProduct $product - * @param string $fieldName - * @return string - */ - public function getContent( - ModelProduct $product, - string $fieldName - ): string; -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php deleted file mode 100644 index 39f2074ed7592..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\ObjectManagerInterface; - -/** - * Class FormatList - * @package Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute - */ -class FormatList -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var string - */ - private $formats; - - /** - * @param ObjectManagerInterface $objectManager - * @param array $formats - */ - public function __construct( - ObjectManagerInterface $objectManager, - array $formats - ) { - $this->objectManager = $objectManager; - $this->formats = $formats; - } - - /** - * @param string $formatIdentifier - * @return FormatInterface - */ - public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface - { - if (!isset($this->formats[$formatIdentifier])) { - throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); - } - $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); - - return $formatInstance; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php deleted file mode 100644 index 830fbf28e3373..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; -use Magento\Catalog\Helper\Output as OutputHelper; -use Magento\Catalog\Model\Product as ModelProduct; - -class Html implements FormatInterface -{ - /** - * @var ValueFactory - */ - private $valueFactory; - - /** - * @var OutputHelper - */ - private $outputHelper; - - /** - * @param ValueFactory $valueFactory - * @param OutputHelper $outputHelper - */ - public function __construct( - ValueFactory $valueFactory, - OutputHelper $outputHelper - ) { - $this->valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function getContent( - ModelProduct $product, - string $fieldName - ): string { - return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php new file mode 100644 index 0000000000000..c0b67889ecd74 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; + +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Helper\Output as OutputHelper; + +/** + * HTML content of Product Text Attribute + */ +class HtmlContent implements ResolverInterface +{ + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param OutputHelper $outputHelper + */ + public function __construct( + OutputHelper $outputHelper + ) { + $this->outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): array { + if (!isset($value['model'])) { + return []; + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + + return $renderedValue; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a7d9ab5483d46..3ffdc85a40d68 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -558,24 +558,5 @@ type SortFields @doc(description: "SortFields contains a default value for sort } type ProductTextAttribute @doc(description: "Product text attribute.") { - content: String -} - -input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { - format: String @doc(description: "Format of the content") - eq: String @doc(description: "Equals") - finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") - from: String @doc(description: "From. Must be used with 'to'") - gt: String @doc(description: "Greater than") - gteq: String @doc(description: "Greater than or equal to") - in: [String] @doc(description: "In. The value can contain a set of comma-separated values") - like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") - lt: String @doc(description: "Less than") - lteq: String @doc(description: "Less than or equal to") - moreq: String @doc(description: "More than or equal to") - neq: String @doc(description: "Not equal to") - notnull: String @doc(description: "Not null") - null: String @doc(description: "Is null") - to: String@doc(description: "To. Must be used with 'from'") - nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") + html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") } From 795bc1f0f449e1e599586bf42525d5c088cfbae2 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Tue, 23 Oct 2018 14:50:43 -0500 Subject: [PATCH 0755/1415] Merge remote-tracking branch 'upstream/2.3-develop' into 2.3.0-release-sync --- .../Model/Import/Product/CategoryProcessor.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index f299fa010591e..951989146e67e 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -115,22 +115,14 @@ protected function createCategory($name, $parentId) if (!($parentCategory = $this->getCategoryById($parentId))) { $parentCategory = $this->categoryFactory->create()->load($parentId); } - - // Set StoreId to 0 to generate URL Keys global and prevent generating url rewrites just for default website - $category->setStoreId(0); $category->setPath($parentCategory->getPath()); $category->setParentId($parentId); $category->setName($this->unquoteDelimiter($name)); $category->setIsActive(true); $category->setIncludeInMenu(true); $category->setAttributeSetId($category->getDefaultAttributeSetId()); - try { - $category->save(); - $this->categoriesCache[$category->getId()] = $category; - } catch (\Exception $e) { - $this->addFailedCategory($category, $e); - } - + $category->save(); + $this->categoriesCache[$category->getId()] = $category; return $category->getId(); } From 127b1b8029a52fca7ad9726380f55c99c9db4c8a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:28:11 -0500 Subject: [PATCH 0756/1415] Fix docblock --- app/code/Magento/Newsletter/Model/Queue.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 58c5ba8a7e04a..a3279f8c83699 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -136,6 +136,7 @@ class Queue extends \Magento\Framework\Model\AbstractModel implements TemplateTy * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param TimezoneInterface $timezone + * @param LocalizedDateToUtcConverterInterface $utcConverter * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( From 526bfc9267c837ef8b9bf7234869cf16d4327a26 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:31:08 -0500 Subject: [PATCH 0757/1415] Fix docblock --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 8534e798481cb..6514c01f92370 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,6 +257,8 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** + * Format date according to date and time formats, locale, timezone and pattern + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -300,6 +302,7 @@ public function formatDateTime( /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date From edc962dbf324a3866f9ac78537ce23abfc1316e4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:32:37 -0500 Subject: [PATCH 0758/1415] Fix static tests --- .../DateTime/Timezone/LocalizedDateToUtcConverter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php index 721ed9a384dad..420fd6e543e07 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -36,13 +36,13 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac /** * LocalizedDateToUtcConverter constructor. * + * @param TimezoneInterface $timezone * @param ResolverInterface $localeResolver */ public function __construct( TimezoneInterface $timezone, ResolverInterface $localeResolver - ) - { + ) { $this->timezone = $timezone; $this->localeResolver = $localeResolver; } @@ -71,4 +71,4 @@ public function convertLocalizedDateToUtc($date) return $date->format($this->defaultFormat); } -} \ No newline at end of file +} From 4fe8c7a3ccc100d23f170dcef994477227aed35e Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:33:27 -0500 Subject: [PATCH 0759/1415] Fix static test --- .../DateTime/Timezone/LocalizedDateToUtcConverterInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php index edc07bee164be..d10bd5f2fefb2 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -15,7 +15,7 @@ interface LocalizedDateToUtcConverterInterface /** * Convert localized date to UTC * - * @param string $data + * @param string $date * @return string */ public function convertLocalizedDateToUtc($date); From e27de555edbbc24ff8a7037ee57de4deea306472 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:36:43 -0500 Subject: [PATCH 0760/1415] Fix static test --- .../Framework/Stdlib/DateTime/Timezone.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 6514c01f92370..cf747bfa2b735 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,15 +257,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * Format date according to date and time formats, locale, timezone and pattern - * - * @param string|\DateTimeInterface $date - * @param int $dateType - * @param int $timeType - * @param string|null $locale - * @param string|null $timezone - * @param string|null $pattern - * @return string + * @inheritdoc */ public function formatDateTime( $date, @@ -301,14 +293,7 @@ public function formatDateTime( } /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @throws LocalizedException - * @return string + * @inheritdoc */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { From 3cba00c951e0df4c843085ab761b9b97c2e3471b Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Tue, 23 Oct 2018 23:39:19 +0300 Subject: [PATCH 0761/1415] Cover \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection class with Integration test --- .../ResourceModel/Grid/CollectionTest.php | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php diff --git a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php new file mode 100644 index 0000000000000..2f3112e705c94 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CheckoutAgreements\Model\ResourceModel\Grid; + +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Check data in collection + */ +class CollectionTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Collection; + */ + private $collection; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->collection = Bootstrap::getObjectManager()->create(Collection::class); + } + + /** + * Check that collection is filterable by store + * + * @magentoDataFixture Magento/CheckoutAgreements/_files/multi_agreements_active_with_text.php + */ + public function testAddStoresToFilter(): void + { + $collectionSize = $this->collection->addStoreFilter(1)->load(false, false)->getSize(); + $this->assertEquals(2, $collectionSize); + } +} From 0d0c210a7e081086a8235f9777a219601bd7e8c4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:40:36 -0500 Subject: [PATCH 0762/1415] Fix static test --- .../Framework/Stdlib/DateTime/TimezoneInterface.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 4aff80161ef80..d1ac24c84be9a 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -6,6 +6,8 @@ namespace Magento\Framework\Stdlib\DateTime; +use Magento\Framework\Exception\LocalizedException; + /** * Timezone Interface * @api @@ -122,6 +124,8 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** + * Format date according to date and time formats, locale, timezone and pattern. + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -140,9 +144,14 @@ public function formatDateTime( ); /** + * Convert date from config timezone to UTC. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * * @param string|\DateTimeInterface $date * @param string $format * @return string + * @throws LocalizedException * @since 100.1.0 */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); From 29ccdae0897db8ef212b67a8ecf92e985c8d2e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Ca=C3=A7ador?= <20863811+samuel27m@users.noreply.github.com> Date: Tue, 23 Oct 2018 23:19:31 +0100 Subject: [PATCH 0763/1415] Remove unnecesary "header" block redeclaration Remove unnecesary header block redeclaration on Magento Luma Theme, which made impossible to set the header template through custom modules. Example: - Create new module. - Create new default.xml and try to use referenceBlock to set the template. - Doesn't work, because Luma theme XML files are compiled after all modules and overrides the custom module modifications. Removed because this block was already created in module Magento_Theme, so this redeclaration is just unnecesary --- .../Magento/luma/Magento_Customer/layout/default.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml index 1f8c162ef923a..4b08bf28ece9f 100644 --- a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml +++ b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml @@ -15,11 +15,6 @@ </arguments> </block> </referenceBlock> - <block class="Magento\Theme\Block\Html\Header" name="header" as="header"> - <arguments> - <argument name="show_part" xsi:type="string">welcome</argument> - </arguments> - </block> <move element="header" destination="header.links" before="-"/> <move element="register-link" destination="header.links"/> <move element="top.links" destination="customer"/> From 6e1710aec76825c8fc03e1e159f518dfba8d18e4 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Tue, 23 Oct 2018 17:29:09 -0500 Subject: [PATCH 0764/1415] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Review comments fix. Using action group for logout. --- .../Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml index 6d1f266f4c66b..e9b54e3f1a3dc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -79,7 +79,7 @@ <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct2"> <argument name="productName" value="simpleProductForMassUpdate2.name"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="amOnLogoutPage"/> </after> <!-- Search and select products --> From 7b078de306f1c48eaf16544df53516b4c4d412a2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 17:55:35 -0500 Subject: [PATCH 0765/1415] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- .../Magento/Test/Legacy/_files/obsolete_constants.php | 1 - lib/internal/Magento/Framework/App/Config/Value.php | 10 +++++----- .../Magento/Framework/App/Config/ValueInterface.php | 2 ++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php index cbf499c8dad38..5bcc712be6f74 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php @@ -712,7 +712,6 @@ 'Magento\Sales\Block\Reorder\Sidebar', '\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT', ], - ['ENTITY', 'Magento\Framework\App\Config\ValueInterface'], ['XML_PATH_ALLOW_CURRENCIES_INSTALLED', 'Magento\Framework\Locale\CurrencyInterface'], [ 'DEFAULT_CURRENCY', diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 9326fa4fa3f72..6fde4dded4695 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -9,7 +9,7 @@ * Config data model * * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit - * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * developers' needs of extensibility. In 2.4 we are going to introduce a new interface which should cover all needs * and deprecate the mentioned together with the model * * @method string getScope() @@ -113,9 +113,9 @@ public function getFieldsetDataValue($key) } /** - * @inheritdoc + * Processing object after save data * - * @inheritdoc. In addition, it sets status 'invalidate' for config caches + * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * * @return $this */ @@ -129,9 +129,9 @@ public function afterSave() } /** - * @inheritdoc + * Processing object after delete data * - * @inheritdoc. In addition, it sets status 'invalidate' for config caches + * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * * @return $this */ diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 6f2b6f37aca72..0aa600b84dcce 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -18,6 +18,8 @@ interface ValueInterface { /** * Table name + * + * @deprecated since it is not used */ const ENTITY = 'config_data'; From 53b5b4902f08c20d7b5ceea85fea8fd8823ae055 Mon Sep 17 00:00:00 2001 From: godvsdeity <alex.simplecoding@gmail.com> Date: Wed, 24 Oct 2018 02:00:10 +0300 Subject: [PATCH 0766/1415] performance improvements Get rid of unnecessary reviews queries on product listing: "select review_entity_summary.* from review_entity_summary where (review_entity_summary.entity_pk_value = ?) and (store_id = ?)" This query was executed for each product on listing which didn't have a review summary(@see: Magento\Review\Block\Product\ReviewRenderer::getReviewsSummaryHtml) --- app/code/Magento/Review/Model/Review.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Review/Model/Review.php b/app/code/Magento/Review/Model/Review.php index c00af3fc61407..e689d4ed460ac 100644 --- a/app/code/Magento/Review/Model/Review.php +++ b/app/code/Magento/Review/Model/Review.php @@ -5,6 +5,7 @@ */ namespace Magento\Review\Model; +use Magento\Framework\DataObject; use Magento\Catalog\Model\Product; use Magento\Framework\DataObject\IdentityInterface; use Magento\Review\Model\ResourceModel\Review\Product\Collection as ProductCollection; @@ -327,6 +328,9 @@ public function appendSummary($collection) $item->setRatingSummary($summary); } } + if (!$item->getRatingSummary()) { + $item->setRatingSummary(new DataObject()); + } } return $this; From 0dc76a43811ac8598abc4530cab1fe976aa734a2 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 08:44:12 +0300 Subject: [PATCH 0767/1415] ENGCOM-17516: added Australian states --- .../Setup/Patch/Data/AddDataForAustralia.php | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php new file mode 100644 index 0000000000000..7574f684bb465 --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Framework\Setup\Patch\PatchVersionInterface; + +/** + * Adds Australian States + */ +class AddDataForAustralia implements DataPatchInterface, PatchVersionInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var \Magento\Directory\Setup\DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForCroatia constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * {@inheritdoc} + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForAustralia() + ); + } + + /** + * Croatian states data. + * + * @return array + */ + private function getDataForAustralia() + { + return [ + ['AU', 'ACT', 'Australian Capital Territory'], + ['AU', 'NSW', 'New South Wales'], + ['AU', 'VIC', 'Victoria'], + ['AU', 'QLD', 'Queensland'], + ['AU', 'SA', 'South Australia'], + ['AU', 'TAS', 'Tasmania'], + ['AU', 'WA', 'Western Australia'], + ['AU', 'NT', 'Northern Territory'] + ]; + } + + /** + * {@inheritdoc} + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * {@inheritdoc} + */ + public static function getVersion() + { + return '2.0.3'; + } + + /** + * {@inheritdoc} + */ + public function getAliases() + { + return []; + } +} From 50ff962c0d838cfd58a2c151bbb86730f23f00c8 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 08:51:12 +0300 Subject: [PATCH 0768/1415] ENGCOM-17516: Fixed phpdocs --- .../Directory/Setup/Patch/Data/AddDataForAustralia.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index 7574f684bb465..0abadf7153424 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -27,8 +27,6 @@ class AddDataForAustralia implements DataPatchInterface, PatchVersionInterface private $dataInstallerFactory; /** - * AddDataForCroatia constructor. - * * @param ModuleDataSetupInterface $moduleDataSetup * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory */ @@ -54,7 +52,7 @@ public function apply() } /** - * Croatian states data. + * Australian states data. * * @return array */ From e7d5aa8c8bb959b3d03c5d8f75ce3eee4727df00 Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Tue, 23 Oct 2018 17:04:32 +0300 Subject: [PATCH 0769/1415] MAGETWO-95848: Customer Cart Checkout error --- .../Item/ItemProductResolver.php | 56 ++++--- .../Item/ItemProductResolverTest.php | 143 ++++++++++++++++++ 2 files changed, 176 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php b/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php index 6c33ecc138aea..7de78b6612a10 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php @@ -13,16 +13,17 @@ use Magento\Catalog\Model\Product\Configuration\Item\ItemResolverInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Catalog\Model\Product; +use Magento\Store\Model\ScopeInterface; /** - * {@inheritdoc} + * Resolves the product from a configured item. */ class ItemProductResolver implements ItemResolverInterface { /** * Path in config to the setting which defines if parent or child product should be used to generate a thumbnail. */ - const CONFIG_THUMBNAIL_SOURCE = 'checkout/cart/configurable_product_image'; + public const CONFIG_THUMBNAIL_SOURCE = 'checkout/cart/configurable_product_image'; /** * @var ScopeConfigInterface @@ -38,27 +39,21 @@ public function __construct(ScopeConfigInterface $scopeConfig) } /** - * {@inheritdoc} + * Get the final product from a configured item by product type and selection. + * + * @param ItemInterface $item + * @return ProductInterface */ - public function getFinalProduct(ItemInterface $item) : ProductInterface + public function getFinalProduct(ItemInterface $item): ProductInterface { /** * Show parent product thumbnail if it must be always shown according to the related setting in system config * or if child thumbnail is not available. */ - $parentProduct = $item->getProduct(); - $finalProduct = $parentProduct; + $finalProduct = $item->getProduct(); $childProduct = $this->getChildProduct($item); - if ($childProduct !== $parentProduct) { - $configValue = $this->scopeConfig->getValue( - self::CONFIG_THUMBNAIL_SOURCE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); - $childThumb = $childProduct->getData('thumbnail'); - $finalProduct = - ($configValue == Thumbnail::OPTION_USE_PARENT_IMAGE) || (!$childThumb || $childThumb == 'no_selection') - ? $parentProduct - : $childProduct; + if ($childProduct !== null && $this->isUseChildProduct($childProduct)) { + $finalProduct = $childProduct; } return $finalProduct; } @@ -67,15 +62,30 @@ public function getFinalProduct(ItemInterface $item) : ProductInterface * Get item configurable child product. * * @param ItemInterface $item - * @return Product + * @return Product | null */ - private function getChildProduct(ItemInterface $item) : Product + private function getChildProduct(ItemInterface $item): ?Product { + /** @var \Magento\Quote\Model\Quote\Item\Option $option */ $option = $item->getOptionByCode('simple_product'); - $product = $item->getProduct(); - if ($option) { - $product = $option->getProduct(); - } - return $product; + return $option ? $option->getProduct() : null; + } + + /** + * Is need to use child product + * + * @param Product $childProduct + * @return bool + */ + private function isUseChildProduct(Product $childProduct): bool + { + $configValue = $this->scopeConfig->getValue( + self::CONFIG_THUMBNAIL_SOURCE, + ScopeInterface::SCOPE_STORE + ); + $childThumb = $childProduct->getData('thumbnail'); + return $configValue !== Thumbnail::OPTION_USE_PARENT_IMAGE + && $childThumb !== null + && $childThumb !== 'no_selection'; } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php new file mode 100644 index 0000000000000..8dac2dee10d37 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProduct\Test\Unit\Model\Product\Configuration\Item; + +use Magento\Catalog\Model\Config\Source\Product\Thumbnail; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; +use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface; +use Magento\ConfigurableProduct\Model\Product\Configuration\Item\ItemProductResolver; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Quote\Model\Quote\Item\Option; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class ItemProductResolverTest extends TestCase +{ + /** @var ItemProductResolver */ + private $model; + /** @var ItemInterface | MockObject */ + private $item; + /** @var Product | MockObject */ + private $parentProduct; + /** @var ScopeConfigInterface | MockObject */ + private $scopeConfig; + /** @var OptionInterface | MockObject */ + private $option; + /** @var Product | MockObject */ + private $childProduct; + + /** + * Set up method + */ + protected function setUp() + { + parent::setUp(); + + $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->parentProduct = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->parentProduct + ->method('getSku') + ->willReturn('parent_product'); + + $this->childProduct = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->childProduct + ->method('getSku') + ->willReturn('child_product'); + + $this->option = $this->getMockBuilder(Option::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->option + ->method('getProduct') + ->willReturn($this->childProduct); + + $this->item = $this->getMockBuilder(ItemInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->item + ->expects($this->once()) + ->method('getProduct') + ->willReturn($this->parentProduct); + + $this->model = new ItemProductResolver($this->scopeConfig); + } + + /** + * Test for deleted child product from configurable product + */ + public function testGetFinalProductChildIsNull(): void + { + $this->scopeConfig->expects($this->never())->method('getValue'); + $this->childProduct->expects($this->never())->method('getData'); + + $this->item->expects($this->once()) + ->method('getOptionByCode') + ->willReturn(null); + + $finalProduct = $this->model->getFinalProduct($this->item); + $this->assertEquals( + $this->parentProduct->getSku(), + $finalProduct->getSku() + ); + } + + /** + * Tests child product from configurable product + * + * @dataProvider provideScopeConfig + * @param string $expectedSku + * @param string $scopeValue + * @param string | null $thumbnail + */ + public function testGetFinalProductChild($expectedSku, $scopeValue, $thumbnail): void + { + $this->item->expects($this->once()) + ->method('getOptionByCode') + ->willReturn($this->option); + + $this->childProduct + ->expects($this->once()) + ->method('getData') + ->willReturn($thumbnail); + + $this->scopeConfig->expects($this->once()) + ->method('getValue') + ->willReturn($scopeValue); + + $finalProduct = $this->model->getFinalProduct($this->item); + $this->assertEquals($expectedSku, $finalProduct->getSku()); + } + + /** + * Dataprovider for scope test + * @return array + */ + public function provideScopeConfig(): array + { + return [ + ['child_product', Thumbnail::OPTION_USE_OWN_IMAGE, 'thumbnail'], + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, 'thumbnail'], + + ['parent_product', Thumbnail::OPTION_USE_OWN_IMAGE, null], + ['parent_product', Thumbnail::OPTION_USE_OWN_IMAGE, 'no_selection'], + + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, null], + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, 'no_selection'], + ]; + } +} From d9de494dcfd714101117a6619895805aeec6f8e8 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Wed, 24 Oct 2018 01:24:02 -0700 Subject: [PATCH 0770/1415] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../CatalogPriceRuleActionGroup.xml | 19 +++++ ...hipArePersistedUnderLongTermCookieTest.xml | 85 +++++++++++++++++++ .../Section/StorefrontPanelHeaderSection.xml | 1 + .../Test/Mftf/Data/PersistentData.xml | 14 +++ .../Mftf/Metadata/persistent_config-meta.xml | 3 + 5 files changed, 122 insertions(+) create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index cfd41f2ab970c..fe4042e8a2e9f 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -58,4 +58,23 @@ <fillField selector="{{AdminNewCatalogPriceRuleConditions.targetInput('1', '1')}}" userInput="{{productSku}}" after="clickEllipsis" stepKey="fillProductSku"/> <click selector="{{AdminNewCatalogPriceRuleConditions.applyButton('1', '1')}}" after="fillProductSku" stepKey="clickApply"/> </actionGroup> + + <!--Add Catalog Rule Condition With Category--> + <actionGroup name="newCatalogPriceRuleByUIWithConditionIsCategory" extends="newCatalogPriceRuleByUI"> + <arguments> + <argument name="categoryId"/> + </arguments> + <click selector="{{AdminNewCatalogPriceRule.conditionsTab}}" after="discardSubsequentRules" stepKey="openConditionsTab"/> + <waitForPageLoad after="openConditionsTab" stepKey="waitForConditionTabOpened"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.newCondition}}" after="waitForConditionTabOpened" stepKey="addNewCondition"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.conditionSelect('1')}}" userInput="Magento\CatalogRule\Model\Rule\Condition\Product|category_ids" after="addNewCondition" stepKey="selectTypeCondition"/> + <waitForPageLoad after="selectTypeCondition" stepKey="waitForConditionChosed"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.targetEllipsis('1')}}" after="waitForConditionChosed" stepKey="clickEllipsis"/> + <fillField selector="{{AdminNewCatalogPriceRuleConditions.targetInput('1', '1')}}" userInput="{{categoryId}}" after="clickEllipsis" stepKey="fillCategoryId"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.applyButton('1', '1')}}" after="fillCategoryId" stepKey="clickApply"/> + </actionGroup> + + <actionGroup name="selectGeneralCustomerGroupActionGroup"> + <selectOption selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="General" stepKey="selectCustomerGroup"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml new file mode 100644 index 0000000000000..2e09ee7134733 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest"> + <annotations> + <features value="Persistent"/> + <stories value="Check the price"/> + <title value="Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie"/> + <description value="Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-69455"/> + <group value="persistent"/> + </annotations> + <before> + <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> + <createData entity="PersistentLogoutClearDisable" stepKey="persistentLogoutClearDisable"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">50</field> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"> + <field key="group_id">1</field> + </createData> + + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <!--Create Catalog Rule--> + <actionGroup ref="newCatalogPriceRuleByUIWithConditionIsCategory" stepKey="createCatalogPriceRule"> + <argument name="catalogRule" value="_defaultCatalogRule"/> + <argument name="categoryId" value="$$createCategory.id$$"/> + </actionGroup> + <actionGroup ref="selectGeneralCustomerGroupActionGroup" stepKey="selectCustomerGroup"/> + <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="clickSaveAndApplyRules"/> + <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccess"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <!-- Delete the rule --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToCatalogPriceRulePage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRule"> + <argument name="name" value="{{_defaultCatalogRule.name}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + <createData entity="PersistentConfigDefault" stepKey="setDefaultPersistentState"/> + <createData entity="PersistentLogoutClearEnabled" stepKey="persistentLogoutClearEnabled"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + + <!--Go to category and check price--> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage"/> + <see selector="{{StorefrontCategoryProductSection.ProductPriceByNumber('1')}}" userInput="$$createProduct.price$$" stepKey="checkPriceSimpleProduct"/> + + <!--Login to storfront from customer and check price--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="logInFromCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage2"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome"/> + <see selector="{{StorefrontCategoryProductSection.ProductSpecialPriceByNumber('1')}}" userInput="45.00" stepKey="checkPriceSimpleProduct2"/> + + <!--Click *Sign Out* and check the price of the Simple Product--> + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="storefrontSignOut"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage3"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome2"/> + <seeElement selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="checkLinkNotYoy"/> + <see selector="{{StorefrontCategoryProductSection.ProductSpecialPriceByNumber('1')}}" userInput="45.00" stepKey="checkPriceSimpleProduct3"/> + + <!--Click the *Not you?* link and check the price for Simple Product--> + <click selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="clickNext"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage4"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome3"/> + <see selector="{{StorefrontCategoryProductSection.ProductPriceByNumber('1')}}" userInput="$$createProduct.price$$" stepKey="checkPriceSimpleProduct4"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml index 06b82db767ab5..a0c83f5bc491b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml @@ -11,5 +11,6 @@ <section name="StorefrontPanelHeaderSection"> <element name="WelcomeMessage" type="text" selector=".greet.welcome span"/> <element name="createAnAccountLink" type="select" selector=".panel.header li:nth-child(3)" timeout="30"/> + <element name="notYouLink" type="button" selector=".greet.welcome span a"/> </section> </sections> diff --git a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml index f4e2fa198e7ff..3d42ae6da81a5 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml @@ -20,4 +20,18 @@ <entity name="persistentEnabledState" type="persistent_options_enabled"> <data key="value">1</data> </entity> + + <entity name="PersistentLogoutClearEnabled" type="persistent_config_state"> + <requiredEntity type="persistent_options_logout_clear">persistentEnabledLogoutClear</requiredEntity> + </entity> + <entity name="persistentEnabledLogoutClear" type="logout_clear"> + <data key="value">1</data> + </entity> + + <entity name="PersistentLogoutClearDisable" type="persistent_config_state"> + <requiredEntity type="persistent_options_logout_clear">persistentDisableLogoutClear</requiredEntity> + </entity> + <entity name="persistentDisableLogoutClear" type="logout_clear"> + <data key="value">0</data> + </entity> </entities> diff --git a/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml b/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml index d165ca5f929b0..7f0e12f8bef93 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml @@ -14,6 +14,9 @@ <object key="enabled" dataType="persistent_options_enabled"> <field key="value">string</field> </object> + <object key="logout_clear" dataType="persistent_options_logout_clear"> + <field key="value">string</field> + </object> </object> </object> </object> From 308ac7e212fb2e60418c2b3b8b252fcfa3dc1911 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 11:50:27 +0300 Subject: [PATCH 0771/1415] MAGETWO-95853: Can't flush Images cache in admin --- .../Framework/Filesystem/Directory/Write.php | 46 ++++++++++++++++++- .../Framework/Filesystem/Driver/File.php | 14 +++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php index 78732d73456f7..74314b747cf42 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php @@ -175,6 +175,7 @@ public function createSymlink($path, $destination, WriteInterface $targetDirecto */ public function delete($path = null) { + $exceptionMessages = []; $this->validatePath($path); if (!$this->isExist($path)) { return true; @@ -183,11 +184,54 @@ public function delete($path = null) if ($this->driver->isFile($absolutePath)) { $this->driver->deleteFile($absolutePath); } else { - $this->driver->deleteDirectory($absolutePath); + try { + $this->deleteFilesRecursively($absolutePath); + $this->driver->deleteDirectory($absolutePath); + } catch (FileSystemException $e) { + $exceptionMessages[] = $e->getMessage(); + } + } + if (!empty($exceptionMessages)) { + throw new FileSystemException( + new \Magento\Framework\Phrase( + \implode(' ', $exceptionMessages) + ) + ); } return true; } + /** + * Delete files recursively + * + * Implemented in order to delete as much files as possible and collect all exceptions + * + * @param string $path + * @return void + * @throws FileSystemException + */ + private function deleteFilesRecursively(string $path) + { + $exceptionMessages = []; + $entitiesList = $this->driver->readDirectoryRecursively($path); + foreach ($entitiesList as $entityPath) { + if (!$this->driver->isDirectory($entityPath)) { + try { + $this->driver->deleteFile($entityPath); + } catch (FileSystemException $e) { + $exceptionMessages[] = $e->getMessage(); + } + } + } + if (!empty($exceptionMessages)) { + throw new FileSystemException( + new \Magento\Framework\Phrase( + \implode(' ', $exceptionMessages) + ) + ); + } + } + /** * Change permissions of given path * diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index b54b02bd6de98..e8d51f52ff153 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -399,16 +399,28 @@ public function deleteFile($path) */ public function deleteDirectory($path) { + $exceptionMessages = []; $flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS; $iterator = new \FilesystemIterator($path, $flags); /** @var \FilesystemIterator $entity */ foreach ($iterator as $entity) { if ($entity->isDir()) { - $this->deleteDirectory($entity->getPathname()); + try { + $this->deleteDirectory($entity->getPathname()); + } catch (FileSystemException $exception) { + $exceptionMessages[] = $exception->getMessage(); + } } else { $this->deleteFile($entity->getPathname()); } } + if (!empty($exceptionMessages)) { + throw new FileSystemException( + new \Magento\Framework\Phrase( + \implode(' ', $exceptionMessages) + ) + ); + } $result = @rmdir($this->getScheme() . $path); if (!$result) { throw new FileSystemException( From a14244e86c129f1296e5f5b0b2a0fac86e5fb526 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 11:51:40 +0300 Subject: [PATCH 0772/1415] MAGETWO-95853: Can't flush Images cache in admin --- lib/internal/Magento/Framework/Filesystem/Directory/Write.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php index 74314b747cf42..cb8f6dd0b88e0 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php @@ -215,7 +215,7 @@ private function deleteFilesRecursively(string $path) $exceptionMessages = []; $entitiesList = $this->driver->readDirectoryRecursively($path); foreach ($entitiesList as $entityPath) { - if (!$this->driver->isDirectory($entityPath)) { + if ($this->driver->isFile($entityPath)) { try { $this->driver->deleteFile($entityPath); } catch (FileSystemException $e) { From 7e74d4ee5ee682926044e4c8f153437c768e62d8 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 12:55:47 +0300 Subject: [PATCH 0773/1415] MAGETWO-95853: Can't flush Images cache in admin --- .../Magento/Framework/Filesystem/Directory/Write.php | 5 ++++- lib/internal/Magento/Framework/Filesystem/Driver/File.php | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php index cb8f6dd0b88e0..88c03f7869581 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php @@ -9,6 +9,9 @@ use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\ValidatorException; +/** + * Write Interface implementation + */ class Write extends Read implements WriteInterface { /** @@ -289,7 +292,7 @@ public function touch($path, $modificationTime = null) /** * Check if given path is writable * - * @param null $path + * @param string|null $path * @return bool * @throws \Magento\Framework\Exception\FileSystemException * @throws ValidatorException diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index e8d51f52ff153..395144ca6ee7d 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -14,6 +14,7 @@ /** * Class File + * * @package Magento\Framework\Filesystem\Driver * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -855,6 +856,8 @@ public function fileUnlock($resource) } /** + * Retrieves absolute path + * * @param string $basePath * @param string $path * @param string|null $scheme From ea180c8940a7e5da139feee9770e943cefdb96b3 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 13:04:23 +0300 Subject: [PATCH 0774/1415] MAGETWO-95853: Can't flush Images cache in admin --- lib/internal/Magento/Framework/Filesystem/Driver/File.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index 395144ca6ee7d..4ba8f566f3f10 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -895,6 +895,7 @@ public function getRelativePath($basePath, $path = null) /** * Fixes path separator + * * Utility method. * * @param string $path From 5e8ae07871b82b7d36983f16c5296110e6a9bc9d Mon Sep 17 00:00:00 2001 From: Dzmitry Tabusheu <dzmitry_tabusheu@epam.com> Date: Wed, 24 Oct 2018 14:07:54 +0300 Subject: [PATCH 0775/1415] MAGETWO-95805: User agent exception not setting the correct templates for product pages - Fixed template detection in 'ProductViewCounter' block --- .../Product/Listing/Collector/ImageTest.php | 8 +++++++- .../Product/Listing/Collector/Image.php | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Listing/Collector/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Listing/Collector/ImageTest.php index 12bc9acfa4c51..009cd690d4cd4 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Listing/Collector/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Listing/Collector/ImageTest.php @@ -15,6 +15,7 @@ use Magento\Catalog\Helper\ImageFactory; use Magento\Catalog\Api\Data\ProductRender\ImageInterface; use Magento\Catalog\Helper\Image as ImageHelper; +use Magento\Framework\View\DesignLoader; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -33,6 +34,9 @@ class ImageTest extends \PHPUnit\Framework\TestCase /** @var DesignInterface | \PHPUnit_Framework_MockObject_MockObject */ private $design; + /** @var DesignLoader | \PHPUnit_Framework_MockObject_MockObject*/ + private $designLoader; + /** @var Image */ private $model; @@ -60,13 +64,15 @@ public function setUp() ->getMock(); $this->storeManager = $this->createMock(StoreManagerInterface::class); $this->design = $this->createMock(DesignInterface::class); + $this->designLoader = $this->createMock(DesignLoader::class); $this->model = new Image( $this->imageFactory, $this->state, $this->storeManager, $this->design, $this->imageInterfaceFactory, - $this->imageCodes + $this->imageCodes, + $this->designLoader ); } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php index 216bc16968fcb..524927ac1c4b4 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php @@ -17,12 +17,14 @@ use Magento\Framework\View\DesignInterface; use Magento\Store\Model\StoreManager; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\View\DesignLoader; /** * Collect enough information about image rendering on front * If you want to add new image, that should render on front you need * to configure this class in di.xml * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Image implements ProductRenderCollectorInterface { @@ -51,6 +53,7 @@ class Image implements ProductRenderCollectorInterface /** * @var DesignInterface + * @deprecated 2.3.0 DesignLoader is used for design theme loading */ private $design; @@ -59,6 +62,11 @@ class Image implements ProductRenderCollectorInterface */ private $imageRenderInfoFactory; + /** + * @var DesignLoader + */ + private $designLoader; + /** * Image constructor. * @param ImageFactory $imageFactory @@ -67,6 +75,7 @@ class Image implements ProductRenderCollectorInterface * @param DesignInterface $design * @param ImageInterfaceFactory $imageRenderInfoFactory * @param array $imageCodes + * @param DesignLoader $designLoader */ public function __construct( ImageFactory $imageFactory, @@ -74,7 +83,8 @@ public function __construct( StoreManagerInterface $storeManager, DesignInterface $design, ImageInterfaceFactory $imageRenderInfoFactory, - array $imageCodes = [] + array $imageCodes = [], + DesignLoader $designLoader = null ) { $this->imageFactory = $imageFactory; $this->imageCodes = $imageCodes; @@ -82,6 +92,8 @@ public function __construct( $this->storeManager = $storeManager; $this->design = $design; $this->imageRenderInfoFactory = $imageRenderInfoFactory; + $this->designLoader = $designLoader ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(DesignLoader::class); } /** @@ -124,6 +136,8 @@ public function collect(ProductInterface $product, ProductRenderInterface $produ } /** + * Callback for emulating image creation + * * Callback in which we emulate initialize default design theme, depends on current store, be settings store id * from render info * @@ -136,7 +150,7 @@ public function collect(ProductInterface $product, ProductRenderInterface $produ public function emulateImageCreating(ProductInterface $product, $imageCode, $storeId, ImageInterface $image) { $this->storeManager->setCurrentStore($storeId); - $this->design->setDefaultDesignTheme(); + $this->designLoader->load(); $imageHelper = $this->imageFactory->create(); $imageHelper->init($product, $imageCode); From 0a4dc35bb14a28634a7b58e9fe12e68df7e86ea7 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 14:21:40 +0300 Subject: [PATCH 0776/1415] graphQl-44: added ProductTextAttribute and fixed api functional test --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++++++++++ .../ProductTextAttribute/HtmlContent.php | 10 ++++-- .../CatalogGraphQl/etc/schema.graphqls | 4 +-- .../GraphQl/Catalog/ProductViewTest.php | 36 ++++++++++++++++--- 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php new file mode 100644 index 0000000000000..171e84a65aba4 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Resolve rendered content for text attributes + */ +class ProductTextAttribute implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): array { + $value['field'] = $field->getName(); + + return $value; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php index c0b67889ecd74..724d0826dbb3d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Helper\Output as OutputHelper; @@ -41,14 +42,17 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): array { + ): ?string { if (!isset($value['model'])) { - return []; + throw new GraphQlInputException(__('"model" value should be specified')); + } + if (!isset($value['field'])) { + throw new GraphQlInputException(__('"field" value should be specified')); } /* @var $product Product */ $product = $value['model']; - $fieldName = $field->getName(); + $fieldName = $value['field']; $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); return $renderedValue; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 3ffdc85a40d68..ad724c18a5c9a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 7c2cda3a4551b..615e50f640380 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,7 +44,9 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description + description { + html + } gift_message_available id categories { @@ -203,7 +205,9 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description + short_description { + html + } sku small_image { path @@ -262,6 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); + $this->assertTextEavAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -917,11 +922,9 @@ private function assertEavAttributes($product, $actualResponse) { $eavAttributes = [ 'url_key', - 'description', 'meta_description', 'meta_keyword', 'meta_title', - 'short_description', 'country_of_manufacture', 'gift_message_available', 'news_from_date', @@ -943,6 +946,31 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } + /** + * @param ProductInterface $product + * @param array $actualResponse + */ + private function assertTextEavAttributes($product, $actualResponse) + { + $eavAttributes = [ + 'description', + 'short_description', + ]; + $assertionMap = []; + foreach ($eavAttributes as $attributeCode) { + $expectedAttribute = $product->getCustomAttribute($attributeCode); + + $assertionMap[] = [ + 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), + 'expected_value' => $expectedAttribute ? [ + 'html' => $expectedAttribute->getValue() + ] : null + ]; + } + + $this->assertResponseFields($actualResponse, $assertionMap); + } + /** * @param string $eavAttributeCode * @return string From 5fe9697ceec3d0192b9be5125c2cfb5f301521ba Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Wed, 24 Oct 2018 05:40:18 -0700 Subject: [PATCH 0777/1415] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 73025023c23c8..45c6c90a76973 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -25,7 +25,6 @@ <argument name="ProductAttribute" type="string"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.GridFilterFrontEndLabel}}" userInput="{{ProductAttribute}}" stepKey="navigateToAttributeEditPage1" /> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="navigateToAttributeEditPage2" /> <waitForPageLoad stepKey="waitForPageLoad2" /> From 6862c04ece31c29d41be7ac65005e9bdf7c24490 Mon Sep 17 00:00:00 2001 From: Sunil Patel <patelsunil42@gmail.com> Date: Sat, 19 May 2018 15:50:34 +0530 Subject: [PATCH 0778/1415] 15259 : Unable to disable without providing Industry value --- app/code/Magento/Analytics/etc/adminhtml/system.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Analytics/etc/adminhtml/system.xml b/app/code/Magento/Analytics/etc/adminhtml/system.xml index 4e21648d00ce8..c7da840b7e665 100644 --- a/app/code/Magento/Analytics/etc/adminhtml/system.xml +++ b/app/code/Magento/Analytics/etc/adminhtml/system.xml @@ -36,6 +36,9 @@ <source_model>Magento\Analytics\Model\Config\Source\Vertical</source_model> <backend_model>Magento\Analytics\Model\Config\Backend\Vertical</backend_model> <frontend_model>Magento\Analytics\Block\Adminhtml\System\Config\Vertical</frontend_model> + <depends> + <field id="analytics/general/enabled">1</field> + </depends> </field> <field id="additional_comment" translate="label comment" type="label" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="0"> <label><![CDATA[<strong>Get more insights from Magento Business Intelligence</strong>]]></label> From 857908e3ef1b06ef66cfa9c2910861e90eb6bcfd Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Wed, 24 Oct 2018 16:37:54 +0300 Subject: [PATCH 0779/1415] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Section/StorefrontProductInfoMainSection.xml | 1 + .../Mftf/Data/ProductAttributeOptionData.xml | 16 ++++++++++++++++ .../Catalog/Test/Mftf/Data/StoreLabelData.xml | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index 735571375866e..fae1ec331b667 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -13,5 +13,6 @@ <element name="priceTo" type="text" selector=".product-info-price .price-to"/> <element name="minPrice" type="text" selector="span[data-price-type='minPrice']"/> <element name="maxPrice" type="text" selector="span[data-price-type='minPrice']"/> + <element name="productBundleOptionsCheckbox" type="checkbox" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{childName}}')]/../input" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml index c575f1a5db82f..c21f23d16463e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml @@ -65,4 +65,20 @@ <data key="is_default">false</data> <data key="sort_order">0</data> </entity> + <entity name="productAttributeOption7" type="ProductAttributeOption"> + <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> + <data key="label" unique="suffix">Green</data> + <data key="is_default">false</data> + <data key="sort_order">3</data> + <requiredEntity type="StoreLabel">Option7Store0</requiredEntity> + <requiredEntity type="StoreLabel">Option8Store1</requiredEntity> + </entity> + <entity name="productAttributeOption8" type="ProductAttributeOption"> + <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> + <data key="label" unique="suffix">Red</data> + <data key="is_default">false</data> + <data key="sort_order">3</data> + <requiredEntity type="StoreLabel">Option9Store0</requiredEntity> + <requiredEntity type="StoreLabel">Option10Store1</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml index ce964e2d71503..0e51995ac72e8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml @@ -56,4 +56,20 @@ <data key="store_id">1</data> <data key="label">option6</data> </entity> + <entity name="Option7Store0" type="StoreLabel"> + <data key="store_id">0</data> + <data key="label">Green</data> + </entity> + <entity name="Option8Store1" type="StoreLabel"> + <data key="store_id">1</data> + <data key="label">Green</data> + </entity> + <entity name="Option9Store0" type="StoreLabel"> + <data key="store_id">0</data> + <data key="label">Red</data> + </entity> + <entity name="Option10Store1" type="StoreLabel"> + <data key="store_id">1</data> + <data key="label">Red</data> + </entity> </entities> From 8248518ce4988324fd1e6224eb79f39d211cf41a Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 17:25:21 +0300 Subject: [PATCH 0780/1415] MAGETWO-95853: Can't flush Images cache in admin --- .../Framework/Filesystem/Directory/Write.php | 14 +++++++------- .../Magento/Framework/Filesystem/Driver/File.php | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php index 88c03f7869581..e4b52de49d5f9 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php @@ -193,13 +193,13 @@ public function delete($path = null) } catch (FileSystemException $e) { $exceptionMessages[] = $e->getMessage(); } - } - if (!empty($exceptionMessages)) { - throw new FileSystemException( - new \Magento\Framework\Phrase( - \implode(' ', $exceptionMessages) - ) - ); + if (!empty($exceptionMessages)) { + throw new FileSystemException( + new \Magento\Framework\Phrase( + \implode(' ', $exceptionMessages) + ) + ); + } } return true; } diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index 4ba8f566f3f10..f9065e6be6190 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -405,14 +405,14 @@ public function deleteDirectory($path) $iterator = new \FilesystemIterator($path, $flags); /** @var \FilesystemIterator $entity */ foreach ($iterator as $entity) { - if ($entity->isDir()) { - try { + try { + if ($entity->isDir()) { $this->deleteDirectory($entity->getPathname()); - } catch (FileSystemException $exception) { - $exceptionMessages[] = $exception->getMessage(); + } else { + $this->deleteFile($entity->getPathname()); } - } else { - $this->deleteFile($entity->getPathname()); + } catch (FileSystemException $exception) { + $exceptionMessages[] = $exception->getMessage(); } } if (!empty($exceptionMessages)) { From c05cbea7b6df8620b9a2ee8b97cb1dbcff7b4b79 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 24 Oct 2018 17:44:29 +0300 Subject: [PATCH 0781/1415] MAGETWO-95853: Can't flush Images cache in admin --- .../Magento/Framework/Filesystem/Directory/Write.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php index e4b52de49d5f9..3c6d2b7321b82 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/Write.php @@ -189,10 +189,15 @@ public function delete($path = null) } else { try { $this->deleteFilesRecursively($absolutePath); + } catch (FileSystemException $e) { + $exceptionMessages[] = $e->getMessage(); + } + try { $this->driver->deleteDirectory($absolutePath); } catch (FileSystemException $e) { $exceptionMessages[] = $e->getMessage(); } + if (!empty($exceptionMessages)) { throw new FileSystemException( new \Magento\Framework\Phrase( From 5ef522d0b2178c0d8086df04cdb4c282200ce7fa Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Wed, 24 Oct 2018 10:46:13 -0500 Subject: [PATCH 0782/1415] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT --- .../Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml | 2 ++ .../Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 2 ++ .../Mftf/Test/CartPriceRuleForConfigurableProductTest.xml | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml index aaedaedb7236c..ace50aa3e6d33 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml @@ -50,6 +50,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ApiSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsite"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="chooseNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> <fillField selector="{{AdminCartPriceRulesFormSection.userPerCoupon}}" userInput="99" stepKey="fillUserPerCoupon"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index 60df3f27fd65b..08e859b11d1bb 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -45,6 +45,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ApiSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsite"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="chooseNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <!-- Open the Actions Tab in the Rules Edit page --> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml index 4c194c63ec378..e2687f5f16baf 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="CartPriceRuleForConfigurableProductTest"> <annotations> <features value="SalesRule"/> @@ -96,6 +96,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="ABCD" stepKey="fillCouponCOde"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> From 88197c8b1624f9dc82dbea3fc0a5cbc3986f259d Mon Sep 17 00:00:00 2001 From: Pratik Oza <pratik.oza@krishtechnolabs.com> Date: Wed, 24 Oct 2018 22:22:56 +0530 Subject: [PATCH 0783/1415] Remove useless semicolon statements --- .../catalog/product/attribute/set/main/tree/attribute.phtml | 2 +- .../CatalogSearch/Model/Indexer/Fulltext/Action/Full.php | 2 +- app/code/Magento/GiftMessage/Model/ItemRepository.php | 4 ++-- app/code/Magento/GiftMessage/Model/OrderItemRepository.php | 4 ++-- app/code/Magento/GiftMessage/Model/OrderRepository.php | 2 +- .../Magento/Indexer/Console/Command/IndexerReindexCommand.php | 2 +- app/code/Magento/Indexer/Model/DimensionModes.php | 2 +- app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php | 2 +- .../view/adminhtml/templates/importExportHeader.phtml | 2 +- app/code/Magento/Theme/Model/Design/Config/Validator.php | 2 +- app/code/Magento/Theme/view/frontend/templates/text.phtml | 2 +- .../Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php | 4 ++-- .../Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php | 2 +- .../app/Magento/ImportExport/Test/Fixture/Import/File.php | 2 +- .../integration/testsuite/Magento/Deploy/_files/theme.php | 2 +- .../GiftMessage/_files/quote_with_item_message_rollback.php | 2 +- .../Test/Integrity/Magento/Backend/ControllerAclTest.php | 2 +- .../Framework/Indexer/Config/DependencyInfoProvider.php | 2 +- lib/internal/Magento/Framework/Setup/OldDbValidator.php | 2 +- .../Unit/Autoloader/GeneratedClassesAutoloader.php | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml index 223b3e9888eea..75f04eae82159 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml @@ -2,4 +2,4 @@ /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. - */; + */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 2b4be8369de59..7c93595b2b9ff 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -400,7 +400,7 @@ public function rebuildStoreIndex($storeId, $productIds = null) } $products = $this->dataProvider ->getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId, $this->batchSize); - }; + } } /** diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php index 3c62a489af4ab..dce60079e43e3 100644 --- a/app/code/Magento/GiftMessage/Model/ItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php @@ -88,7 +88,7 @@ public function get($cartId, $itemId) throw new NoSuchEntityException( __('No item with the provided ID was found in the Cart. Verify the ID and try again.') ); - }; + } $messageId = $item->getGiftMessageId(); if (!$messageId) { return null; @@ -121,7 +121,7 @@ public function save($cartId, \Magento\GiftMessage\Api\Data\MessageInterface $gi $itemId ) ); - }; + } if ($item->getIsVirtual()) { throw new InvalidTransitionException(__('Gift messages can\'t be used for virtual products.')); diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php index 943552e2b75bc..6cfcd485f7645 100644 --- a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php @@ -89,7 +89,7 @@ public function get($orderId, $orderItemId) throw new NoSuchEntityException( __('No item with the provided ID was found in the Order. Verify the ID and try again.') ); - }; + } if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) { throw new NoSuchEntityException( @@ -123,7 +123,7 @@ public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\Messa throw new NoSuchEntityException( __('No item with the provided ID was found in the Order. Verify the ID and try again.') ); - }; + } if ($order->getIsVirtual()) { throw new InvalidTransitionException(__("Gift messages can't be used for virtual products.")); diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php index abf38f1287b7a..88d1adf92ed0b 100644 --- a/app/code/Magento/GiftMessage/Model/OrderRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php @@ -106,7 +106,7 @@ public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $g $order = $this->orderFactory->create()->load($orderId); if (!$order->getEntityId()) { throw new NoSuchEntityException(__('No order exists with this ID. Verify your information and try again.')); - }; + } if (0 == $order->getTotalItemCount()) { throw new InputException( diff --git a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php index 6eab92f65117a..6d0716a6f1c27 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php @@ -187,7 +187,7 @@ private function getDependentIndexerIds(string $indexerId) $this->getDependentIndexerIds($id) ); } - }; + } return array_unique($dependentIndexerIds); } diff --git a/app/code/Magento/Indexer/Model/DimensionModes.php b/app/code/Magento/Indexer/Model/DimensionModes.php index bbdee0ced8662..a9507a6f4d358 100644 --- a/app/code/Magento/Indexer/Model/DimensionModes.php +++ b/app/code/Magento/Indexer/Model/DimensionModes.php @@ -26,7 +26,7 @@ public function __construct(array $dimensions) $result = []; foreach ($dimensions as $dimension) { $result[$dimension->getName()] = $dimension; - }; + } return $result; })(...$dimensions); } diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index b109b87e61bbf..8ce448d06b8f2 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -44,7 +44,7 @@ private function isStateReadyForInvoice(OrderInterface $order) $order->getState() === Order::STATE_CLOSED ) { return false; - }; + } return true; } diff --git a/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml b/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml index 223b3e9888eea..75f04eae82159 100644 --- a/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml +++ b/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml @@ -2,4 +2,4 @@ /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. - */; + */ diff --git a/app/code/Magento/Theme/Model/Design/Config/Validator.php b/app/code/Magento/Theme/Model/Design/Config/Validator.php index 994eeba317a34..1279d9d9ccd20 100644 --- a/app/code/Magento/Theme/Model/Design/Config/Validator.php +++ b/app/code/Magento/Theme/Model/Design/Config/Validator.php @@ -80,7 +80,7 @@ public function validate(DesignConfigInterface $designConfig) ["templateName" => $name] ) ); - }; + } } } } diff --git a/app/code/Magento/Theme/view/frontend/templates/text.phtml b/app/code/Magento/Theme/view/frontend/templates/text.phtml index 4c4b38132c880..7d00235c0362c 100644 --- a/app/code/Magento/Theme/view/frontend/templates/text.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/text.phtml @@ -10,6 +10,6 @@ if (!empty($attr)) { foreach ($block->getAttributes() as $attribute => $value) { $attributes .= ' ' . $attribute . '="' . $value . '"'; } -}; +} echo '<' . $block->getTag() . $attributes . '>' . $block->getText() . '</' . $block->getTag() . '>'; diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php index e83811042fd8b..c335b66505b0e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php @@ -180,7 +180,7 @@ public function optionDataProvider() $fixtureOptions[$item['type']] = [ 'optionData' => $item, ]; - }; + } return $fixtureOptions; } @@ -230,7 +230,7 @@ public function optionNegativeDataProvider() $fixtureOptions[$key] = [ 'optionData' => $item, ]; - }; + } return $fixtureOptions; } diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php index 0b7c31a092280..c08ea7aa9e29b 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php @@ -87,7 +87,7 @@ public function openTab($tabName) if ($tabHeader->isVisible() && strpos($tabHeader->getAttribute('class'), '_show') === false) { $tabHeader->hover(); $tabHeader->click(); - }; + } return $this; } diff --git a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php index 17cfdc31720cc..89f51931f8dc8 100644 --- a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php +++ b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php @@ -316,7 +316,7 @@ private function prepareCsv($csvContent) $explodedArray = $compiledData['explodedArray']; } else { $explodedArray[$i] = str_replace('"', '', $explodedArray[$i]); - }; + } } $data = array_diff($explodedArray, ['%to_delete%']); $this->csv[] = $data; diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php b/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php index ffeca0f16094d..bc190a8519ae9 100644 --- a/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php +++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php @@ -24,7 +24,7 @@ function rcopy($src, $destination) // If source is not a directory stop processing if (!is_dir($src)) { return false; - }; + } // If the destination directory does not exist create it // If the destination directory could not be created stop processing diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php index 22307b4d83956..cd17183be7f78 100644 --- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php @@ -20,7 +20,7 @@ if ($product->getId()) { $product->delete(); } -}; +} $quote->delete(); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php index f204019988b79..46bdd3dd666df 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php @@ -97,7 +97,7 @@ public function testAcl() $inheritanceMessage = "Backend controller $className have to inherit " . AbstractAction::class; $errorMessages[] = $inheritanceMessage; continue; - }; + } $isAclRedefinedInTheChildClass = $this->isConstantOverwritten($controllerClass) || $this->isMethodOverwritten($controllerClass); diff --git a/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php b/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php index c9d7c8a35b243..661f9f9c0ff80 100644 --- a/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php +++ b/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php @@ -49,7 +49,7 @@ public function getIndexerIdsToRunAfter(string $indexerId): array if (array_search($indexerId, $indexerData['dependencies']) !== false) { $result[] = $id; } - }; + } return $result; } diff --git a/lib/internal/Magento/Framework/Setup/OldDbValidator.php b/lib/internal/Magento/Framework/Setup/OldDbValidator.php index 005f7bdd713be..34f916674ca56 100644 --- a/lib/internal/Magento/Framework/Setup/OldDbValidator.php +++ b/lib/internal/Magento/Framework/Setup/OldDbValidator.php @@ -47,7 +47,7 @@ public function getNotUpToDateMessage(): string $requiredVersion = $versionParser->parseConstraints('>' . $error[DbVersionInfo::KEY_REQUIRED]); if ($requiredVersion->matches($currentVersion)) { $codebaseUpdateNeeded = true; - }; + } $messages[] = sprintf( "<info>%20s %10s: %11s -> %-11s</info>", diff --git a/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php b/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php index 03c7d85251ac4..2d8348f64a5af 100644 --- a/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php +++ b/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php @@ -65,7 +65,7 @@ public function load($className) include $classSourceFile; return true; } - }; + } } return false; From ba7630ba98d8fd1196497685a1c5c14586864e9c Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 24 Oct 2018 11:57:26 -0500 Subject: [PATCH 0784/1415] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Fix static test failures --- .../Catalog/Model/Indexer/Category/Flat/Action/Full.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index 624001b498449..a62e3d8f83b85 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -183,7 +183,8 @@ private function getActualStoreTablesForCategoryFlat(): array foreach ($this->storeManager->getStores() as $store) { $actualStoreTables[] = sprintf( '%s_store_%s', - $this->connection->getTableName('catalog_category_flat'), $store->getId() + $this->connection->getTableName('catalog_category_flat'), + $store->getId() ); } From 86e035f3ba615cb5e1bb3ff0e4821b82a57fe7fe Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Wed, 24 Oct 2018 21:17:45 +0300 Subject: [PATCH 0785/1415] Cover \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection class with Integration test --- .../Model/ResourceModel/Grid/CollectionTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php index 2f3112e705c94..bc098cf1bd0ec 100644 --- a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php @@ -25,7 +25,8 @@ class CollectionTest extends \PHPUnit\Framework\TestCase */ public function setUp() { - $this->collection = Bootstrap::getObjectManager()->create(Collection::class); + $this->collection = Bootstrap::getObjectManager() + ->create(Collection::class); } /** @@ -35,7 +36,9 @@ public function setUp() */ public function testAddStoresToFilter(): void { - $collectionSize = $this->collection->addStoreFilter(1)->load(false, false)->getSize(); + $collectionSize = $this->collection->addStoreFilter(1) + ->load(false, false) + ->getSize(); $this->assertEquals(2, $collectionSize); } } From 2fcc1830d0a3a24dce25f986c46b97d15f3c4bae Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 22:36:36 +0300 Subject: [PATCH 0786/1415] graphQl-44: added ComplexTextValue to graphQl module --- .../Resolver/Product/ProductTextAttribute.php | 30 +++++++++- .../ProductTextAttribute/HtmlContent.php | 60 ------------------- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 --- .../CatalogGraphQl/etc/schema.graphqls | 8 +-- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ++++++++++++ app/code/Magento/GraphQl/etc/schema.graphqls | 4 ++ 6 files changed, 71 insertions(+), 76 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php create mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 171e84a65aba4..febcd12f0e96f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,12 +10,29 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Catalog\Helper\Output as OutputHelper; /** - * Resolve rendered content for text attributes + * Resolve rendered content for attributes where HTML content is allowed */ class ProductTextAttribute implements ResolverInterface { + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param OutputHelper $outputHelper + */ + public function __construct( + OutputHelper $outputHelper + ) { + $this->outputHelper = $outputHelper; + } + /** * @inheritdoc */ @@ -26,8 +43,15 @@ public function resolve( array $value = null, array $args = null ): array { - $value['field'] = $field->getName(); + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return $value; + return ['html' => $renderedValue]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php deleted file mode 100644 index 724d0826dbb3d..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Catalog\Model\Product; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Catalog\Helper\Output as OutputHelper; - -/** - * HTML content of Product Text Attribute - */ -class HtmlContent implements ResolverInterface -{ - /** - * @var OutputHelper - */ - private $outputHelper; - - /** - * @param OutputHelper $outputHelper - */ - public function __construct( - OutputHelper $outputHelper - ) { - $this->outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): ?string { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - if (!isset($value['field'])) { - throw new GraphQlInputException(__('"field" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $value['field']; - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - - return $renderedValue; - } -} diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 8d4ca97001d3d..68a292ede6b4a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,13 +63,6 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList"> - <arguments> - <argument name="formats" xsi:type="array"> - <item name="html" xsi:type="string">Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html</item> - </argument> - </arguments> - </type> <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="customFilters" xsi:type="array"> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index ad724c18a5c9a..fb7dd4ee2c8f0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -556,7 +556,3 @@ type SortFields @doc(description: "SortFields contains a default value for sort default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } - -type ProductTextAttribute @doc(description: "Product text attribute.") { - html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") -} diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php new file mode 100644 index 0000000000000..2ec4d24017b0e --- /dev/null +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -0,0 +1,38 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Model\Resolver\ComplexTextValue; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * HTML format for complex text value. + * + * Initially, a value from parent resolver should be in HTML format, therefore, there is no any customization. + */ +class HtmlFormat implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): ?string { + if (!isset($value['html'])) { + throw new GraphQlInputException(__('"html" value should be specified')); + } + + return $value['html']; + } +} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index c6651cdde0cb3..8923776a63bcf 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -35,3 +35,7 @@ enum SortEnum @doc(description: "This enumeration indicates whether to return re ASC DESC } + +type ComplexTextValue { + html: String! @doc(description: "HTML format") @resolver(class: "\\Magento\\GraphQl\\Model\\Resolver\\ComplexTextValue\\HtmlFormat") +} From 6bb825873812cff3ab77d71f1f3542d40aae2b85 Mon Sep 17 00:00:00 2001 From: ashutosh <ashutosh045@webkul.com> Date: Thu, 25 Oct 2018 01:07:09 +0530 Subject: [PATCH 0787/1415] fixed Product Advanced Pricing design issue #18775 --- app/code/Magento/Ui/view/base/web/templates/form/field.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/form/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html index ed84e158819a2..6a095b4da14ed 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html @@ -8,8 +8,8 @@ visible="visible" css="$data.additionalClasses" attr="'data-index': index"> - <div class="admin__field-label"> - <label if="$data.label" visible="$data.labelVisible" attr="for: uid"> + <div class="admin__field-label" visible="$data.labelVisible"> + <label if="$data.label" attr="for: uid"> <span translate="label" attr="'data-config-scope': $data.scopeLabel" /> </label> </div> From be525d11b45746670822462ab5c1125fd2aca7de Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 23:13:05 +0300 Subject: [PATCH 0788/1415] graphQl-44: refactored resolver name --- ...oductTextAttribute.php => ProductComplexTextAttribute.php} | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 4 ++-- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductTextAttribute.php => ProductComplexTextAttribute.php} (95%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php similarity index 95% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index febcd12f0e96f..7cf7225d0f61c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -17,7 +17,7 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextAttribute implements ResolverInterface +class ProductComplexTextAttribute implements ResolverInterface { /** * @var OutputHelper diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index fb7dd4ee2c8f0..423283bdda7b0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 615e50f640380..1ab7ed5890472 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -266,7 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertTextEavAttributes($product, $response['products']['items'][0]); + $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -950,7 +950,7 @@ private function assertEavAttributes($product, $actualResponse) * @param ProductInterface $product * @param array $actualResponse */ - private function assertTextEavAttributes($product, $actualResponse) + private function assertComplexTextAttributes($product, $actualResponse) { $eavAttributes = [ 'description', From 1a745a5db170b77ed92b6d71444bc8c8e0f0aa3e Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 24 Oct 2018 15:47:58 -0500 Subject: [PATCH 0789/1415] MAGETWO-95798: All country state's are shown for USA when shipping form has custom address attributes. --- .../Ui/view/base/web/js/form/element/region.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/region.js b/app/code/Magento/Ui/view/base/web/js/form/element/region.js index 45d38b339b50b..f6eafcf49284d 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/region.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/region.js @@ -78,13 +78,12 @@ define([ * @param {String} field */ filter: function (value, field) { - var country = registry.get(this.parentName + '.' + 'country_id'), - option; + var superFn = this._super; - if (country) { - option = country.indexedOptions[value]; + registry.get(this.parentName + '.' + 'country_id', function (country) { + var option = country.indexedOptions[value]; - this._super(value, field); + superFn.call(this, value, field); if (option && option['is_region_visible'] === false) { // hide select and corresponding text input field if region must not be shown for selected country @@ -94,7 +93,7 @@ define([ this.toggleInput(false); } } - } + }.bind(this)); } }); }); From e5f866d185489d85248134da0aec7f20df468ff1 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim <gy741.kim@gmail.com> Date: Thu, 25 Oct 2018 09:28:34 +0900 Subject: [PATCH 0790/1415] Remove unnecessary conditional statements --- .../Magento/User/Controller/Adminhtml/User/Role/SaveRole.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index 44862f1fce2a0..4a9b98f214ee4 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -59,9 +59,8 @@ private function getSecurityCookie() { if (!($this->securityCookie instanceof SecurityCookie)) { return \Magento\Framework\App\ObjectManager::getInstance()->get(SecurityCookie::class); - } else { - return $this->securityCookie; } + return $this->securityCookie; } /** From 9d958bbb4103361b2004dcc620a5c9b1b6e4437b Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Thu, 25 Oct 2018 10:40:02 +0300 Subject: [PATCH 0791/1415] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 73025023c23c8..45c6c90a76973 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -25,7 +25,6 @@ <argument name="ProductAttribute" type="string"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.GridFilterFrontEndLabel}}" userInput="{{ProductAttribute}}" stepKey="navigateToAttributeEditPage1" /> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="navigateToAttributeEditPage2" /> <waitForPageLoad stepKey="waitForPageLoad2" /> From bf0030fbbd49ce1c40a17bd1f0717a9dffeb326d Mon Sep 17 00:00:00 2001 From: Ronak Patel <ronak2ram@gmail.com> Date: Thu, 25 Oct 2018 13:12:00 +0530 Subject: [PATCH 0792/1415] Update blocks --- app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php | 5 ++++- .../Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php index 962127e16f716..d7c0008c7d927 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php @@ -78,7 +78,10 @@ private function getBlocksData(array $blockIdentifiers): array $blocksData = []; try { foreach ($blockIdentifiers as $blockIdentifier) { - $blocksData[$blockIdentifier] = $this->blockDataProvider->getData($blockIdentifier); + $blockData = $this->blockDataProvider->getData($blockIdentifier); + if (!empty($blockData)) { + $blocksData[$blockIdentifier] = $blockData; + } } } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index 5b7e632a73cb0..d47a0dca27157 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -49,7 +49,7 @@ public function getData(string $blockIdentifier): array $block = $this->blockRepository->getById($blockIdentifier); if (false === $block->isActive()) { - throw new NoSuchEntityException(); + return []; } $renderedContent = $this->widgetFilter->filter($block->getContent()); From 6e9d5e5fcda4ce91ef25559bb946c8e52e777148 Mon Sep 17 00:00:00 2001 From: Janak <janak@krishtechnolabs.com> Date: Tue, 16 Oct 2018 14:26:48 +0530 Subject: [PATCH 0793/1415] Fix customer unsubscribed issue --- app/code/Magento/Newsletter/Model/Subscriber.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..c58c2bbf3ba3e 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -597,6 +597,8 @@ protected function _updateCustomerSubscription($customerId, $subscribe) } elseif (($this->getStatus() == self::STATUS_UNCONFIRMED) && ($customerData->getConfirmation() === null)) { $status = self::STATUS_SUBSCRIBED; $sendInformationEmail = true; + } elseif (($this->getStatus() == self::STATUS_NOT_ACTIVE) && ($customerData->getConfirmation() === null)) { + $status = self::STATUS_NOT_ACTIVE; } else { $status = self::STATUS_UNSUBSCRIBED; } From 069195ce52b458f6ec9dbcc2907c27722e0f7990 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Thu, 25 Oct 2018 11:44:36 +0300 Subject: [PATCH 0794/1415] Added form fieldset before html to \Magento\Framework\Data\Form\Element\Fieldset in getElementHtml() method --- lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php index 66b1299b98696..90482ab55fc71 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php @@ -43,7 +43,8 @@ public function __construct( */ public function getElementHtml() { - $html = '<fieldset id="' . $this->getHtmlId() . '"' . $this->serialize( + $html = $this->getBeforeElementHtml(); + $html .= '<fieldset area-hidden="false" id="' . $this->getHtmlId() . '"' . $this->serialize( ['class'] ) . $this->_getUiId() . '>' . "\n"; if ($this->getLegend()) { From 42e3fd5fa39beee02c9f03e7cda6a1165e34482e Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Thu, 25 Oct 2018 02:01:26 -0700 Subject: [PATCH 0795/1415] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - .../Magento/Persistent/Test/Mftf/Data/PersistentData.xml | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 45c6c90a76973..ddd73b4191afc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -13,7 +13,6 @@ <argument name="ProductAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> diff --git a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml index 3d42ae6da81a5..39e55693811e9 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml @@ -22,16 +22,16 @@ </entity> <entity name="PersistentLogoutClearEnabled" type="persistent_config_state"> - <requiredEntity type="persistent_options_logout_clear">persistentEnabledLogoutClear</requiredEntity> + <requiredEntity type="persistent_options_logout_clear">PersistentEnabledLogoutClear</requiredEntity> </entity> - <entity name="persistentEnabledLogoutClear" type="logout_clear"> + <entity name="PersistentEnabledLogoutClear" type="logout_clear"> <data key="value">1</data> </entity> <entity name="PersistentLogoutClearDisable" type="persistent_config_state"> - <requiredEntity type="persistent_options_logout_clear">persistentDisableLogoutClear</requiredEntity> + <requiredEntity type="persistent_options_logout_clear">PersistentDisableLogoutClear</requiredEntity> </entity> - <entity name="persistentDisableLogoutClear" type="logout_clear"> + <entity name="PersistentDisableLogoutClear" type="logout_clear"> <data key="value">0</data> </entity> </entities> From 4349d022166c905e4bd77f3bfb36118c7310ff19 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 11:08:56 +0200 Subject: [PATCH 0796/1415] Run tests without magento installation --- dev/travis/before_script.sh | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index c27e65d3897c7..135152928539c 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -138,25 +138,27 @@ case $TEST_SUITE in api-functional) echo "Installing Magento" mysql -uroot -e 'CREATE DATABASE magento2;' - php bin/magento setup:install -q \ - --language="en_US" \ - --timezone="UTC" \ - --currency="USD" \ - --base-url="http://${MAGENTO_HOST_NAME}/" \ - --admin-firstname="John" \ - --admin-lastname="Doe" \ - --backend-frontname="backend" \ - --admin-email="admin@example.com" \ - --admin-user="admin" \ - --use-rewrites=1 \ - --admin-use-security-key=0 \ - --admin-password="123123q" - - echo "Enabling production mode" - php bin/magento deploy:mode:set production +# php bin/magento setup:install -q \ +# --language="en_US" \ +# --timezone="UTC" \ +# --currency="USD" \ +# --base-url="http://${MAGENTO_HOST_NAME}/" \ +# --admin-firstname="John" \ +# --admin-lastname="Doe" \ +# --backend-frontname="backend" \ +# --admin-email="admin@example.com" \ +# --admin-user="admin" \ +# --use-rewrites=1 \ +# --admin-use-security-key=0 \ +# --admin-password="123123q" + +# echo "Enabling production mode" +# php bin/magento deploy:mode:set production echo "Prepare api-functional tests for running" cd dev/tests/api-functional + cp config/install-config-mysql.php.dist config/install-config-mysql.php + sed -e "s?http://localhost/?http://${MAGENTO_HOST_NAME}/?g" --in-place ./config/install-config-mysql.php cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml From 6a6079dcde8068dbac8173699ae4450079ed3201 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Thu, 25 Oct 2018 15:18:26 +0300 Subject: [PATCH 0797/1415] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix getCountAllProductImages select and cover class with unit tests. --- .../Model/ResourceModel/Product/Image.php | 8 +- .../Model/ResourceModel/Product/ImageTest.php | 171 ++++++++++++++++++ 2 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 123f358be40c8..5a290d5141e80 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -77,7 +77,13 @@ public function getAllProductImages(): \Generator */ public function getCountAllProductImages(): int { - $select = $this->getVisibleImagesSelect()->reset('columns')->columns('count(*)'); + $select = $this->getVisibleImagesSelect() + ->reset('columns') + ->reset('distinct') + ->columns( + new \Zend_Db_Expr('count(distinct value)') + ); + return (int) $this->connection->fetchOne($select); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php new file mode 100644 index 0000000000000..16e245ba640cb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -0,0 +1,171 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product; + +use Magento\Catalog\Model\ResourceModel\Product\Image; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Query\Generator; +use Magento\Framework\DB\Select; +use Magento\Framework\App\ResourceConnection; +use Magento\Catalog\Model\ResourceModel\Product\Gallery; + +class ImageTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $connectionMock; + + /** + * @var Generator | \PHPUnit_Framework_MockObject_MockObject + */ + protected $generatorMock; + + /** + * @var ResourceConnection | \PHPUnit_Framework_MockObject_MockObject + */ + protected $resourceMock; + + /** + * @var Image + */ + protected $imageModel; + + /** + * @var int + */ + protected $imagesCount = 50; + + /** + * @var int + */ + protected $batchSize = 10; + + protected function setUp(): void + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->connectionMock = $this->createMock(AdapterInterface::class); + + $this->resourceMock = $this->createMock(ResourceConnection::class); + $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); + $this->resourceMock->method('getTableName')->willReturnArgument(0); + + $this->generatorMock = $this->createMock(Generator::class); + + $this->imageModel = $objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock, + 'batchSize' => $this->batchSize + ] + ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_MockObject + { + $selectMock = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + $selectMock->expects($this->once()) + ->method('distinct') + ->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('from') + ->with( + ['images' => Gallery::GALLERY_TABLE], + 'value as filepath' + )->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('where') + ->with('disabled = 0') + ->willReturnSelf(); + + return $selectMock; + } + + public function testGetCountAllProductImages(): void + { + $selectMock = $this->getVisibleImagesSelectMock(); + $selectMock->expects($this->exactly(2)) + ->method('reset') + ->withConsecutive( + ['columns'], + ['distinct'] + )->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('columns') + ->with(new \Zend_Db_Expr('count(distinct value)')) + ->willReturnSelf(); + + $this->connectionMock->expects($this->once()) + ->method('select') + ->willReturn($selectMock); + $this->connectionMock->expects($this->once()) + ->method('fetchOne') + ->with($selectMock) + ->willReturn($this->imagesCount); + + $this->assertSame($this->imagesCount, $this->imageModel->getCountAllProductImages()); + } + + public function testGetAllProductImages(): void + { + $getBatchIteratorMock = function ($selectMock, $imagesCount, $batchSize): array { + $result = []; + $count = $imagesCount / $batchSize; + while ($count) { + $count--; + $result[$count] = $selectMock; + } + + return $result; + }; + + $getAllProductImagesSelectFetchResults = function ($batchSize): array { + $result = []; + $count = $batchSize; + while ($count) { + $count--; + $result[$count] = $count; + } + + return $result; + }; + + $this->connectionMock->expects($this->once()) + ->method('select') + ->willReturn($this->getVisibleImagesSelectMock()); + + $fetchResult = $getAllProductImagesSelectFetchResults($this->batchSize); + $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) + ->method('fetchAll') + ->willReturn($fetchResult); + + /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ + $selectMock = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $batchIteratorMock = $getBatchIteratorMock($selectMock, $this->imagesCount, $this->batchSize); + $this->generatorMock->expects($this->once()) + ->method('generate') + ->with( + 'value_id', + $selectMock, + $this->batchSize, + \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR + )->willReturn($batchIteratorMock); + + $this->assertCount($this->imagesCount, $this->imageModel->getAllProductImages()); + } +} From ccfffbc78a4e2c0204c0f16e8b1ff32316f5f7c1 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 14:27:13 +0200 Subject: [PATCH 0798/1415] Deploy test modules before api-functional tests --- .travis.yml | 4 ++-- dev/travis/before_install.sh | 2 +- dev/travis/before_script.sh | 39 ++++++++++++++++++------------------ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 930172a9ea6e0..25b18949f0386 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: # - TEST_SUITE=integration INTEGRATION_INDEX=2 # - TEST_SUITE=integration INTEGRATION_INDEX=3 # - TEST_SUITE=functional - - TEST_SUITE=api-functional + - TEST_SUITE=graphql-api-functional matrix: exclude: - php: 7.1 @@ -66,4 +66,4 @@ script: - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi - - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/api-functional; fi + - if [ $TEST_SUITE == "graphql-api-functional" ]; then phpunit -c dev/tests/api-functional; fi diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index 44ba3fd8b74f1..845d70e4e79fd 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "api-functional" ]; then +if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "graphql-api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 135152928539c..64591e8112cef 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -135,34 +135,35 @@ case $TEST_SUITE in cd ../../.. ;; - api-functional) + graphql-api-functional) echo "Installing Magento" mysql -uroot -e 'CREATE DATABASE magento2;' -# php bin/magento setup:install -q \ -# --language="en_US" \ -# --timezone="UTC" \ -# --currency="USD" \ -# --base-url="http://${MAGENTO_HOST_NAME}/" \ -# --admin-firstname="John" \ -# --admin-lastname="Doe" \ -# --backend-frontname="backend" \ -# --admin-email="admin@example.com" \ -# --admin-user="admin" \ -# --use-rewrites=1 \ -# --admin-use-security-key=0 \ -# --admin-password="123123q" - -# echo "Enabling production mode" -# php bin/magento deploy:mode:set production + php bin/magento setup:install -q \ + --language="en_US" \ + --timezone="UTC" \ + --currency="USD" \ + --base-url="http://${MAGENTO_HOST_NAME}/" \ + --admin-firstname="John" \ + --admin-lastname="Doe" \ + --backend-frontname="backend" \ + --admin-email="admin@example.com" \ + --admin-user="admin" \ + --use-rewrites=1 \ + --admin-use-security-key=0 \ + --admin-password="123123q" + + echo "Enabling production mode" + php bin/magento deploy:mode:set production echo "Prepare api-functional tests for running" cd dev/tests/api-functional - cp config/install-config-mysql.php.dist config/install-config-mysql.php - sed -e "s?http://localhost/?http://${MAGENTO_HOST_NAME}/?g" --in-place ./config/install-config-mysql.php + cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests + php ../../../bin/magento setup:upgrade cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml cd ../../.. + php bin/magento setup:upgrade ;; esac From 33f40d63ee1d102e81822341fadeb4cd5af68997 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 14:50:06 +0200 Subject: [PATCH 0799/1415] Remove redundant setup:upgrade --- .travis.yml | 2 +- dev/travis/before_script.sh | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25b18949f0386..db42be9f1e217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ matrix: - php: 7.1 env: TEST_SUITE=functional - php: 7.1 - env: TEST_SUITE=api-functional + env: TEST_SUITE=graphql-api-functional cache: apt: true directories: diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 64591e8112cef..8b5dcab310418 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -158,7 +158,6 @@ case $TEST_SUITE in echo "Prepare api-functional tests for running" cd dev/tests/api-functional cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests - php ../../../bin/magento setup:upgrade cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml From 35356efc619f0165dfe04f5762e9af63816569a7 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Thu, 25 Oct 2018 14:53:30 +0200 Subject: [PATCH 0800/1415] magento-engcom/import-export-improvements#51: fix for uploader filepath --- .../Magento/CatalogImportExport/Model/Import/Uploader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index e7ffe408cc732..8dc551c407277 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -113,15 +113,15 @@ public function __construct( \Magento\Framework\Filesystem\File\ReadFactory $readFactory, $filePath = null ) { - if ($filePath !== null) { - $this->_setUploadFile($filePath); - } $this->_imageFactory = $imageFactory; $this->_coreFileStorageDb = $coreFileStorageDb; $this->_coreFileStorage = $coreFileStorage; $this->_validator = $validator; $this->_directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $this->_readFactory = $readFactory; + if ($filePath !== null) { + $this->_setUploadFile($filePath); + } } /** From 41bf2a1485ead39c75d97cccc819c9cc2091f0ca Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 15:11:04 +0200 Subject: [PATCH 0801/1415] Enable back other tests --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index db42be9f1e217..78b088c9d848d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: -# - TEST_SUITE=unit -# - TEST_SUITE=static -# - TEST_SUITE=js GRUNT_COMMAND=spec -# - TEST_SUITE=js GRUNT_COMMAND=static -# - TEST_SUITE=integration INTEGRATION_INDEX=1 -# - TEST_SUITE=integration INTEGRATION_INDEX=2 -# - TEST_SUITE=integration INTEGRATION_INDEX=3 -# - TEST_SUITE=functional + - TEST_SUITE=unit + - TEST_SUITE=static + - TEST_SUITE=js GRUNT_COMMAND=spec + - TEST_SUITE=js GRUNT_COMMAND=static + - TEST_SUITE=integration INTEGRATION_INDEX=1 + - TEST_SUITE=integration INTEGRATION_INDEX=2 + - TEST_SUITE=integration INTEGRATION_INDEX=3 + - TEST_SUITE=functional - TEST_SUITE=graphql-api-functional matrix: exclude: From 9cc9cf7fdc0067192fde233c1f3d5d6979ea862f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Thu, 25 Oct 2018 16:56:12 +0300 Subject: [PATCH 0802/1415] MAGETWO-95833: Shared gift registry does not show the special price for a configurable product - Use simple product to get price. --- .../Block/Cart/Item/Renderer/Configurable.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/Configurable.php b/app/code/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/Configurable.php index 3b657dd1ab2d0..77110975401ff 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/Configurable.php @@ -70,4 +70,14 @@ public function getIdentities() } return $identities; } + + /** + * Get price for exact simple product added to cart + * + * @inheritdoc + */ + public function getProductPriceHtml(\Magento\Catalog\Model\Product $product) + { + return parent::getProductPriceHtml($this->getChildProduct()); + } } From 879961ccdc740003f9e83fdc2057a1e141db65da Mon Sep 17 00:00:00 2001 From: vprohorov <vitaliy_prokharau@epam.com> Date: Wed, 24 Oct 2018 15:33:29 +0300 Subject: [PATCH 0803/1415] MAGETWO-95821: Order fails on review step if gift card applied - Adding exception for orders with zero grandTotal --- .../Controller/Express/AbstractExpress.php | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php index 571d73d07b68e..fa131f9591fa9 100644 --- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php +++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php @@ -7,12 +7,17 @@ use Magento\Checkout\Controller\Express\RedirectLoginInterface; use Magento\Framework\App\Action\Action as AppAction; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Abstract Express Checkout Controller * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -abstract class AbstractExpress extends AppAction implements RedirectLoginInterface +abstract class AbstractExpress extends AppAction implements + RedirectLoginInterface, + HttpGetActionInterface, + HttpPostActionInterface { /** * @var \Magento\Paypal\Model\Express\Checkout @@ -137,6 +142,14 @@ protected function _initCheckout() $this->getResponse()->setStatusHeader(403, '1.1', 'Forbidden'); throw new \Magento\Framework\Exception\LocalizedException(__('We can\'t initialize Express Checkout.')); } + if (!(float)$quote->getGrandTotal()) { + throw new \Magento\Framework\Exception\LocalizedException( + __( + 'PayPal can\'t process orders with a zero balance due. ' + . 'To finish your purchase, please go through the standard checkout process.' + ) + ); + } if (!isset($this->_checkoutTypes[$this->_checkoutType])) { $parameters = [ 'params' => [ @@ -151,6 +164,8 @@ protected function _initCheckout() } /** + * Get Proper Checkout Token + * * Search for proper checkout token in request or session or (un)set specified one * Combined getter/setter * @@ -221,8 +236,7 @@ protected function _getQuote() } /** - * Returns before_auth_url redirect parameter for customer session - * @return null + * @inheritdoc */ public function getCustomerBeforeAuthUrl() { @@ -230,8 +244,7 @@ public function getCustomerBeforeAuthUrl() } /** - * Returns a list of action flags [flag_key] => boolean - * @return array + * @inheritdoc */ public function getActionFlagList() { @@ -240,6 +253,7 @@ public function getActionFlagList() /** * Returns login url parameter for redirect + * * @return string */ public function getLoginUrl() @@ -249,6 +263,7 @@ public function getLoginUrl() /** * Returns action name which requires redirect + * * @return string */ public function getRedirectActionName() @@ -269,4 +284,9 @@ public function redirectLogin() $this->_urlHelper->addRequestParam($this->_customerUrl->getLoginUrl(), ['context' => 'checkout']) ); } + + /** + * @inheritdoc + */ + abstract public function execute(); } From 466daaa332e85eee15d3391d0ceead11855e90dd Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Thu, 25 Oct 2018 18:15:55 +0300 Subject: [PATCH 0804/1415] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix code style; --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 16e245ba640cb..9c783e237ab24 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -131,7 +131,7 @@ public function testGetAllProductImages(): void return $result; }; - $getAllProductImagesSelectFetchResults = function ($batchSize): array { + $getFetchResults = function ($batchSize): array { $result = []; $count = $batchSize; while ($count) { @@ -146,7 +146,7 @@ public function testGetAllProductImages(): void ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); - $fetchResult = $getAllProductImagesSelectFetchResults($this->batchSize); + $fetchResult = $getFetchResults($this->batchSize); $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) ->method('fetchAll') ->willReturn($fetchResult); From f82912dc75d57694b056ca6a7ca198fde1e6b108 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 25 Oct 2018 18:34:19 +0300 Subject: [PATCH 0805/1415] graphQl-44: fixed copyrights --- .../GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php index 2ec4d24017b0e..fffca765faba6 100644 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -1,7 +1,7 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); From 992a750e8870e413b0af592ffea819308d448a24 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 9 Oct 2018 10:36:33 -0500 Subject: [PATCH 0806/1415] MC-4154: Banner Background Image disappear after saving Schedule Update page of CMS Block - fixed JS console error when saving scheduled update --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js index 760e0785a7893..3526abefa233b 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js @@ -129,7 +129,7 @@ define([ removeEvents: function (wysiwygId) { var editor; - if (typeof tinyMceEditors !== 'undefined') { + if (typeof tinyMceEditors !== 'undefined' && tinyMceEditors.get(wysiwygId)) { editor = tinyMceEditors.get(wysiwygId); varienGlobalEvents.removeEventHandler('tinymceChange', editor.onChangeContent); } From 008fe5d2bec2167e29d45001a674de8249e393e7 Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Thu, 25 Oct 2018 23:31:03 +0530 Subject: [PATCH 0807/1415] fixed Translation issue send-friend in send.phtml #18779 --- .../Magento/SendFriend/view/frontend/templates/send.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 2b25e0efab84a..862ef5fdebc3c 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -23,7 +23,7 @@ </div> <fieldset class="fieldset"> <div class="field name required"> - <label for="recipients-name<%- data._index_ %>" class="label"><span><?= $block->escapeJs($block->escapeHtml(__('Name'))) ?></span></label> + <label for="recipients-name<%- data._index_ %>" class="label"><span><?= $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="recipients[name][<%- data._index_ %>]" type="text" title="<?= $block->escapeHtmlAttr(__('Name')) ?>" class="input-text" id="recipients-name<%- data._index_ %>" data-validate="{required:true}"/> @@ -31,7 +31,7 @@ </div> <div class="field email required"> - <label for="recipients-email<%- data._index_ %>" class="label"><span><?= $block->escapeJs($block->escapeHtml(__('Email'))) ?></span></label> + <label for="recipients-email<%- data._index_ %>" class="label"><span><?= $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="recipients[email][<%- data._index_ %>]" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" id="recipients-email<%- data._index_ %>" type="email" class="input-text" From dd6bcfb3188a5a0e9cbb113be838c222cbf27da2 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:23:31 +0300 Subject: [PATCH 0808/1415] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- .../Magento/Config/App/Config/Type/System.php | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 2b65c2791365a..cc31b9ae6e27a 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -131,6 +131,32 @@ public function get($path = '') return $this->getWithParts($path); } + /** + * Merge newly loaded config data into already loaded. + * + * @param array $newData + * @return void + */ + private function mergeData(array $newData): void + { + if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; + unset($newData[ScopeInterface::SCOPE_DEFAULT]); + } + foreach ($newData as $scopeType => $scopeTypeData) { + if (!array_key_exists($scopeType, $this->data)) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[$scopeType] = (array)$scopeTypeData; + } else { + foreach ($scopeTypeData as $scopeId => $scopeData) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[$scopeType][$scopeId] = (array)$scopeData; + } + } + } + } + /** * Proceed with parts extraction from path. * @@ -143,8 +169,10 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { + //First filling data property with unprocessed data for post-processors to be able to use. $data = $this->readData(); - $this->data = array_replace_recursive($this->data, $this->postProcessor->process($data)); + //Post-processing only the data we know is not yet processed. + $this->mergeData($this->postProcessor->process($data)); } return $this->data[$pathParts[0]]; @@ -154,12 +182,11 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive( - $this->data, - $scopeData = $this->loadDefaultScopeData($scopeType) - ); + //Adding unprocessed data to the data property so it can be used in post-processing. + $this->mergeData($scopeData = $this->loadDefaultScopeData($scopeType)); + //Only post-processing the data we know is raw. $scopeData = $this->postProcessor->process($scopeData); - $this->data = array_replace_recursive($this->data, $scopeData); + $this->mergeData($scopeData); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -169,9 +196,11 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); - $this->data = array_replace_recursive($this->data, $scopeData); + //Adding unprocessed data to the data property so it can be used in post-processing. + $this->mergeData($scopeData); + //Only post-processing the data we know is raw. $scopeData = $this->postProcessor->process($scopeData); - $this->data = array_replace_recursive($this->data, $scopeData); + $this->mergeData($scopeData); } return isset($this->data[$scopeType][$scopeId]) From ff5b15ac4c100315927000434550b90e9370d203 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:35:10 +0300 Subject: [PATCH 0809/1415] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index cc31b9ae6e27a..7f61ded7d8835 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -22,6 +22,7 @@ * * @api * @since 100.1.2 + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class System implements ConfigTypeInterface { From afd779379611a21cc865966c7517e649146e37cc Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:47:02 +0300 Subject: [PATCH 0810/1415] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 7f61ded7d8835..46b143fd15ab2 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,6 +140,7 @@ public function get($path = '') */ private function mergeData(array $newData): void { + return $this->data = array_merge_recursive($this->data, $newData); if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From a70858bfe5621fe850cff47b0572661db4cab0ca Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 13:09:00 +0300 Subject: [PATCH 0811/1415] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 46b143fd15ab2..7c072dcd1a2aa 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,7 +140,8 @@ public function get($path = '') */ private function mergeData(array $newData): void { - return $this->data = array_merge_recursive($this->data, $newData); + $this->data = array_replace_recursive($this->data, $newData); + return; if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From 88b030313513aeb7021f6af841be559bb9f426e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 13:19:29 +0300 Subject: [PATCH 0812/1415] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 7c072dcd1a2aa..7f61ded7d8835 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,8 +140,6 @@ public function get($path = '') */ private function mergeData(array $newData): void { - $this->data = array_replace_recursive($this->data, $newData); - return; if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From afe43948a64f0882112f79eb3dc29fbbb02713e9 Mon Sep 17 00:00:00 2001 From: Tom Richards <tom.r@delegator.com> Date: Thu, 25 Oct 2018 15:30:32 -0400 Subject: [PATCH 0813/1415] Replace erroneous usage of unsData method --- .../Magento/GroupedProduct/Model/Product/Type/Grouped.php | 2 +- .../Test/Unit/Model/Product/Type/GroupedTest.php | 4 ++-- .../Magento/Reports/Model/Product/Index/AbstractIndex.php | 2 +- .../testsuite/Magento/Newsletter/Controller/ManageTest.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index 80824d45cb6e5..673450838fb94 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -236,7 +236,7 @@ public function getAssociatedProducts($product) */ public function flushAssociatedProductsCache($product) { - return $product->unsData($this->_keyAssociatedProducts); + return $product->unsetData($this->_keyAssociatedProducts); } /** diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php index 06c07a8dc34a8..e50d6491a6aca 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php @@ -611,9 +611,9 @@ public function testPrepareForCartAdvancedZeroQty() public function testFlushAssociatedProductsCache() { - $productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['unsData']); + $productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['unsetData']); $productMock->expects($this->once()) - ->method('unsData') + ->method('unsetData') ->with('_cache_instance_associated_products') ->willReturnSelf(); $this->assertEquals($productMock, $this->_model->flushAssociatedProductsCache($productMock)); diff --git a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php index 5682892a77c60..56991e290dec6 100644 --- a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php +++ b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php @@ -252,7 +252,7 @@ public function clean() public function registerIds($productIds) { $this->_getResource()->registerIds($this, $productIds); - $this->_getSession()->unsData($this->_countCacheKey); + $this->_getSession()->unsetData($this->_countCacheKey); return $this; } } diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php index 5a094eb05c774..175c1c7c6c668 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php @@ -40,7 +40,7 @@ protected function setUp() protected function tearDown() { $this->customerSession->setCustomerId(null); - $this->coreSession->unsData('_form_key'); + $this->coreSession->unsetData('_form_key'); } /** From 3d0d8b7674c6798c3907cb77e690f62ef5310592 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Fri, 26 Oct 2018 01:46:45 +0530 Subject: [PATCH 0814/1415] Issue #18150 fixed --- app/code/Magento/Backup/Controller/Adminhtml/Index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index dcafbc7370d2d..142211fe90a44 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -19,7 +19,7 @@ abstract class Index extends \Magento\Backend\App\Action * * @see _isAllowed() */ - const ADMIN_RESOURCE = 'Magento_Backend::backup'; + const ADMIN_RESOURCE = 'Magento_Backup::backup'; /** * Core registry From b85984979deb494d12942446d6a8ab9e876c2d31 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Thu, 25 Oct 2018 16:20:52 -0500 Subject: [PATCH 0815/1415] Merge remote-tracking branch 'upstream/2.3.0-release' into 2.3.0-release-sync --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 9cab91ce52bd8..2c003a67598df 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -454,7 +454,9 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image + small_image { + path + } small_image_label special_from_date special_price From c58ac50f9f090e2094639b006dca414b13a225d5 Mon Sep 17 00:00:00 2001 From: Jason Evans <evans022@gmail.com> Date: Thu, 25 Oct 2018 16:29:39 -0500 Subject: [PATCH 0816/1415] Issue #14571 - Wrong column type when creating temporary tables for flat catalog --- .../Indexer/Product/Flat/TableBuilder.php | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php index a32379b8c0a67..a3d958ea537e1 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php @@ -7,6 +7,9 @@ use Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterfaceFactory; +/** + * Class TableBuilder + */ class TableBuilder { /** @@ -137,13 +140,23 @@ protected function _createTemporaryTable($tableName, array $columns, $valueField ); $flatColumns = $this->_productIndexerHelper->getFlatColumns(); - $temporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER); + $temporaryTableBuilder->addColumn( + 'entity_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['unsigned'=>true] + ); $temporaryTableBuilder->addColumn('type_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT); $temporaryTableBuilder->addColumn('attribute_set_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER); - $valueTemporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER); + $valueTemporaryTableBuilder->addColumn( + 'entity_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['unsigned'=>true] + ); /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ foreach ($columns as $columnName => $attribute) { @@ -198,9 +211,10 @@ protected function _getTemporaryTableName($tableName) * Fill temporary entity table * * @param string $tableName - * @param array $columns - * @param array $changedIds + * @param array $columns + * @param array $changedIds * @return void + * @throws \Exception */ protected function _fillTemporaryEntityTable($tableName, array $columns, array $changedIds = []) { @@ -244,11 +258,12 @@ protected function _addPrimaryKeyToTable($tableName, $columnName = 'entity_id') * Fill temporary table by data from products EAV attributes by type * * @param string $tableName - * @param array $tableColumns - * @param array $changedIds + * @param array $tableColumns + * @param array $changedIds * @param string $valueFieldSuffix * @param int $storeId * @return void + * @throws \Exception */ protected function _fillTemporaryTable( $tableName, @@ -345,6 +360,8 @@ protected function _fillTemporaryTable( } /** + * Get Metadata Pool + * * @return \Magento\Framework\EntityManager\MetadataPool * @deprecated 101.1.0 */ From 86a30b6295fec501b0ecaa27e173bcdefc8fa95b Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Tue, 16 Oct 2018 09:04:53 -0400 Subject: [PATCH 0817/1415] Write intercepted mapping to generated/metadata during compilation This prevents the intercepted cache from being cleared following compilation. The mapping is stored in the frontend cache when the mapping metadata file is not present, ie developer, default modes. Fixes #17680 --- .../Framework/Interception/Config/Config.php | 111 ++++++++++++++---- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/Interception/Config/Config.php b/lib/internal/Magento/Framework/Interception/Config/Config.php index 7c80051537baa..9011ddac769bd 100644 --- a/lib/internal/Magento/Framework/Interception/Config/Config.php +++ b/lib/internal/Magento/Framework/Interception/Config/Config.php @@ -78,6 +78,16 @@ class Config implements \Magento\Framework\Interception\ConfigInterface */ private $serializer; + /** + * @var \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem + */ + private $configWriter; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled + */ + private $compiledLoader; + /** * Config constructor * @@ -89,6 +99,8 @@ class Config implements \Magento\Framework\Interception\ConfigInterface * @param \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions * @param string $cacheId * @param SerializerInterface|null $serializer + * @param \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter + * @param \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader */ public function __construct( \Magento\Framework\Config\ReaderInterface $reader, @@ -98,7 +110,9 @@ public function __construct( \Magento\Framework\Interception\ObjectManager\ConfigInterface $omConfig, \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions, $cacheId = 'interception', - SerializerInterface $serializer = null + SerializerInterface $serializer = null, + \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter = null, + \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader = null ) { $this->_omConfig = $omConfig; $this->_relations = $relations; @@ -109,11 +123,15 @@ public function __construct( $this->_scopeList = $scopeList; $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(Serialize::class); - $intercepted = $this->_cache->load($this->_cacheId); + $this->configWriter = $configWriter ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem::class); + $this->compiledLoader = $compiledLoader ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class); + $intercepted = $this->loadIntercepted(); if ($intercepted !== false) { - $this->_intercepted = $this->serializer->unserialize($intercepted); + $this->_intercepted = $intercepted; } else { - $this->initialize($this->_classDefinitions->getClasses()); + $this->initializeUncompiled($this->_classDefinitions->getClasses()); } } @@ -125,24 +143,9 @@ public function __construct( */ public function initialize($classDefinitions = []) { - $this->_cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$this->_cacheId]); - $config = []; - foreach ($this->_scopeList->getAllScopes() as $scope) { - $config = array_replace_recursive($config, $this->_reader->read($scope)); - } - unset($config['preferences']); - foreach ($config as $typeName => $typeConfig) { - if (!empty($typeConfig['plugins'])) { - $this->_intercepted[ltrim($typeName, '\\')] = true; - } - } - foreach ($config as $typeName => $typeConfig) { - $this->hasPlugins($typeName); - } - foreach ($classDefinitions as $class) { - $this->hasPlugins($class); - } - $this->_cache->save($this->serializer->serialize($this->_intercepted), $this->_cacheId); + $this->generateIntercepted($classDefinitions); + + $this->configWriter->write($this->_cacheId, $this->_intercepted); } /** @@ -188,4 +191,68 @@ public function hasPlugins($type) } return $this->_inheritInterception($type); } + + /** + * Write interception config to cache + * + * @param array $classDefinitions + */ + private function initializeUncompiled($classDefinitions = []) + { + $this->_cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$this->_cacheId]); + + $this->generateIntercepted($classDefinitions); + + $this->_cache->save($this->serializer->serialize($this->_intercepted), $this->_cacheId); + } + + /** + * Generate intercepted array to store in compiled metadata or frontend cache + * + * @param $classDefinitions + */ + private function generateIntercepted($classDefinitions) + { + $config = []; + foreach ($this->_scopeList->getAllScopes() as $scope) { + $config = array_replace_recursive($config, $this->_reader->read($scope)); + } + unset($config['preferences']); + foreach ($config as $typeName => $typeConfig) { + if (!empty($typeConfig['plugins'])) { + $this->_intercepted[ltrim($typeName, '\\')] = true; + } + } + foreach ($config as $typeName => $typeConfig) { + $this->hasPlugins($typeName); + } + foreach ($classDefinitions as $class) { + $this->hasPlugins($class); + } + } + + /** + * Load the interception config from cache + * + * @return array|false + */ + private function loadIntercepted() + { + if ($this->isCompiled()) { + return $this->compiledLoader->load($this->_cacheId); + } + + $intercepted = $this->_cache->load($this->_cacheId); + return $intercepted ? $this->serializer->unserialize($intercepted) : false; + } + + /** + * Check for the compiled config with the generated metadata + * + * @return bool + */ + private function isCompiled() + { + return file_exists(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::getFilePath($this->_cacheId)); + } } From 32191691b5e66da54c422b4968590b7c581c0e58 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Thu, 18 Oct 2018 08:59:30 -0400 Subject: [PATCH 0818/1415] Move ObjectManager Config Writer to Framework The ObjectManager Config Writer class currently lives in the Setup module and is needed in the Framework when writing the interception config to the filesystem during compilation. This commit adds the classes to the Framework and replaces any existing usage with the new interface/class. --- .../ConfigWriter/FilesystemTest.php | 59 ++++++++++++++++++ .../ObjectManager/ConfigWriter/Filesystem.php | 61 +++++++++++++++++++ .../ObjectManager/ConfigWriterInterface.php | 24 ++++++++ .../Framework/Interception/Config/Config.php | 8 +-- .../Console/Command/DiCompileCommand.php | 4 +- .../Module/Di/App/Task/Operation/Area.php | 6 +- .../Di/Compiler/Config/Writer/Filesystem.php | 4 ++ .../Di/Compiler/Config/WriterInterface.php | 3 +- .../Test/Unit/Module/Di/App/Task/AreaTest.php | 2 +- 9 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/App/ObjectManager/ConfigWriter/FilesystemTest.php create mode 100644 lib/internal/Magento/Framework/App/ObjectManager/ConfigWriter/Filesystem.php create mode 100644 lib/internal/Magento/Framework/App/ObjectManager/ConfigWriterInterface.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/ObjectManager/ConfigWriter/FilesystemTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/ObjectManager/ConfigWriter/FilesystemTest.php new file mode 100644 index 0000000000000..843be22c57d67 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/App/ObjectManager/ConfigWriter/FilesystemTest.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\App\ObjectManager\ConfigWriter; + +class FilesystemTest extends \PHPUnit\Framework\TestCase +{ + const CACHE_KEY = 'filesystemtest'; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem + */ + private $configWriter; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigLoader + */ + private $configReader; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->configWriter = $objectManager->create( + \Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class + ); + $this->configReader = $objectManager->create( + \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class + ); + } + + public function testWrite() + { + $sampleData = [ + 'classA' => true, + 'classB' => false, + ]; + + $this->configWriter->write(self::CACHE_KEY, $sampleData); + $this->assertEquals($sampleData, $this->configReader->load(self::CACHE_KEY)); + } + + public function testOverwrite() + { + $this->configWriter->write(self::CACHE_KEY, ['hello' => 'world']); + + $sampleData = [ + 'classC' => false, + 'classD' => true, + ]; + + $this->configWriter->write(self::CACHE_KEY, $sampleData); + $this->assertEquals($sampleData, $this->configReader->load(self::CACHE_KEY)); + } +} diff --git a/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriter/Filesystem.php b/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriter/Filesystem.php new file mode 100644 index 0000000000000..2b1cdd2a9c10b --- /dev/null +++ b/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriter/Filesystem.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\App\ObjectManager\ConfigWriter; + +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\ObjectManager\ConfigWriterInterface; + +/** + * @inheritdoc + */ +class Filesystem implements ConfigWriterInterface +{ + /** + * @var DirectoryList + */ + private $directoryList; + + /** + * @param DirectoryList $directoryList + */ + public function __construct( + DirectoryList $directoryList + ) { + $this->directoryList = $directoryList; + } + + /** + * Writes config in storage + * + * @param string $key + * @param array $config + * @return void + */ + public function write(string $key, array $config) + { + $this->initialize(); + $configuration = sprintf('<?php return %s;', var_export($config, true)); + file_put_contents( + $this->directoryList->getPath(DirectoryList::GENERATED_METADATA) . '/' . $key . '.php', + $configuration + ); + } + + /** + * Initializes writer + * + * @return void + */ + private function initialize() + { + if (!file_exists($this->directoryList->getPath(DirectoryList::GENERATED_METADATA))) { + mkdir($this->directoryList->getPath(DirectoryList::GENERATED_METADATA)); + } + } +} diff --git a/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriterInterface.php b/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriterInterface.php new file mode 100644 index 0000000000000..cccbb0ae30b99 --- /dev/null +++ b/lib/internal/Magento/Framework/App/ObjectManager/ConfigWriterInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\App\ObjectManager; + +/** + * Write compiled object manager configuration to storage + */ +interface ConfigWriterInterface +{ + /** + * Writes config in storage + * + * @param string $key + * @param array $config + * @return void + */ + public function write(string $key, array $config); +} diff --git a/lib/internal/Magento/Framework/Interception/Config/Config.php b/lib/internal/Magento/Framework/Interception/Config/Config.php index 9011ddac769bd..9a7845e96006b 100644 --- a/lib/internal/Magento/Framework/Interception/Config/Config.php +++ b/lib/internal/Magento/Framework/Interception/Config/Config.php @@ -79,7 +79,7 @@ class Config implements \Magento\Framework\Interception\ConfigInterface private $serializer; /** - * @var \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem + * @var \Magento\Framework\App\ObjectManager\ConfigWriterInterface */ private $configWriter; @@ -99,7 +99,7 @@ class Config implements \Magento\Framework\Interception\ConfigInterface * @param \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions * @param string $cacheId * @param SerializerInterface|null $serializer - * @param \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter + * @param \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter * @param \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader */ public function __construct( @@ -111,7 +111,7 @@ public function __construct( \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions, $cacheId = 'interception', SerializerInterface $serializer = null, - \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem $configWriter = null, + \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter = null, \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader = null ) { $this->_omConfig = $omConfig; @@ -124,7 +124,7 @@ public function __construct( $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(Serialize::class); $this->configWriter = $configWriter ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem::class); + ->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); $this->compiledLoader = $compiledLoader ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class); $intercepted = $this->loadIntercepted(); diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 68e26ec83c3f7..ee26e71d94f30 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -307,8 +307,8 @@ private function configureObjectManager(OutputInterface $output) { $this->objectManager->configure( [ - 'preferences' => [\Magento\Setup\Module\Di\Compiler\Config\WriterInterface::class => - \Magento\Setup\Module\Di\Compiler\Config\Writer\Filesystem::class, + 'preferences' => [\Magento\Framework\App\ObjectManager\ConfigWriterInterface::class => + \Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class, ], \Magento\Setup\Module\Di\Compiler\Config\ModificationChain::class => [ 'arguments' => [ 'modificationsList' => [ diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php index ec5fb3f94e4b4..7acc84e356c4d 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php @@ -28,7 +28,7 @@ class Area implements OperationInterface private $configReader; /** - * @var Config\WriterInterface + * @var \Magento\Framework\App\ObjectManager\ConfigWriterInterface */ private $configWriter; @@ -46,7 +46,7 @@ class Area implements OperationInterface * @param App\AreaList $areaList * @param \Magento\Setup\Module\Di\Code\Reader\Decorator\Area $areaInstancesNamesList * @param Config\Reader $configReader - * @param Config\WriterInterface $configWriter + * @param \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter * @param \Magento\Setup\Module\Di\Compiler\Config\ModificationChain $modificationChain * @param array $data */ @@ -54,7 +54,7 @@ public function __construct( App\AreaList $areaList, \Magento\Setup\Module\Di\Code\Reader\Decorator\Area $areaInstancesNamesList, Config\Reader $configReader, - Config\WriterInterface $configWriter, + \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter, Config\ModificationChain $modificationChain, $data = [] ) { diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php index b4601a970de87..ee9321c5d4199 100644 --- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php +++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php @@ -10,6 +10,10 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Setup\Module\Di\Compiler\Config\WriterInterface; +/** + * @deprecated Moved to Framework to allow broader reuse + * @see \Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem + */ class Filesystem implements WriterInterface { /** diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/WriterInterface.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/WriterInterface.php index 9e6a3008283dc..1ff5524529cc4 100644 --- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/WriterInterface.php +++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/WriterInterface.php @@ -9,7 +9,8 @@ /** * Interface \Magento\Setup\Module\Di\Compiler\Config\WriterInterface - * + * @deprecated Moved to Framework to allow broader reuse + * @see \Magento\Framework\App\ObjectManager\ConfigWriterInterface */ interface WriterInterface { diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php index 39e67401760b7..03b423bb32b0f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php @@ -48,7 +48,7 @@ protected function setUp() $this->configReaderMock = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\Reader::class) ->disableOriginalConstructor() ->getMock(); - $this->configWriterMock = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\WriterInterface::class) + $this->configWriterMock = $this->getMockBuilder(\Magento\Framework\App\ObjectManager\ConfigWriterInterface::class) ->disableOriginalConstructor() ->getMock(); $this->configChain = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\ModificationChain::class) From a901ad3fd5390c455409d1b8e09af8190debd26c Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 19 Oct 2018 16:52:03 -0400 Subject: [PATCH 0819/1415] Add Interception Config Integration Test Test load logic added for persisting compiled cache data in `generated/metadata` --- .../Interception/Config/ConfigTest.php | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php new file mode 100644 index 0000000000000..5221b8bb422cf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\Interception\Config; + +use Magento\Framework\App\Filesystem\DirectoryList; + +class ConfigTest extends \PHPUnit\Framework\TestCase +{ + const CACHE_ID = 'interceptiontest'; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + + /** + * @var \Magento\Framework\Cache\FrontendInterface + */ + private $cache; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigWriterInterface + */ + private $configWriter; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + $this->serializer = $this->objectManager->get(\Magento\Framework\Serialize\Serializer\Serialize::class); + $this->cache = $this->objectManager->get(\Magento\Framework\App\CacheInterface::class); + $this->configWriter = $this->objectManager->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); + + $this->initializeMetadataDirectory(); + } + + /** + * Delete compiled file if it was created and clear cache data + */ + protected function tearDown() + { + $compiledPath = \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::getFilePath(self::CACHE_ID); + if (file_exists($compiledPath)) { + unlink($compiledPath); + } + + $this->cache->remove(self::CACHE_ID); + } + + /** + * Test load interception cache from generated/metadata + * @dataProvider interceptionCompiledConfigDataProvider + * @param array $testConfig + */ + public function testInstantiateFromCompiled(array $testConfig) + { + $this->configWriter->write(self::CACHE_ID, $testConfig); + $config = $this->getConfig(); + + foreach ($testConfig as $className => $hasPlugins) { + $this->assertEquals($hasPlugins, $config->hasPlugins($className)); + } + } + + /** + * Test load interception cache from backend cache + * @dataProvider interceptionCacheConfigDataProvider + * @param array $testConfig + */ + public function testInstantiateFromCache(array $testConfig) + { + $this->cache->save($this->serializer->serialize($testConfig), self::CACHE_ID); + $config = $this->getConfig(); + + foreach ($testConfig as $className => $hasPlugins) { + $this->assertEquals($hasPlugins, $config->hasPlugins($className)); + } + } + + public function interceptionCompiledConfigDataProvider() + { + return [ + [['classA' => true, 'classB' => false]], + [['classA' => false, 'classB' => true]], + ]; + } + + public function interceptionCacheConfigDataProvider() + { + return [ + [['classC' => true, 'classD' => false]], + [['classC' => false, 'classD' => true]], + ]; + } + + /** + * Ensure generated/metadata exists + */ + private function initializeMetadataDirectory() + { + $diPath = DirectoryList::getDefaultConfig()[DirectoryList::GENERATED_METADATA][DirectoryList::PATH]; + $fullPath = BP . DIRECTORY_SEPARATOR . $diPath; + if (!file_exists($fullPath)) { + mkdir($fullPath); + } + } + + /** + * Create instance of Config class with specific cacheId. This is done to prevent our test + * from altering the interception config that may have been generated during application + * installation. Inject a new instance of the compileLoaded to bypass it's caching. + * + * @return \Magento\Framework\Interception\Config\Config + */ + private function getConfig() + { + return $this->objectManager->create( + \Magento\Framework\Interception\Config\Config::class, + [ + 'cacheId' => self::CACHE_ID, + 'compiledLoader' => $this->objectManager->create(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class), + ] + ); + } +} From 7dae4c185b01b621cd51841ecb67521d8b745298 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Wed, 24 Oct 2018 16:39:34 -0400 Subject: [PATCH 0820/1415] Update serializer used in integration test Replace serialize with it's interface. Also passes the serializer when instantiating the test subject. This ensures the correct implementation is used becuase the interface preference and fallback in the constructor do not match. --- .../Magento/Framework/Interception/Config/ConfigTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php index 5221b8bb422cf..1ece9189169bb 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php @@ -38,7 +38,7 @@ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->serializer = $this->objectManager->get(\Magento\Framework\Serialize\Serializer\Serialize::class); + $this->serializer = $this->objectManager->get(\Magento\Framework\Serialize\SerializerInterface::class); $this->cache = $this->objectManager->get(\Magento\Framework\App\CacheInterface::class); $this->configWriter = $this->objectManager->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); @@ -130,6 +130,7 @@ private function getConfig() [ 'cacheId' => self::CACHE_ID, 'compiledLoader' => $this->objectManager->create(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class), + 'serializer' => $this->serializer, ] ); } From 4eac0fce975759e961793d88c77d35f61bd9d94e Mon Sep 17 00:00:00 2001 From: Ronak Patel <ronak2ram@gmail.com> Date: Fri, 26 Oct 2018 13:06:44 +0530 Subject: [PATCH 0821/1415] Added warning log --- .../Magento/CmsGraphQl/Model/Resolver/Blocks.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php index d7c0008c7d927..fabb479763e60 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php @@ -14,6 +14,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Psr\Log\LoggerInterface; /** * CMS blocks field resolver, used for GraphQL request processing @@ -25,13 +26,20 @@ class Blocks implements ResolverInterface */ private $blockDataProvider; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param BlockDataProvider $blockDataProvider */ public function __construct( - BlockDataProvider $blockDataProvider + BlockDataProvider $blockDataProvider, + LoggerInterface $logger ) { $this->blockDataProvider = $blockDataProvider; + $this->logger = $logger; } /** @@ -81,6 +89,10 @@ private function getBlocksData(array $blockIdentifiers): array $blockData = $this->blockDataProvider->getData($blockIdentifier); if (!empty($blockData)) { $blocksData[$blockIdentifier] = $blockData; + } else { + $this->logger->warning( + sprintf('The CMS block with the "%s" Identifier is disabled.', $blockIdentifier) + ); } } } catch (NoSuchEntityException $e) { From 7f24f769d794792b6a960043c0815ed6c33814bb Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 26 Oct 2018 11:05:12 +0300 Subject: [PATCH 0822/1415] magento-engcom/magento2ce#2280: Code style fixes --- .../ProductCategoryCondition.php | 1 + .../Model/Product/Attribute/Repository.php | 14 +++++++------ .../Catalog/Model/ProductCategoryList.php | 1 - .../Model/Import/Product/Validator.php | 20 +++++++++++++++++-- .../Block/Product/ProductsList.php | 2 ++ .../Model/PaymentInformationManagement.php | 8 +++++--- .../Agreement/Grid/Collection.php | 6 +++++- .../GiftMessage/Model/ItemRepository.php | 4 ++-- .../GiftMessage/Model/OrderItemRepository.php | 4 ++-- .../GiftMessage/Model/OrderRepository.php | 4 ++-- .../Console/Command/IndexerReindexCommand.php | 12 ++++++++--- .../Quote/Model/BillingAddressManagement.php | 7 ++++--- .../Model/Order/Validation/CanInvoice.php | 6 ++++++ .../Adminhtml/User/Role/SaveRole.php | 6 ++++++ lib/internal/Magento/Framework/Mview/View.php | 2 ++ .../Framework/Setup/OldDbValidator.php | 6 +++++- .../Magento/Setup/Model/PhpReadinessCheck.php | 2 ++ 17 files changed, 79 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php index d37f97c38a4f6..66a9132ae44b8 100644 --- a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php @@ -38,6 +38,7 @@ class ProductCategoryCondition implements CustomConditionInterface /** * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param \Magento\Catalog\Model\CategoryRepository $categoryRepository */ public function __construct( \Magento\Framework\App\ResourceConnection $resourceConnection, diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index 48ca12321a250..99edfe5bc7208 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -11,6 +11,8 @@ use Magento\Framework\Exception\NoSuchEntityException; /** + * Product attribute repository + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInterface @@ -78,7 +80,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($attributeCode) { @@ -89,7 +91,7 @@ public function get($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) { @@ -100,7 +102,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -180,7 +182,7 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute) { @@ -189,7 +191,7 @@ public function delete(\Magento\Catalog\Api\Data\ProductAttributeInterface $attr } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($attributeCode) { @@ -200,7 +202,7 @@ public function deleteById($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getCustomAttributesMetadata($dataObjectClassName = null) diff --git a/app/code/Magento/Catalog/Model/ProductCategoryList.php b/app/code/Magento/Catalog/Model/ProductCategoryList.php index c8b075ffb494e..c3a88a505c516 100644 --- a/app/code/Magento/Catalog/Model/ProductCategoryList.php +++ b/app/code/Magento/Catalog/Model/ProductCategoryList.php @@ -84,7 +84,6 @@ public function getCategoryIds($productId) 'intval', $this->productResource->getConnection()->fetchCol($unionSelect) ); - } return $this->categoryIdList[$productId]; diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 21f7f87875e12..4b7416f6ad9a6 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -61,6 +61,8 @@ public function __construct( } /** + * Text validation + * * @param mixed $attrCode * @param string $type * @return bool @@ -108,6 +110,8 @@ private function validateOption($attrCode, $possibleOptions, $value) } /** + * Numeric validation + * * @param mixed $attrCode * @param string $type * @return bool @@ -135,6 +139,8 @@ protected function numericValidation($attrCode, $type) } /** + * Is required attribute valid + * * @param string $attrCode * @param array $attributeParams * @param array $rowData @@ -162,6 +168,8 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra } /** + * Is attribute valid + * * @param string $attrCode * @param array $attrParams * @param array $rowData @@ -258,6 +266,8 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) } /** + * Set invalid attribute + * * @param string|null $attribute * @return void * @since 100.1.0 @@ -268,6 +278,8 @@ protected function setInvalidAttribute($attribute) } /** + * Get invalid attribute + * * @return string * @since 100.1.0 */ @@ -277,6 +289,8 @@ public function getInvalidAttribute() } /** + * Is valid attributes + * * @return bool * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ @@ -303,7 +317,7 @@ protected function isValidAttributes() } /** - * {@inheritdoc} + * @inheritdoc */ public function isValid($value) { @@ -334,6 +348,8 @@ public function getRowScope(array $rowData) } /** + * Init + * * @param \Magento\CatalogImportExport\Model\Import\Product $context * @return $this */ @@ -344,4 +360,4 @@ public function init($context) $validator->init($context); } } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index a0cfc08406189..55f4d67273379 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -410,6 +410,8 @@ private function getPriceCurrency() } /** + * Get widget block name + * * @return string */ private function getWidgetPagerBlockName() diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 947f7b896f67a..d2bd680aa38f3 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -9,6 +9,8 @@ use Magento\Framework\Exception\CouldNotSaveException; /** + * Payment information management + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInformationManagementInterface @@ -72,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function savePaymentInformationAndPlaceOrder( $cartId, @@ -98,7 +100,7 @@ public function savePaymentInformationAndPlaceOrder( } /** - * {@inheritDoc} + * @inheritdoc */ public function savePaymentInformation( $cartId, @@ -124,7 +126,7 @@ public function savePaymentInformation( } /** - * {@inheritDoc} + * @inheritdoc */ public function getPaymentInformation($cartId) { diff --git a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php index 78ad7b32330ad..bc055ca9f663b 100644 --- a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php +++ b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php @@ -14,7 +14,7 @@ class Collection extends \Magento\CheckoutAgreements\Model\ResourceModel\Agreeme { /** - * {@inheritdoc} + * @inheritdoc */ public function load($printQuery = false, $logQuery = false) { @@ -30,6 +30,8 @@ public function load($printQuery = false, $logQuery = false) } /** + * Add stores to result + * * @return void */ private function addStoresToResult() @@ -56,6 +58,8 @@ private function addStoresToResult() } /** + * Get stores for agreements + * * @return array */ private function getStoresForAgreements() diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php index dce60079e43e3..aa65bf94f361a 100644 --- a/app/code/Magento/GiftMessage/Model/ItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php @@ -74,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($cartId, $itemId) { @@ -103,7 +103,7 @@ public function get($cartId, $itemId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($cartId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage, $itemId) { diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php index 6cfcd485f7645..445ba54ac4d9c 100644 --- a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php @@ -80,7 +80,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($orderId, $orderItemId) { @@ -111,7 +111,7 @@ public function get($orderId, $orderItemId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage) { diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php index 88d1adf92ed0b..e943fa2a3b084 100644 --- a/app/code/Magento/GiftMessage/Model/OrderRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php @@ -74,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($orderId) { @@ -98,7 +98,7 @@ public function get($orderId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage) { diff --git a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php index 6d0716a6f1c27..fffa4503e14a7 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php @@ -58,7 +58,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { @@ -70,7 +70,7 @@ protected function configure() } /** - * {@inheritdoc} + * @inheritdoc */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -105,7 +105,9 @@ protected function execute(InputInterface $input, OutputInterface $output) } /** - * {@inheritdoc} Returns the ordered list of specified indexers and related indexers. + * @inheritdoc + * + * Returns the ordered list of specified indexers and related indexers. */ protected function getIndexers(InputInterface $input) { @@ -272,6 +274,8 @@ private function getConfig() } /** + * Get indexer registry + * * @return IndexerRegistry * @deprecated 100.2.0 */ @@ -284,6 +288,8 @@ private function getIndexerRegistry() } /** + * Get dependency info provider + * * @return DependencyInfoProvider * @deprecated 100.2.0 */ diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index e8af185b8c2f0..bc055e71c662e 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -14,7 +14,6 @@ /** * Quote billing address write service object. - * */ class BillingAddressManagement implements BillingAddressManagementInterface { @@ -70,7 +69,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc * @SuppressWarnings(PHPMD.NPathComplexity) */ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) @@ -92,7 +91,7 @@ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $addres } /** - * {@inheritDoc} + * @inheritdoc */ public function get($cartId) { @@ -101,6 +100,8 @@ public function get($cartId) } /** + * Get shipping address assignment + * * @return \Magento\Quote\Model\ShippingAddressAssignment * @deprecated 100.2.0 */ diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index 8ce448d06b8f2..7b346a232ab95 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -15,6 +15,8 @@ class CanInvoice implements ValidatorInterface { /** + * Validate + * * @param OrderInterface $entity * @return array */ @@ -32,6 +34,8 @@ public function validate($entity) } /** + * Is state ready for invoice + * * @param OrderInterface $order * @return bool */ @@ -50,6 +54,8 @@ private function isStateReadyForInvoice(OrderInterface $order) } /** + * Can invoice + * * @param OrderInterface $order * @return bool */ diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index 4a9b98f214ee4..acd3430f5c25a 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -15,6 +15,8 @@ use Magento\Security\Model\SecurityCookie; /** + * Save role controller + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role implements HttpPostActionInterface @@ -150,6 +152,8 @@ protected function validateUser() } /** + * Process previous users + * * @param \Magento\Authorization\Model\Role $role * @return $this * @throws \Exception @@ -206,6 +210,8 @@ protected function _deleteUserFromRole($userId, $roleId) } /** + * Save data to session and redirect + * * @param \Magento\Authorization\Model\Role $role * @param array $data * @param \Magento\Backend\Model\View\Result\Redirect $resultRedirect diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index 589034886010f..1b32238813f86 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -10,6 +10,8 @@ use Magento\Framework\Mview\View\SubscriptionFactory; /** + * Mview + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class View extends \Magento\Framework\DataObject implements ViewInterface diff --git a/lib/internal/Magento/Framework/Setup/OldDbValidator.php b/lib/internal/Magento/Framework/Setup/OldDbValidator.php index 34f916674ca56..4c224a6c713ef 100644 --- a/lib/internal/Magento/Framework/Setup/OldDbValidator.php +++ b/lib/internal/Magento/Framework/Setup/OldDbValidator.php @@ -11,7 +11,9 @@ use Magento\Framework\Module\DbVersionInfo; /** - * Old Validator for database is used in order to support backward compatability of modules that are installed + * Old Validator for database + * + * Used in order to support backward compatability of modules that are installed * in old way (with Install/Upgrade Schema/Data scripts) */ class OldDbValidator implements UpToDateValidatorInterface @@ -63,6 +65,8 @@ public function getNotUpToDateMessage(): string } /** + * Is up to date + * * @return bool */ public function isUpToDate(): bool diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index 98da6cb7a5e0f..86a377c8edc62 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -179,6 +179,7 @@ public function checkPhpExtensions() /** * Checks php memory limit + * * @return array */ public function checkMemoryLimit() @@ -235,6 +236,7 @@ public function checkMemoryLimit() /** * Checks if xdebug.max_nesting_level is set 200 or more + * * @return array */ private function checkXDebugNestedLevel() From 81527754cc8dcd78cd798e522cc6d611d4a19dd5 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 26 Oct 2018 11:54:14 +0300 Subject: [PATCH 0823/1415] ENGCOM-3259: [Forwardport] 17516: added Australian states #18774. Fix static and database compare tests. --- .../Directory/Setup/Patch/Data/AddDataForAustralia.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index 0abadf7153424..e71abf3a58571 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -39,7 +39,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function apply() { @@ -71,17 +71,19 @@ private function getDataForAustralia() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { return [ InitializeDirectoryData::class, + AddDataForCroatia::class, + AddDataForIndia::class, ]; } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -89,7 +91,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { From 755ef37b3a1e35b59f38652e69f1c26ea1ff56b4 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Fri, 26 Oct 2018 12:59:49 +0300 Subject: [PATCH 0824/1415] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - .../Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index c44610ef19649..80cadbb6571f2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -13,7 +13,6 @@ <argument name="ProductAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml index c21f23d16463e..5be2a84f54555 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml @@ -65,7 +65,7 @@ <data key="is_default">false</data> <data key="sort_order">0</data> </entity> - <entity name="productAttributeOption7" type="ProductAttributeOption"> + <entity name="ProductAttributeOption7" type="ProductAttributeOption"> <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> <data key="label" unique="suffix">Green</data> <data key="is_default">false</data> @@ -73,7 +73,7 @@ <requiredEntity type="StoreLabel">Option7Store0</requiredEntity> <requiredEntity type="StoreLabel">Option8Store1</requiredEntity> </entity> - <entity name="productAttributeOption8" type="ProductAttributeOption"> + <entity name="ProductAttributeOption8" type="ProductAttributeOption"> <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> <data key="label" unique="suffix">Red</data> <data key="is_default">false</data> From 4bed4727be909f0c57b6e7df402a84e545d913e9 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 26 Oct 2018 13:12:14 +0300 Subject: [PATCH 0825/1415] ENGCOM-3259: [Forwardport] 17516: added Australian states #18774. Fix static tests. --- .../Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index e71abf3a58571..20306d08a292c 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Directory\Setup\Patch\Data; use Magento\Directory\Setup\DataInstaller; From 63cc7536ae1d0a070c047b3b06ad3eb1889b61a7 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Fri, 26 Oct 2018 13:22:57 +0300 Subject: [PATCH 0826/1415] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- app/code/Magento/Catalog/Helper/Data.php | 23 ++-- .../Backend/TierPrice/UpdateHandler.php | 17 ++- .../Controller/Adminhtml/ProductTest.php | 103 ++++++++++++++++++ 3 files changed, 125 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Data.php b/app/code/Magento/Catalog/Helper/Data.php index ae20cda460796..c83eb70486c43 100644 --- a/app/code/Magento/Catalog/Helper/Data.php +++ b/app/code/Magento/Catalog/Helper/Data.php @@ -7,6 +7,7 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Pricing\PriceCurrencyInterface; @@ -273,7 +274,8 @@ public function setStoreId($store) /** * Return current category path or get it from current category - * and creating array of categories|product paths for breadcrumbs + * + * Creating array of categories|product paths for breadcrumbs * * @return array */ @@ -382,6 +384,7 @@ public function getLastViewedUrl() /** * Split SKU of an item by dashes and spaces + * * Words will not be broken, unless this length is greater than $length * * @param string $sku @@ -410,14 +413,15 @@ public function getAttributeHiddenFields() /** * Retrieve Catalog Price Scope * - * @return int + * @return int/null */ - public function getPriceScope() + public function getPriceScope(): ?int { - return $this->scopeConfig->getValue( + $priceScope = $this->scopeConfig->getValue( self::XML_PATH_PRICE_SCOPE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); + return isset($priceScope) ? (int)$priceScope : null; } /** @@ -439,7 +443,7 @@ public function isUsingStaticUrlsAllowed() { return $this->scopeConfig->isSetFlag( self::CONFIG_USE_STATIC_URLS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } @@ -454,7 +458,7 @@ public function isUrlDirectivesParsingAllowed() { return $this->scopeConfig->isSetFlag( self::CONFIG_PARSE_URL_DIRECTIVES, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $this->_storeId ); } @@ -472,6 +476,7 @@ public function getPageTemplateProcessor() /** * Whether to display items count for each filter option + * * @param int $storeId Store view ID * @return bool */ @@ -479,12 +484,14 @@ public function shouldDisplayProductCountOnLayer($storeId = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_DISPLAY_PRODUCT_COUNT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $storeId ); } /** + * Convert tax address array to address data object with country id and postcode + * * @param array $taxAddress * @return \Magento\Customer\Api\Data\AddressInterface|null */ diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php index b4d6dc2c19e51..aef3e87586015 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php @@ -86,10 +86,10 @@ public function execute($entity, $arguments = []) __('Tier prices data should be array, but actually other type is received') ); } - $websiteId = $this->storeManager->getStore($entity->getStoreId())->getWebsiteId(); + $websiteId = (int)$this->storeManager->getStore($entity->getStoreId())->getWebsiteId(); $isGlobal = $attribute->isScopeGlobal() || $websiteId === 0; $identifierField = $this->metadataPoll->getMetadata(ProductInterface::class)->getLinkField(); - $productId = (int) $entity->getData($identifierField); + $productId = (int)$entity->getData($identifierField); // prepare original data to compare $origPrices = []; @@ -98,7 +98,7 @@ public function execute($entity, $arguments = []) $origPrices = $entity->getOrigData($attribute->getName()); } - $old = $this->prepareOriginalDataToCompare($origPrices, $isGlobal); + $old = $this->prepareOldTierPriceToCompare($origPrices); // prepare data for save $new = $this->prepareNewDataForSave($priceRows, $isGlobal); @@ -271,21 +271,18 @@ private function isWebsiteGlobal(int $websiteId): bool } /** - * Prepare original data to compare. + * Prepare old data to compare. * * @param array|null $origPrices - * @param bool $isGlobal * @return array */ - private function prepareOriginalDataToCompare(?array $origPrices, bool $isGlobal = true): array + private function prepareOldTierPriceToCompare(?array $origPrices): array { $old = []; if (is_array($origPrices)) { foreach ($origPrices as $data) { - if ($isGlobal === $this->isWebsiteGlobal((int)$data['website_id'])) { - $key = $this->getPriceKey($data); - $old[$key] = $data; - } + $key = $this->getPriceKey($data); + $old[$key] = $data; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index 06bbc43e36e8d..d949993e7ea3c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -252,4 +252,107 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider() ] ]; } + + /** + * Test product save with selected tier price + * + * @dataProvider saveActionTierPriceDataProvider + * @param array $postData + * @param array $tierPrice + * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php + * @magentoAppIsolation enabled + * @magentoConfigFixture current_store catalog/price/scope 1 + * @magentoDbIsolation disabled + */ + public function testSaveActionTierPrice(array $postData, array $tierPrice) + { + $postData['product'] = $this->getProductData($tierPrice); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue($postData); + $this->dispatch('backend/catalog/product/save/id/' . $postData['id']); + $this->assertSessionMessages( + $this->contains('You saved the product.'), + \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + ); + } + + /** + * Provide test data for testSaveActionWithAlreadyExistingUrlKey(). + * + * @return array + */ + public function saveActionTierPriceDataProvider() + { + return [ + [ + 'post_data' => [ + 'id' => '1', + 'type' => 'simple', + 'store' => '0', + 'set' => '4', + 'back' => 'edit', + 'product' => [], + 'is_downloadable' => '0', + 'affect_configurable_product_attributes' => '1', + 'new_variation_attribute_set_id' => '4', + 'use_default' => [ + 'gift_message_available' => '0', + 'gift_wrapping_available' => '0' + ], + 'configurable_matrix_serialized' => '[]', + 'associated_product_ids_serialized' => '[]' + ], + 'tier_price_for_request' => [ + [ + 'price_id' => '1', + 'website_id' => '0', + 'cust_group' => '32000', + 'price' => '111.00', + 'price_qty' => '100', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '1', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '2', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '222.00', + 'price_qty' => '200', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '2', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '3', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '333.00', + 'price_qty' => '300', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '3', + 'value_type' => 'fixed' + ] + ] + ] + ]; + } + + /** + * Return product data for test without entity_id for further save + * + * @param array $tierPrice + * @return array + */ + private function getProductData(array $tierPrice) + { + $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); + $product = $repository->get('tier_prices')->getData(); + $product['tier_price'] = $tierPrice; + unset($product['entity_id']); + return $product; + } } From c8eb11567542d5e8002180801153fa19f6724336 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 12:42:07 +0200 Subject: [PATCH 0827/1415] GraphQL-43: introduce wishlist graphql module --- .../WishlistItemsProductsResolver.php | 58 ++++++++++++++++++ .../Model/Resolver/WishlistItemsResolver.php | 60 +++++++++++++++++++ .../Model/Resolver/WishlistResolver.php | 55 +++++++++++++++++ .../Model/WishlistDataProvider.php | 39 ++++++++++++ .../Model/WishlistItemsDataProvider.php | 52 ++++++++++++++++ .../WishlistItemsProductDataProvider.php | 32 ++++++++++ app/code/Magento/WishlistGraphQl/README.md | 4 ++ .../Magento/WishlistGraphQl/composer.json | 25 ++++++++ .../Magento/WishlistGraphQl/etc/module.xml | 10 ++++ .../WishlistGraphQl/etc/schema.graphqls | 20 +++++++ .../Magento/WishlistGraphQl/registration.php | 9 +++ composer.json | 1 + 12 files changed, 365 insertions(+) create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/README.md create mode 100644 app/code/Magento/WishlistGraphQl/composer.json create mode 100644 app/code/Magento/WishlistGraphQl/etc/module.xml create mode 100644 app/code/Magento/WishlistGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/WishlistGraphQl/registration.php diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php new file mode 100644 index 0000000000000..567e85c3c0309 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php @@ -0,0 +1,58 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemsProductsResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\WishlistGraphQl\Model\WishlistItemsProductDataProvider; + +class WishlistItemsProductsResolver implements ResolverInterface +{ + /** + * @var WishlistItemsProductDataProvider + */ + private $productDataProvider; + + public function __construct(WishlistItemsProductDataProvider $productDataProvider) + { + $this->productDataProvider = $productDataProvider; + } + + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['product_id'])) { + throw new GraphQlInputException( + __('Missing key %1 in wishlist item data', ['product_id']) + ); + } + return $this->productDataProvider->getProductDataById($value['product_id']); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php new file mode 100644 index 0000000000000..3f51db6eef3e1 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -0,0 +1,60 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\Item; +use Magento\WishlistGraphQl\Model\WishlistItemsDataProvider; + +class WishlistItemsResolver implements ResolverInterface +{ + /** + * @var WishlistItemsDataProvider + */ + private $wishlistItemsDataProvider; + + public function __construct(WishlistItemsDataProvider $wishlistItemsDataProvider) + { + $this->wishlistItemsDataProvider = $wishlistItemsDataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + return array_map(function (Item $wishlistItem) { + return [ + 'id' => $wishlistItem->getId(), + 'qty' => $wishlistItem->getData('qty'), + 'description' => (string)$wishlistItem->getDescription(), + 'added_at' => $wishlistItem->getAddedAt(), + 'product_id' => (int)$wishlistItem->getProductId() + ]; + }, $this->wishlistItemsDataProvider->getWishlistItemsForCustomer($context->getUserId())); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php new file mode 100644 index 0000000000000..3aec792b9de54 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -0,0 +1,55 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\WishlistGraphQl\Model\WishlistDataProvider; + +class WishlistResolver implements ResolverInterface +{ + /** + * @var WishlistDataProvider + */ + private $wishlistDataProvider; + + public function __construct(WishlistDataProvider $wishlistDataProvider) + { + $this->wishlistDataProvider = $wishlistDataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $wishlist = $this->wishlistDataProvider->getWishlistForCustomer($context->getUserId()); + return [ + 'sharing_code' => $wishlist->getSharingCode(), + 'updated_at' => $wishlist->getUpdatedAt() + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php new file mode 100644 index 0000000000000..8f472d610ff4c --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Wishlist\Model\ResourceModel\Wishlist; +use Magento\Wishlist\Model\WishlistFactory; + +class WishlistDataProvider +{ + /** + * @var Wishlist + */ + private $wishlistResource; + /** + * @var WishlistFactory + */ + private $wishlistFactory; + + public function __construct(Wishlist $wishlistResource, WishlistFactory $wishlistFactory) + { + $this->wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; + } + + public function getWishlistForCustomer(int $customerId): \Magento\Wishlist\Model\Wishlist + { + /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + return $wishlist; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php new file mode 100644 index 0000000000000..e339b4886a942 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php @@ -0,0 +1,52 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Wishlist\Model\Item; +use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; + +class WishlistItemsDataProvider +{ + + /** + * @var WishlistItemCollectionFactory + */ + private $wishlistItemCollectionFactory; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + public function __construct( + WishlistItemCollectionFactory $wishlistItemCollectionFactory, + StoreManagerInterface $storeManager + ) { + $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->storeManager = $storeManager; + } + + /** + * @param int $customerId + * @return Item[] + */ + public function getWishlistItemsForCustomer(int $customerId): array + { + $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); + $wishlistItemCollection->addCustomerIdFilter($customerId); + $wishlistItemCollection->addStoreFilter(array_map(function (StoreInterface $store) { + return $store->getId(); + }, $this->storeManager->getStores())); + $wishlistItemCollection->setVisibilityFilter(); + $wishlistItemCollection->load(); + return $wishlistItemCollection->getItems(); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php new file mode 100644 index 0000000000000..a9aa5dc184397 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php @@ -0,0 +1,32 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemsProductsResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Catalog\Api\ProductRepositoryInterface; + +class WishlistItemsProductDataProvider +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + public function __construct(ProductRepositoryInterface $productRepository) + { + $this->productRepository = $productRepository; + } + + public function getProductDataById(int $productId) { + $product = $this->productRepository->getById($productId); + $productData = $product->toArray(); + $productData['model'] = $product; + return $productData; + } +} diff --git a/app/code/Magento/WishlistGraphQl/README.md b/app/code/Magento/WishlistGraphQl/README.md new file mode 100644 index 0000000000000..9121593e6a759 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/README.md @@ -0,0 +1,4 @@ +# WishlistGraphQl + +**WishlistGraphQl** provides type information for the GraphQl module +to generate wishlist fields. diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json new file mode 100644 index 0000000000000..2be27d4239f73 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -0,0 +1,25 @@ +{ + "name": "magento/module-wishlist-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-catalog": "*" + }, + "suggest": { + "magento/module-wishlist": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\WishlistGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/WishlistGraphQl/etc/module.xml b/app/code/Magento/WishlistGraphQl/etc/module.xml new file mode 100644 index 0000000000000..337623cc85a92 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/etc/module.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_WishlistGraphQl" /> +</config> diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..5c6d701138560 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -0,0 +1,20 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "todo") +} + +type WishlistOutput { + items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), + sharing_code: String! @doc(description: "todo"), + updated_at: String! @doc(description: "todo") +} + +type WishlistItem { + id: Int! @doc(description: "todo") + qty: Float! @doc(description: "todo"), + description: String! @doc(description: "todo"), + added_at: String! @doc(description: "todo"), + product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsProductsResolver") +} \ No newline at end of file diff --git a/app/code/Magento/WishlistGraphQl/registration.php b/app/code/Magento/WishlistGraphQl/registration.php new file mode 100644 index 0000000000000..f2047f225e5b6 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_WishlistGraphQl', __DIR__); diff --git a/composer.json b/composer.json index 3f8f0a033c893..eede85d273777 100644 --- a/composer.json +++ b/composer.json @@ -237,6 +237,7 @@ "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": "*", From 0286f170c6e4c74d2e68a11c3de5f588710143fe Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 13:35:10 +0200 Subject: [PATCH 0828/1415] GraphQL-43: add missing hard dependencies --- app/code/Magento/WishlistGraphQl/composer.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index 2be27d4239f73..9226ea1754e6a 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -5,10 +5,9 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-catalog": "*" - }, - "suggest": { - "magento/module-wishlist": "*" + "magento/module-catalog": "*", + "magento/module-wishlist": "*", + "magento/module-store": "*" }, "license": [ "OSL-3.0", From 98715ca4060c262d90f48e31c1f1d202bd2d23b5 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Fri, 26 Oct 2018 13:16:58 +0200 Subject: [PATCH 0829/1415] magento-engcom/import-export-improvements#93: show errors and link to download csv error report on success page --- .../Controller/Adminhtml/Import/Start.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 8f64d023c19f9..06b69c512a194 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -93,6 +93,20 @@ public function execute() $this->addErrorMessages($resultBlock, $errorAggregator); } else { $this->importModel->invalidateIndex(); + + $noticeHtml = $this->historyModel->getSummary(); + + if($this->historyModel->getErrorFile()) { + $noticeHtml .= '<div class="import-error-wrapper">' . __('Only the first 100 errors are shown. ') + . '<a href="' + . $this->createDownloadUrlImportHistoryFile($this->historyModel->getErrorFile()) + . '">' . __('Download full report') . '</a></div>'; + } + + $resultBlock->addNotice( + $noticeHtml + ); + $this->addErrorMessages($resultBlock, $errorAggregator); $resultBlock->addSuccess(__('Import successfully done')); } From 2e4ea72289c28a223354b18b399e28843267e538 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 14:14:25 +0200 Subject: [PATCH 0830/1415] GraphQL-43: add test to retrieve wishlist --- .../Magento/GraphQl/Wishlist/WishlistTest.php | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php new file mode 100644 index 0000000000000..53577d02df50f --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Wishlist; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Wishlist\Model\Item; + +class WishlistTest extends GraphQlAbstract +{ + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * Verify the fields of CMS Block selected by identifiers + * + * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php + * @throws \Magento\Framework\Exception\AuthenticationException + * @throws \Exception + */ + public function testGetCustomersWishlist(): void + { + /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ + $wishlist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Wishlist\Model\Wishlist::class + ); + $wishlist->loadByCustomerId(1, true); + /** @var Item $wishlistItem */ + $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); + $wishlistItemProduct = $wishlistItem->getProduct(); + $query = + <<<QUERY +{ + wishlist { + items { + id + qty + product { + sku + name + } + description + added_at + } + sharing_code + updated_at + } +} +QUERY; + + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders('customer@example.com', 'password')); + $this->assertEquals($wishlist->getSharingCode(), $response['wishlist']['sharing_code']); + $this->assertEquals($wishlistItem->getData('qty'), $response['wishlist']['items'][0]['qty']); + $this->assertEquals($wishlistItem->getDescription(), $response['wishlist']['items'][0]['description']); + $this->assertEquals($wishlistItemProduct->getSku(), $response['wishlist']['items'][0]['product']['sku']); + $this->assertEquals($wishlistItemProduct->getName(), $response['wishlist']['items'][0]['product']['name']); + } + + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } +} From 89eb2776be3bdacf84a86367d866b8746452f129 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 14:19:15 +0200 Subject: [PATCH 0831/1415] GraphQL-43: use correct copyright headers in introduced php classes --- .../Model/Resolver/WishlistItemsProductsResolver.php | 8 +++----- .../Model/Resolver/WishlistItemsResolver.php | 8 +++----- .../WishlistGraphQl/Model/Resolver/WishlistResolver.php | 8 +++----- .../WishlistGraphQl/Model/WishlistDataProvider.php | 8 +++----- .../WishlistGraphQl/Model/WishlistItemsDataProvider.php | 8 +++----- .../Model/WishlistItemsProductDataProvider.php | 8 +++----- 6 files changed, 18 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php index 567e85c3c0309..26ace0e849e3f 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemsProductsResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 3f51db6eef3e1..707618b10602d 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index 3aec792b9de54..ba1a6e935c10e 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php index 8f472d610ff4c..a62ddebd91120 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php index e339b4886a942..ca87b23460fc7 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php index a9aa5dc184397..76df065a80702 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemsProductsResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; From 7db2cc9fbac6adc17e43be576aa149b7e7965b8a Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Fri, 26 Oct 2018 17:50:12 +0530 Subject: [PATCH 0832/1415] fixed Translation issue send-friend in send.phtml --- app/code/Magento/SendFriend/view/frontend/templates/send.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 862ef5fdebc3c..4922a9f365ced 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -17,7 +17,7 @@ <div class="secondary"> <button type="button" id="btn-remove<%- data._index_ %>" class="action remove" title="<?= $block->escapeHtmlAttr(__('Remove Recipent')) ?>"> - <span><?= $block->escapeJs($block->escapeHtml(__('Remove'))) ?></span> + <span><?= $block->escapeHtml(__('Remove')) ?></span> </button> </div> </div> From e5e58325500ef7d6df7dd7d928f25a33962f9d69 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Fri, 26 Oct 2018 14:42:26 +0200 Subject: [PATCH 0833/1415] magento-engcom/import-export-improvements#54: function getBehavior extended with BEHAVIOUR_ADD_UPDATE and BEHAVIOR_CUSTOM --- .../Magento/ImportExport/Model/Import/Entity/AbstractEntity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index e965e8ad207fd..74e2c5626236c 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -554,7 +554,9 @@ public function getBehavior() $this->_parameters['behavior'] ) || $this->_parameters['behavior'] != ImportExport::BEHAVIOR_APPEND && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_ADD_UPDATE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_REPLACE && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_CUSTOM && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_DELETE ) { return ImportExport::getDefaultBehavior(); From 3f5bcdd911b1d7b9604362f078bcfd9b7baa9d3f Mon Sep 17 00:00:00 2001 From: matt <matt@dforce3000.de> Date: Fri, 26 Oct 2018 15:01:27 +0200 Subject: [PATCH 0834/1415] magento2#222 Apply changes from CR for PR 162 --- .../Model/Customer/UpdateAccountInformation.php | 2 +- .../Model/Resolver/ChangePassword.php | 6 +++--- .../Model/Resolver/GenerateCustomerToken.php | 4 ++-- .../Model/Resolver/RevokeCustomerToken.php | 2 +- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 12 ++++++++---- .../Exception/GraphQlAlreadyExistsException.php | 2 +- .../Exception/GraphQlAuthenticationException.php | 2 +- .../Exception/GraphQlAuthorizationException.php | 2 +- .../Exception/GraphQlNoSuchEntityException.php | 2 +- 9 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php index d235d51b5e52d..36365f1910f27 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php @@ -73,7 +73,7 @@ public function execute(int $customerId, array $data): void if (isset($data['email']) && $customer->getEmail() !== $data['email']) { if (!isset($data['password']) || empty($data['password'])) { - throw new GraphQlInputException(__('For changing "email" you should provide current "password".')); + throw new GraphQlInputException(__('Provide the current "password" to change "email".')); } $this->checkCustomerPassword->execute($data['password'], $customerId); diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php index 98b0975b37169..78fa852a7ac59 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php @@ -17,7 +17,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * @inheritdoc + * Change customer password resolver */ class ChangePassword implements ResolverInterface { @@ -70,11 +70,11 @@ public function resolve( array $args = null ) { if (!isset($args['currentPassword'])) { - throw new GraphQlInputException(__('"currentPassword" value should be specified')); + throw new GraphQlInputException(__('Specify the "currentPassword" value.')); } if (!isset($args['newPassword'])) { - throw new GraphQlInputException(__('"newPassword" value should be specified')); + throw new GraphQlInputException(__('Specify the "newPassword" value.')); } $currentUserId = $context->getUserId(); diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php index 9719d048f606b..1bd77fe1cde8f 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php @@ -45,11 +45,11 @@ public function resolve( array $args = null ) { if (!isset($args['email'])) { - throw new GraphQlInputException(__('"email" value should be specified')); + throw new GraphQlInputException(__('Specify the "email" value.')); } if (!isset($args['password'])) { - throw new GraphQlInputException(__('"password" value should be specified')); + throw new GraphQlInputException(__('Specify the "password" value.')); } try { diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php index d3b16c05a6492..3301162dc0088 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php @@ -55,6 +55,6 @@ public function resolve( $this->checkCustomerAccount->execute($currentUserId, $currentUserType); - return $this->customerTokenService->revokeCustomerAccessToken((int)$currentUserId); + return ['result' => $this->customerTokenService->revokeCustomerAccessToken((int)$currentUserId)]; } } diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index b8411f00c5cb1..ca4ac6cc245a7 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -6,10 +6,10 @@ type Query { } type Mutation { - generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token") - changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer") - updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information") - revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke Customer token") + generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve the customer token") + changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes the password for the logged-in customer") + updateCustomer (input: UpdateCustomerInput!): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update the customer's personal information") + revokeCustomerToken: RevokeCustomerTokenOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke the customer token") } type CustomerToken { @@ -28,6 +28,10 @@ type UpdateCustomerOutput { customer: Customer! } +type RevokeCustomerTokenOutput { + result: Boolean! +} + type Customer @doc(description: "Customer defines the customer name and address and other details") { created_at: String @doc(description: "Timestamp indicating when the account was created") group_id: Int @doc(description: "The group assigned to the user. Default values are 0 (Not logged in), 1 (General), 2 (Wholesale), and 3 (Retailer)") diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php index d25707b2ca347..8275219e9e554 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php @@ -12,7 +12,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlAlreadyExistsException + * Exception for GraphQL to be thrown when data already exists */ class GraphQlAlreadyExistsException extends AlreadyExistsException implements ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php index 4df74bbf332cd..44c3d07bd186f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php @@ -12,7 +12,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlAuthenticationException + * Exception for GraphQL to be thrown when authentication fails */ class GraphQlAuthenticationException extends AuthenticationException implements ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php index 5b76e0ab9f5ae..f71652edc63b3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -11,7 +11,7 @@ use Magento\Framework\Exception\AuthorizationException; /** - * Class GraphQlAuthorizationException + * Exception for GraphQL to be thrown when authorization fails */ class GraphQlAuthorizationException extends AuthorizationException implements \GraphQL\Error\ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php index 05c5925e8d1e5..4bd24d6cfd4a7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -11,7 +11,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlNoSuchEntityException + * Exception for GraphQL to be thrown when entity does not exists */ class GraphQlNoSuchEntityException extends NoSuchEntityException implements \GraphQL\Error\ClientAware { From b3a1cc66df511975ceec0d76447cbfadab35d7f8 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Fri, 26 Oct 2018 16:33:32 +0300 Subject: [PATCH 0835/1415] MAGETWO-70532: [GitHub] REST API Missing Product_Option values for Order Items in salesOrderManagementV1 and salesOrderItemRepositoryV1 #9326 - Extracted setting product options to separate class - Added product options setter for order items collection - Covered changed by API functional test --- app/code/Magento/Bundle/etc/di.xml | 7 + app/code/Magento/Catalog/etc/di.xml | 7 + .../Magento/ConfigurableProduct/etc/di.xml | 7 + app/code/Magento/Downloadable/etc/di.xml | 7 + app/code/Magento/Sales/Model/Order.php | 12 +- .../Sales/Model/Order/ItemRepository.php | 119 +----- .../Sales/Model/Order/ProductOption.php | 103 +++++ .../Unit/Model/Order/ItemRepositoryTest.php | 366 ------------------ .../Magento/Sales/Service/V1/OrderGetTest.php | 145 +++++-- .../Sales/_files/order_with_bundle.php | 5 +- .../Interception/PluginList/PluginList.php | 2 +- 11 files changed, 270 insertions(+), 510 deletions(-) create mode 100644 app/code/Magento/Sales/Model/Order/ProductOption.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index 733b089dccd4b..d0e956efee694 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -140,6 +140,13 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\ProductOption"> + <arguments> + <argument name="processorPool" xsi:type="array"> + <item name="bundle" xsi:type="object">Magento\Bundle\Model\ProductOptionProcessor</item> + </argument> + </arguments> + </type> <type name="Magento\Bundle\Ui\DataProvider\Product\Listing\Collector\BundlePrice"> <arguments> <argument name="excludeAdjustments" xsi:type="array"> diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index a802496d299b8..7d2c3699ee2c2 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -602,6 +602,13 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\ProductOption"> + <arguments> + <argument name="processorPool" xsi:type="array"> + <item name="custom_options" xsi:type="object">Magento\Catalog\Model\ProductOptionProcessor</item> + </argument> + </arguments> + </type> <type name="Magento\Framework\Model\Entity\RepositoryFactory"> <arguments> <argument name="entities" xsi:type="array"> diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index 1dbb0969687d5..102ed1314f864 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -125,6 +125,13 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\ProductOption"> + <arguments> + <argument name="processorPool" xsi:type="array"> + <item name="configurable" xsi:type="object">Magento\ConfigurableProduct\Model\ProductOptionProcessor</item> + </argument> + </arguments> + </type> <virtualType name="ConfigurableFinalPriceResolver" type="Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver"> <arguments> <argument name="priceResolver" xsi:type="object">Magento\ConfigurableProduct\Pricing\Price\FinalPriceResolver</argument> diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 932e48e880880..4e9b0b55afb0b 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -77,6 +77,13 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\ProductOption"> + <arguments> + <argument name="processorPool" xsi:type="array"> + <item name="downloadable" xsi:type="object">Magento\Downloadable\Model\ProductOptionProcessor</item> + </argument> + </arguments> + </type> <preference for="Magento\Downloadable\Api\LinkRepositoryInterface" type="Magento\Downloadable\Model\LinkRepository" /> <preference for="Magento\Downloadable\Api\SampleRepositoryInterface" type="Magento\Downloadable\Model\SampleRepository" /> <preference for="Magento\Downloadable\Api\Data\LinkInterface" type="Magento\Downloadable\Model\Link" /> diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 345ff036a2be6..19fcb0d3743e3 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -13,6 +13,7 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderStatusHistoryInterface; use Magento\Sales\Model\Order\Payment; +use Magento\Sales\Model\Order\ProductOption; use Magento\Sales\Model\ResourceModel\Order\Address\Collection; use Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection as CreditmemoCollection; use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as InvoiceCollection; @@ -279,6 +280,11 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface */ private $localeResolver; + /** + * @var ProductOption + */ + private $productOption; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -308,6 +314,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param ResolverInterface $localeResolver + * @param ProductOption|null $productOption * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -338,7 +345,8 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - ResolverInterface $localeResolver = null + ResolverInterface $localeResolver = null, + ProductOption $productOption = null ) { $this->_storeManager = $storeManager; $this->_orderConfig = $orderConfig; @@ -361,6 +369,7 @@ public function __construct( $this->salesOrderCollectionFactory = $salesOrderCollectionFactory; $this->priceCurrency = $priceCurrency; $this->localeResolver = $localeResolver ?: ObjectManager::getInstance()->get(ResolverInterface::class); + $this->productOption = $productOption ?: ObjectManager::getInstance()->get(ProductOption::class); parent::__construct( $context, @@ -1347,6 +1356,7 @@ public function getItemsCollection($filterByTypes = [], $nonChildrenOnly = false if ($this->getId()) { foreach ($collection as $item) { $item->setOrder($this); + $this->productOption->add($item); } } return $collection; diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 7916eb9db2b80..e9764e7d38c5a 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -6,10 +6,8 @@ namespace Magento\Sales\Model\Order; -use Magento\Catalog\Api\Data\ProductOptionExtensionFactory; -use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; -use Magento\Catalog\Model\ProductOptionFactory; use Magento\Catalog\Model\ProductOptionProcessorInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\DataObject; use Magento\Framework\DataObject\Factory as DataObjectFactory; @@ -18,6 +16,7 @@ use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Api\Data\OrderItemSearchResultInterfaceFactory; use Magento\Sales\Api\OrderItemRepositoryInterface; +use Magento\Sales\Model\Order\ProductOption; use Magento\Sales\Model\ResourceModel\Metadata; /** @@ -41,16 +40,6 @@ class ItemRepository implements OrderItemRepositoryInterface */ protected $searchResultFactory; - /** - * @var ProductOptionFactory - */ - protected $productOptionFactory; - - /** - * @var ProductOptionExtensionFactory - */ - protected $extensionFactory; - /** * @var ProductOptionProcessorInterface[] */ @@ -62,40 +51,41 @@ class ItemRepository implements OrderItemRepositoryInterface protected $registry = []; /** - * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface + * @var CollectionProcessorInterface */ private $collectionProcessor; /** - * ItemRepository constructor. + * @var ProductOption + */ + private $productOption; + + /** * @param DataObjectFactory $objectFactory * @param Metadata $metadata * @param OrderItemSearchResultInterfaceFactory $searchResultFactory - * @param ProductOptionFactory $productOptionFactory - * @param ProductOptionExtensionFactory $extensionFactory + * @param CollectionProcessorInterface $collectionProcessor + * @param ProductOption $productOption * @param array $processorPool - * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( DataObjectFactory $objectFactory, Metadata $metadata, OrderItemSearchResultInterfaceFactory $searchResultFactory, - ProductOptionFactory $productOptionFactory, - ProductOptionExtensionFactory $extensionFactory, - array $processorPool = [], - CollectionProcessorInterface $collectionProcessor = null + CollectionProcessorInterface $collectionProcessor, + ProductOption $productOption, + array $processorPool = [] ) { $this->objectFactory = $objectFactory; $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; - $this->productOptionFactory = $productOptionFactory; - $this->extensionFactory = $extensionFactory; + $this->collectionProcessor = $collectionProcessor; + $this->productOption = $productOption; $this->processorPool = $processorPool; - $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** - * load entity + * Loads entity. * * @param int $id * @return OrderItemInterface @@ -116,7 +106,7 @@ public function get($id) ); } - $this->addProductOption($orderItem); + $this->productOption->add($orderItem); $this->addParentItem($orderItem); $this->registry[$id] = $orderItem; } @@ -137,7 +127,7 @@ public function getList(SearchCriteriaInterface $searchCriteria) $this->collectionProcessor->process($searchCriteria, $searchResult); /** @var OrderItemInterface $orderItem */ foreach ($searchResult->getItems() as $orderItem) { - $this->addProductOption($orderItem); + $this->productOption->add($orderItem); } return $searchResult; @@ -186,37 +176,6 @@ public function save(OrderItemInterface $entity) return $this->registry[$entity->getEntityId()]; } - /** - * Add product option data - * - * @param OrderItemInterface $orderItem - * @return $this - */ - protected function addProductOption(OrderItemInterface $orderItem) - { - /** @var DataObject $request */ - $request = $orderItem->getBuyRequest(); - - $productType = $orderItem->getProductType(); - if (isset($this->processorPool[$productType]) - && !$orderItem->getParentItemId()) { - $data = $this->processorPool[$productType]->convertToProductOption($request); - if ($data) { - $this->setProductOption($orderItem, $data); - } - } - - if (isset($this->processorPool['custom_options']) - && !$orderItem->getParentItemId()) { - $data = $this->processorPool['custom_options']->convertToProductOption($request); - if ($data) { - $this->setProductOption($orderItem, $data); - } - } - - return $this; - } - /** * Set parent item. * @@ -231,32 +190,6 @@ private function addParentItem(OrderItemInterface $orderItem) } } - /** - * Set product options data - * - * @param OrderItemInterface $orderItem - * @param array $data - * @return $this - */ - protected function setProductOption(OrderItemInterface $orderItem, array $data) - { - $productOption = $orderItem->getProductOption(); - if (!$productOption) { - $productOption = $this->productOptionFactory->create(); - $orderItem->setProductOption($productOption); - } - - $extensionAttributes = $productOption->getExtensionAttributes(); - if (!$extensionAttributes) { - $extensionAttributes = $this->extensionFactory->create(); - $productOption->setExtensionAttributes($extensionAttributes); - } - - $extensionAttributes->setData(key($data), current($data)); - - return $this; - } - /** * Retrieve order item's buy request * @@ -288,20 +221,4 @@ protected function getBuyRequest(OrderItemInterface $entity) return $request; } - - /** - * Retrieve collection processor - * - * @deprecated 100.2.0 - * @return CollectionProcessorInterface - */ - private function getCollectionProcessor() - { - if (!$this->collectionProcessor) { - $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class - ); - } - return $this->collectionProcessor; - } } diff --git a/app/code/Magento/Sales/Model/Order/ProductOption.php b/app/code/Magento/Sales/Model/Order/ProductOption.php new file mode 100644 index 0000000000000..dc9ec42e27e60 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/ProductOption.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Model\Order; + +use Magento\Sales\Api\Data\OrderItemInterface; +use Magento\Framework\DataObject; +use Magento\Catalog\Model\ProductOptionFactory; +use Magento\Catalog\Model\ProductOptionProcessorInterface; +use Magento\Catalog\Api\Data\ProductOptionExtensionFactory; + +/** + * Adds product option to the order item according to product options processors pool. + * + * @api + */ +class ProductOption +{ + /** + * @var ProductOptionFactory + */ + private $productOptionFactory; + + /** + * @var ProductOptionExtensionFactory + */ + private $extensionFactory; + + /** + * @var ProductOptionProcessorInterface[] + */ + private $processorPool; + + /** + * @param ProductOptionFactory $productOptionFactory + * @param ProductOptionExtensionFactory $extensionFactory + * @param array $processorPool + */ + public function __construct( + ProductOptionFactory $productOptionFactory, + ProductOptionExtensionFactory $extensionFactory, + array $processorPool = [] + ) { + $this->productOptionFactory = $productOptionFactory; + $this->extensionFactory = $extensionFactory; + $this->processorPool = $processorPool; + } + + /** + * Adds product option to the order item. + * + * @param OrderItemInterface $orderItem + */ + public function add(OrderItemInterface $orderItem): void + { + /** @var DataObject $request */ + $request = $orderItem->getBuyRequest(); + + $productType = $orderItem->getProductType(); + if (isset($this->processorPool[$productType]) + && !$orderItem->getParentItemId()) { + $data = $this->processorPool[$productType]->convertToProductOption($request); + if ($data) { + $this->setProductOption($orderItem, $data); + } + } + + if (isset($this->processorPool['custom_options']) + && !$orderItem->getParentItemId()) { + $data = $this->processorPool['custom_options']->convertToProductOption($request); + if ($data) { + $this->setProductOption($orderItem, $data); + } + } + } + + /** + * Sets product options data. + * + * @param OrderItemInterface $orderItem + * @param array $data + */ + private function setProductOption(OrderItemInterface $orderItem, array $data): void + { + $productOption = $orderItem->getProductOption(); + if (!$productOption) { + $productOption = $this->productOptionFactory->create(); + $orderItem->setProductOption($productOption); + } + + $extensionAttributes = $productOption->getExtensionAttributes(); + if (!$extensionAttributes) { + $extensionAttributes = $this->extensionFactory->create(); + $productOption->setExtensionAttributes($extensionAttributes); + } + + $extensionAttributes->setData(key($data), current($data)); + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php deleted file mode 100644 index 8be2c3c8612d7..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ /dev/null @@ -1,366 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Test\Unit\Model\Order; - -use Magento\Sales\Model\Order\ItemRepository; - -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class ItemRepositoryTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Framework\DataObject\Factory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectFactory; - - /** - * @var \Magento\Sales\Model\ResourceModel\Metadata|\PHPUnit_Framework_MockObject_MockObject - */ - protected $metadata; - - /** - * @var \Magento\Sales\Api\Data\OrderItemSearchResultInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $searchResultFactory; - - /** - * @var \Magento\Catalog\Model\ProductOptionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $productOptionProcessorMock; - - /** - * @var \Magento\Catalog\Model\ProductOptionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $productOptionFactory; - - /** - * @var \Magento\Catalog\Api\Data\ProductOptionExtensionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $extensionFactory; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $collectionProcessor; - - /** - * @var array - */ - protected $productOptionData = []; - - protected function setUp() - { - $this->objectFactory = $this->getMockBuilder(\Magento\Framework\DataObject\Factory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->metadata = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Metadata::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->searchResultFactory = $this->getMockBuilder( - \Magento\Sales\Api\Data\OrderItemSearchResultInterfaceFactory::class - ) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->productOptionFactory = $this->getMockBuilder(\Magento\Catalog\Model\ProductOptionFactory::class) - ->setMethods([ - 'create', - ]) - ->disableOriginalConstructor() - ->getMock(); - - $this->collectionProcessor = $this->createMock( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class - ); - - $this->extensionFactory = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductOptionExtensionFactory::class) - ->setMethods([ - 'create', - ]) - ->disableOriginalConstructor() - ->getMock(); - } - - /** - * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage An ID is needed. Set the ID and try again. - */ - public function testGetWithNoId() - { - $model = new ItemRepository( - $this->objectFactory, - $this->metadata, - $this->searchResultFactory, - $this->productOptionFactory, - $this->extensionFactory, - [], - $this->collectionProcessor - ); - - $model->get(null); - } - - /** - * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedExceptionMessage The entity that was requested doesn't exist. Verify the entity and try again. - */ - public function testGetEmptyEntity() - { - $orderItemId = 1; - - $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemMock->expects($this->once()) - ->method('load') - ->with($orderItemId) - ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) - ->method('getItemId') - ->willReturn(null); - - $this->metadata->expects($this->once()) - ->method('getNewInstance') - ->willReturn($orderItemMock); - - $model = new ItemRepository( - $this->objectFactory, - $this->metadata, - $this->searchResultFactory, - $this->productOptionFactory, - $this->extensionFactory, - [], - $this->collectionProcessor - ); - - $model->get($orderItemId); - } - - public function testGet() - { - $orderItemId = 1; - $productType = 'configurable'; - - $this->productOptionData = ['option1' => 'value1']; - - $this->getProductOptionExtensionMock(); - $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); - - $orderItemMock->expects($this->once()) - ->method('load') - ->with($orderItemId) - ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) - ->method('getItemId') - ->willReturn($orderItemId); - - $this->metadata->expects($this->once()) - ->method('getNewInstance') - ->willReturn($orderItemMock); - - $model = $this->getModel($orderItemMock, $productType); - $this->assertSame($orderItemMock, $model->get($orderItemId)); - - // Assert already registered - $this->assertSame($orderItemMock, $model->get($orderItemId)); - } - - public function testGetList() - { - $productType = 'configurable'; - $this->productOptionData = ['option1' => 'value1']; - $searchCriteriaMock = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteria::class) - ->disableOriginalConstructor() - ->getMock(); - $this->getProductOptionExtensionMock(); - $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); - - $searchResultMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class) - ->disableOriginalConstructor() - ->getMock(); - $searchResultMock->expects($this->once()) - ->method('getItems') - ->willReturn([$orderItemMock]); - - $this->searchResultFactory->expects($this->once()) - ->method('create') - ->willReturn($searchResultMock); - - $model = $this->getModel($orderItemMock, $productType); - $this->assertSame($searchResultMock, $model->getList($searchCriteriaMock)); - } - - public function testDeleteById() - { - $orderItemId = 1; - $productType = 'configurable'; - - $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - - $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemMock->expects($this->once()) - ->method('load') - ->with($orderItemId) - ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) - ->method('getItemId') - ->willReturn($orderItemId); - $orderItemMock->expects($this->once()) - ->method('getProductType') - ->willReturn($productType); - $orderItemMock->expects($this->once()) - ->method('getBuyRequest') - ->willReturn($requestMock); - - $orderItemResourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemResourceMock->expects($this->once()) - ->method('delete') - ->with($orderItemMock) - ->willReturnSelf(); - - $this->metadata->expects($this->once()) - ->method('getNewInstance') - ->willReturn($orderItemMock); - $this->metadata->expects($this->exactly(1)) - ->method('getMapper') - ->willReturn($orderItemResourceMock); - - $model = $this->getModel($orderItemMock, $productType); - $this->assertTrue($model->deleteById($orderItemId)); - } - - /** - * @param \PHPUnit_Framework_MockObject_MockObject $orderItemMock - * @param string $productType - * @param array $data - * @return ItemRepository - */ - protected function getModel( - \PHPUnit_Framework_MockObject_MockObject $orderItemMock, - $productType, - array $data = [] - ) { - $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - - $requestUpdateMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - $requestUpdateMock->expects($this->any()) - ->method('getData') - ->willReturn($data); - - $this->productOptionProcessorMock = $this->getMockBuilder( - \Magento\Catalog\Model\ProductOptionProcessorInterface::class - ) - ->getMockForAbstractClass(); - $this->productOptionProcessorMock->expects($this->any()) - ->method('convertToProductOption') - ->with($requestMock) - ->willReturn($this->productOptionData); - $this->productOptionProcessorMock->expects($this->any()) - ->method('convertToBuyRequest') - ->with($orderItemMock) - ->willReturn($requestUpdateMock); - - $model = new ItemRepository( - $this->objectFactory, - $this->metadata, - $this->searchResultFactory, - $this->productOptionFactory, - $this->extensionFactory, - [ - $productType => $this->productOptionProcessorMock, - 'custom_options' => $this->productOptionProcessorMock - ], - $this->collectionProcessor - ); - return $model; - } - - /** - * @param string $productType - * @param \PHPUnit_Framework_MockObject_MockObject $productOption - * @return \PHPUnit_Framework_MockObject_MockObject - */ - protected function getOrderMock($productType, $productOption) - { - $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - - $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemMock->expects($this->once()) - ->method('getProductType') - ->willReturn($productType); - $orderItemMock->expects($this->once()) - ->method('getBuyRequest') - ->willReturn($requestMock); - $orderItemMock->expects($this->any()) - ->method('getProductOption') - ->willReturn(null); - $orderItemMock->expects($this->any()) - ->method('setProductOption') - ->with($productOption) - ->willReturnSelf(); - - return $orderItemMock; - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - protected function getProductOptionMock() - { - $productOption = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductOptionInterface::class) - ->getMockForAbstractClass(); - $productOption->expects($this->any()) - ->method('getExtensionAttributes') - ->willReturn(null); - - $this->productOptionFactory->expects($this->any()) - ->method('create') - ->willReturn($productOption); - - return $productOption; - } - - protected function getProductOptionExtensionMock() - { - $productOptionExtension = $this->getMockBuilder( - \Magento\Catalog\Api\Data\ProductOptionExtensionInterface::class - ) - ->setMethods([ - 'setData', - ]) - ->getMockForAbstractClass(); - $productOptionExtension->expects($this->any()) - ->method('setData') - ->with(key($this->productOptionData), current($this->productOptionData)) - ->willReturnSelf(); - - $this->extensionFactory->expects($this->any()) - ->method('create') - ->willReturn($productOptionExtension); - } -} diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php index a10a224604897..09c49bed1de83 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php @@ -3,8 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Service\V1; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Webapi\Rest\Request; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; class OrderGetTest extends WebapiAbstract @@ -18,19 +25,24 @@ class OrderGetTest extends WebapiAbstract const ORDER_INCREMENT_ID = '100000001'; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ - protected $objectManager; + private $objectManager; - protected function setUp() + /** + * @inheritdoc + */ + protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->objectManager = Bootstrap::getObjectManager(); } /** + * Checks order attributes. + * * @magentoApiDataFixture Magento/Sales/_files/order.php */ - public function testOrderGet() + public function testOrderGet(): void { $expectedOrderData = [ 'base_subtotal' => '100.0000', @@ -67,36 +79,21 @@ public function testOrderGet() 'region' => 'CA' ]; - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); - $order->loadByIncrementId(self::ORDER_INCREMENT_ID); - - $serviceInfo = [ - 'rest' => [ - 'resourcePath' => self::RESOURCE_PATH . '/' . $order->getId(), - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, - ], - 'soap' => [ - 'service' => self::SERVICE_READ_NAME, - 'serviceVersion' => self::SERVICE_VERSION, - 'operation' => self::SERVICE_READ_NAME . 'get', - ], - ]; - $result = $this->_webApiCall($serviceInfo, ['id' => $order->getId()]); + $result = $this->makeServiceCall(self::ORDER_INCREMENT_ID); foreach ($expectedOrderData as $field => $value) { - $this->assertArrayHasKey($field, $result); - $this->assertEquals($value, $result[$field]); + self::assertArrayHasKey($field, $result); + self::assertEquals($value, $result[$field]); } - $this->assertArrayHasKey('payment', $result); + self::assertArrayHasKey('payment', $result); foreach ($expectedPayments as $field => $value) { - $this->assertEquals($value, $result['payment'][$field]); + self::assertEquals($value, $result['payment'][$field]); } - $this->assertArrayHasKey('billing_address', $result); + self::assertArrayHasKey('billing_address', $result); foreach ($expectedBillingAddressNotEmpty as $field) { - $this->assertArrayHasKey($field, $result['billing_address']); + self::assertArrayHasKey($field, $result['billing_address']); } self::assertArrayHasKey('extension_attributes', $result); @@ -112,28 +109,86 @@ public function testOrderGet() //check that nullable fields were marked as optional and were not sent foreach ($result as $value) { - $this->assertNotNull($value); + self::assertNotNull($value); } } /** + * Checks order extension attributes. + * * @magentoApiDataFixture Magento/Sales/_files/order_with_tax.php */ - public function testOrderGetExtensionAttributes() + public function testOrderGetExtensionAttributes(): void { $expectedTax = [ 'code' => 'US-NY-*-Rate 1', 'type' => 'shipping' ]; - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); - $order->loadByIncrementId(self::ORDER_INCREMENT_ID); + $result = $this->makeServiceCall(self::ORDER_INCREMENT_ID); + $appliedTaxes = $result['extension_attributes']['applied_taxes']; + self::assertEquals($expectedTax['code'], $appliedTaxes[0]['code']); + $appliedTaxes = $result['extension_attributes']['item_applied_taxes']; + self::assertEquals($expectedTax['type'], $appliedTaxes[0]['type']); + self::assertNotEmpty($appliedTaxes[0]['applied_taxes']); + self::assertEquals(true, $result['extension_attributes']['converting_from_quote']); + } + + /** + * Checks if the order contains product option attributes. + * + * @magentoApiDataFixture Magento/Sales/_files/order_with_bundle.php + */ + public function testGetOrderWithProductOption(): void + { + $expected = [ + 'extension_attributes' => [ + 'bundle_options' => [ + [ + 'option_id' => 1, + 'option_selections' => [1], + 'option_qty' => 1 + ] + ] + ] + ]; + $result = $this->makeServiceCall(self::ORDER_INCREMENT_ID); + + $bundleProduct = $this->getBundleProduct($result['items']); + self::assertNotEmpty($bundleProduct, '"Bundle Product" should not be empty.'); + self::assertNotEmpty($bundleProduct['product_option'], '"Product Option" should not be empty.'); + self::assertEquals($expected, $bundleProduct['product_option']); + } + + /** + * Gets order by increment ID. + * + * @param string $incrementId + * @return OrderInterface + */ + private function getOrder(string $incrementId): OrderInterface + { + /** @var Order $order */ + $order = $this->objectManager->create(Order::class); + $order->loadByIncrementId($incrementId); + + return $order; + } + + /** + * Makes service call. + * + * @param string $incrementId + * @return array + */ + private function makeServiceCall(string $incrementId): array + { + $order = $this->getOrder($incrementId); $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/' . $order->getId(), - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + 'httpMethod' => Request::HTTP_METHOD_GET, ], 'soap' => [ 'service' => self::SERVICE_READ_NAME, @@ -141,13 +196,23 @@ public function testOrderGetExtensionAttributes() 'operation' => self::SERVICE_READ_NAME . 'get', ], ]; - $result = $this->_webApiCall($serviceInfo, ['id' => $order->getId()]); + return $this->_webApiCall($serviceInfo, ['id' => $order->getId()]); + } - $appliedTaxes = $result['extension_attributes']['applied_taxes']; - $this->assertEquals($expectedTax['code'], $appliedTaxes[0]['code']); - $appliedTaxes = $result['extension_attributes']['item_applied_taxes']; - $this->assertEquals($expectedTax['type'], $appliedTaxes[0]['type']); - $this->assertNotEmpty($appliedTaxes[0]['applied_taxes']); - $this->assertEquals(true, $result['extension_attributes']['converting_from_quote']); + /** + * Gets a bundle product from the result. + * + * @param array $items + * @return array + */ + private function getBundleProduct(array $items): array + { + foreach ($items as $item) { + if ($item['product_type'] == 'bundle') { + return $item; + } + } + + return []; } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php index 6b6d6d6e6ec04..4473fb8dfe72c 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_bundle.php @@ -6,7 +6,6 @@ declare(strict_types=1); use Magento\Sales\Api\Data\OrderItemInterface; -use Magento\Sales\Api\OrderItemRepositoryInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Item; @@ -29,6 +28,10 @@ OrderItemInterface::PRODUCT_TYPE => 'bundle', 'product_options' => [ 'product_calculations' => 0, + 'info_buyRequest' => [ + 'bundle_option' => [1 => 1], + 'bundle_option_qty' => 1, + ] ], 'children' => [ [ diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index e21841b48bc13..a4f728454a524 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -30,7 +30,7 @@ class PluginList extends Scoped implements InterceptionPluginList * * @var array */ - protected $_inherited; + protected $_inherited = []; /** * Inherited plugin data, preprocessed for read From dfc9cd0a5ce6d9285b56b40f9cc4c429f8d5f33c Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 26 Oct 2018 17:23:09 +0300 Subject: [PATCH 0836/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index b10c8e5ad54a0..1cd0e15780c11 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -161,7 +161,7 @@ <!-- Go to the product page and see the uploaded image --> <amOnPage url="$$secondProduct.name$$.html" stepKey="goToStorefront2"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('Large')}}" stepKey="seeLarge2"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge2"/> </test> <test name="AdminSimpleProductRemoveImagesTest"> From 505ac52e2a242555873545faced2eef0a275fe4e Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Fri, 26 Oct 2018 16:55:02 +0200 Subject: [PATCH 0837/1415] GraphQL-202: [Mutations] adds sendEmailFriend Logic --- .../Model/Resolver/SendEmailToFriend.php | 147 ++++++++++++++++++ .../Magento/SendFriendGraphQl/etc/module.xml | 11 ++ .../SendFriendGraphQl/etc/schema.graphqls | 33 ++++ .../SendFriendGraphQl/registration.php | 9 ++ 4 files changed, 200 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php create mode 100644 app/code/Magento/SendFriendGraphQl/etc/module.xml create mode 100644 app/code/Magento/SendFriendGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/SendFriendGraphQl/registration.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php new file mode 100644 index 0000000000000..56f6d20b20f18 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -0,0 +1,147 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SendFriendGraphQl\Model\Resolver; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\DataObjectFactory; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\SendFriend\Model\SendFriend; + +class SendEmailToFriend implements ResolverInterface +{ + /** + * @var SendFriend + */ + private $sendFriend; + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + public function __construct( + SendFriend $sendFriend, + ProductRepositoryInterface $productRepository, + DataObjectFactory $dataObjectFactory + ) { + $this->sendFriend = $sendFriend; + $this->productRepository = $productRepository; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + + $product = $this->getProductFromRepository($args['input']['params']['product_id']); + $senderArray = $this->getSenderArrayFromArgs($args); + $recipientsArray = $this->getRecipientsArray($args); + //@todo clarify if event should be dispatched + //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); + $this->sendFriend->setSender($senderArray); + $this->sendFriend->setRecipients($recipientsArray); + $this->sendFriend->setProduct($product); + + $this->prepareDataForValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + $this->addRecipientNameValidation($args); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + + $this->sendFriend->send(); + + return array_merge($senderArray, $recipientsArray); + } + + private function prepareDataForValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + + /** + * @param array $args + * @throws GraphQlInputException + */ + private function addRecipientNameValidation(array $args): void + { + foreach ($args['input']['recipients'] as $recipient) { + if (empty($recipient['name'])) { + throw new GraphQlInputException( + __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] + )); + } + } + } + + /** + * @param int $productId + * @return bool|\Magento\Catalog\Api\Data\ProductInterface + */ + private function getProductFromRepository(int $productId) + { + try { + $product = $this->productRepository->getById($productId); + if (!$product->isVisibleInCatalog()) { + return false; + } + } catch (NoSuchEntityException $noEntityException) { + return false; + } + + return $product; + } + + private function getRecipientsArray(array $args): array + { + $recipientsArray = []; + foreach ($args['input']['recipients'] as $recipient) { + $recipientsArray[] = [ + 'name' => $recipient['name'], + 'email' => $recipient['email'], + ]; + } + return ['recipients' => $recipientsArray]; + } + + private function getSenderArrayFromArgs(array $args): array + { + return ['sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ] + ]; + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml new file mode 100644 index 0000000000000..14d792198cd5f --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_SendFriendGraphGl"/> +</config> diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..87bf90fd10072 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -0,0 +1,33 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Mutation { + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") +} + +input SendEmailToFriendSenderInput { + sender: Sender! + params: Params! + recipients: [Recipient] +} + +type Sender { + name: String! + email: String! + message: String! +} +#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed +type Params { + product_id: Int! +} + +type Recipient { + name: String! + email: String! +} + + +type SendEmailToFriendOutput { + sender: Sender + recipients: [Recipient] +} diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php new file mode 100644 index 0000000000000..c41607a0dc864 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphGl', __DIR__); From 9a7fa4c650dd41151d986486a02dd58d4c6cc2ff Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 12:26:08 -0400 Subject: [PATCH 0838/1415] Added $_regionCollection property to class --- .../Magento/CustomerImportExport/Model/Import/Address.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index e1345edcf146d..9ba50738ebc1a 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -101,6 +101,13 @@ class Address extends AbstractCustomer */ protected $_entityTable; + /** + * Region collection instance + * + * @var string + */ + protected $_regionCollection; + /** * Countries and regions * From ac90f7a0be57d6d4240e64ac7fd98aeafeb80045 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 12:52:10 -0400 Subject: [PATCH 0839/1415] Added $connection property to class --- .../Magento/DownloadableImportExport/Helper/Uploader.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php index 46081f77cc66a..9420aeb51d41c 100644 --- a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php +++ b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php @@ -38,6 +38,13 @@ class Uploader extends \Magento\Framework\App\Helper\AbstractHelper */ protected $parameters = []; + /** + * Connection resource. + * + * @var \Magento\Framework\DB\Adapter\AdapterInterface + */ + protected $connection = []; + /** * Construct * From 06a47b55f36dda9bec631eede0f4cf9566971b82 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 13:01:39 -0400 Subject: [PATCH 0840/1415] Added $websiteString property to test class --- .../Model/Import/AdvancedPricing/Validator/WebsiteTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php index b46e286e75007..41ac72bd8dacc 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php @@ -25,6 +25,11 @@ class WebsiteTest extends \PHPUnit\Framework\TestCase */ protected $website; + /** + * @var \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website|\PHPUnit_Framework_MockObject_MockObject + */ + protected $websiteString; + protected function setUp() { $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\Website::class) From e3df0f684ac20c478685cc601590e5231a531eb1 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 13:12:37 -0400 Subject: [PATCH 0841/1415] Fixed miss called property in getStoreIdByCode method --- .../BundleImportExport/Model/Import/Product/Type/Bundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php index 3ed7e144ddd5a..77d331a8b5696 100644 --- a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php +++ b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php @@ -779,7 +779,7 @@ protected function clear() */ private function getStoreIdByCode(string $storeCode): int { - if (!isset($this->storeIdToCode[$storeCode])) { + if (!isset($this->storeCodeToId[$storeCode])) { /** @var $store \Magento\Store\Model\Store */ foreach ($this->storeManager->getStores() as $store) { $this->storeCodeToId[$store->getCode()] = $store->getId(); From 5181674d525cc5e39482ac443ea3ac2b1a6c9bd0 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 13:28:40 -0400 Subject: [PATCH 0842/1415] Added $_customerCollection property to Storage class --- .../Model/ResourceModel/Import/Customer/Storage.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php index f779505a38011..38890de643295 100644 --- a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php +++ b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php @@ -48,6 +48,13 @@ class Storage */ private $customerCollectionFactory; + /** + * Customer collection. + * + * @var \Magento\Customer\Model\ResourceModel\Customer\Collection + */ + private $_customerCollection; + /** * @param CustomerCollectionFactory $collectionFactory * @param CollectionByPagesIteratorFactory $colIteratorFactory From dfa2f25534e05050fde25d2b4b960f5ecfa173bd Mon Sep 17 00:00:00 2001 From: Rus0 <andoni@space.bar> Date: Fri, 26 Oct 2018 14:50:55 -0500 Subject: [PATCH 0843/1415] Resolves issue 6731 by adding a custom message for refunding shipping --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 0cc4143e569db..c62f6459a5e91 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -10,6 +10,7 @@ class Discount extends AbstractTotal /** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { @@ -26,6 +27,16 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * basing on how much shipping should be refunded. */ $baseShippingAmount = $this->getBaseShippingAmount($creditmemo); + + /** + * If credit memo's shipping amount is set and Order's shipping amount is 0, + * throw exception with differente message + */ + if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + ); + } if ($baseShippingAmount) { $baseShippingDiscount = $baseShippingAmount * $order->getBaseShippingDiscountAmount() / From 0f0f64de5c2ece4a0d3ec9ed54f65df3c30284e9 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:34:08 -0500 Subject: [PATCH 0844/1415] magento/magento2#18840: Invalid Unit Test Annotations - fixed invalid unit tests annotations that assert exception messages --- .../Unit/Model/Product/Gallery/GalleryManagementTest.php | 2 +- .../Catalog/Test/Unit/Model/Product/PriceModifierTest.php | 6 +++--- .../Test/Unit/Model/Product/TierPriceManagementTest.php | 2 +- app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php | 2 +- .../Downloadable/Test/Unit/Helper/DownloadTest.php | 2 +- .../GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php | 8 ++++---- .../GuestCartManagement/Plugin/AuthorizationTest.php | 2 +- .../Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php | 2 +- .../Test/Unit/Model/ShippingAddressManagementTest.php | 2 +- .../Search/Test/Unit/Model/SynonymGroupRepositoryTest.php | 4 ++-- .../Theme/Test/Unit/Model/Theme/Source/ThemeTest.php | 1 - .../Ui/Test/Unit/Component/Filters/FilterModifierTest.php | 5 +++-- .../Magento/Framework/App/Test/Unit/ErrorHandlerTest.php | 4 ++-- .../App/Test/Unit/Response/Http/FileFactoryTest.php | 2 +- lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php | 2 +- .../Profiler/Test/Unit/Driver/Standard/StatTest.php | 4 ++-- .../Setup/Test/Unit/Module/I18n/Parser/ParserTest.php | 2 +- 17 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php index 9fafbc9d9675b..1d12645019d1e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php @@ -266,7 +266,7 @@ public function testGetWithNonExistingProduct() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedExceptionText The image doesn't exist. Verify and try again. + * @expectedExceptionMessage The image doesn't exist. Verify and try again. */ public function testGetWithNonExistingImage() { diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php index 754d80302d410..6029a2b820086 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php @@ -54,7 +54,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedMessage Tier price is unavailable for this product. + * @expectedExceptionMessage Product hasn't group price with such data: customerGroupId = '1', website = 1, qty = 3 */ public function testRemoveWhenTierPricesNotExists() { @@ -70,7 +70,7 @@ public function testRemoveWhenTierPricesNotExists() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedMessage For current customerGroupId = '10' with 'qty' = 15 any tier price exist'. + * @expectedExceptionMessage Product hasn't group price with such data: customerGroupId = '10', website = 1, qty = 5 */ public function testRemoveTierPriceForNonExistingCustomerGroup() { @@ -81,7 +81,7 @@ public function testRemoveTierPriceForNonExistingCustomerGroup() ->will($this->returnValue($this->prices)); $this->productMock->expects($this->never())->method('setData'); $this->productRepositoryMock->expects($this->never())->method('save'); - $this->priceModifier->removeTierPrice($this->productMock, 10, 15, 1); + $this->priceModifier->removeTierPrice($this->productMock, 10, 5, 1); } public function testSuccessfullyRemoveTierPriceSpecifiedForAllGroups() diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php index f340d0b204b62..ae479a9b34d48 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php @@ -195,7 +195,7 @@ public function testSuccessDeleteTierPrice() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @message The product doesn't exist. Verify and try again. + * @expectedExceptionMessage No such entity. */ public function testDeleteTierPriceFromNonExistingProduct() { diff --git a/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php index a196b10478c7f..ff7340f87f32e 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php @@ -98,7 +98,7 @@ public function testCheckQuoteItem() /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @exceptedExceptionMessage The quote item isn't found. Verify the item and try again. + * @expectedExceptionMessage The quote item isn't found. Verify the item and try again. */ public function testCheckQuoteItemWithException() { diff --git a/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php b/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php index 7cb5b03b0385f..9551cfe982bd5 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php @@ -89,7 +89,7 @@ public function testSetResourceInvalidPath() /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @exectedExceptionMessage Please set resource file and link type. + * @expectedExceptionMessage Please set resource file and link type. */ public function testGetFileSizeNoResource() { diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php index 2170864407ea4..f3e060ad5fc72 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php @@ -128,7 +128,7 @@ public function testAfterSaveGiftMessages() /** * @expectedException \Magento\Framework\Exception\CouldNotSaveException - * @expectedMessage The gift message couldn't be added to the "Test message" order. + * @expectedExceptionMessage The gift message couldn't be added to the "Test message" order. */ public function testAfterSaveIfGiftMessagesNotExist() { @@ -146,7 +146,7 @@ public function testAfterSaveIfGiftMessagesNotExist() $this->giftMessageOrderRepositoryMock ->expects($this->once()) ->method('save') - ->willThrowException(new \Exception('TestMessage')); + ->willThrowException(new \Exception('Test message')); // save Gift Messages on item level $this->orderMock->expects($this->never())->method('getItems'); @@ -155,7 +155,7 @@ public function testAfterSaveIfGiftMessagesNotExist() /** * @expectedException \Magento\Framework\Exception\CouldNotSaveException - * @expectedMessage The gift message couldn't be added to the "Test message" order. + * @expectedExceptionMessage The gift message couldn't be added to the "Test message" order item. */ public function testAfterSaveIfItemGiftMessagesNotExist() { @@ -185,7 +185,7 @@ public function testAfterSaveIfItemGiftMessagesNotExist() $this->giftMessageOrderItemRepositoryMock ->expects($this->once())->method('save') ->with($orderId, $orderItemId, $this->giftMessageMock) - ->willThrowException(new \Exception('TestMessage')); + ->willThrowException(new \Exception('Test message')); $this->plugin->afterSave($this->orderRepositoryMock, $this->orderMock); } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php b/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php index 22962aacc8dac..49ed8a10bee35 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php @@ -36,7 +36,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\StateException - * @expectedMessage You don't have the correct permissions to assign the customer to the cart. + * @expectedExceptionMessage You don't have the correct permissions to assign the customer to the cart. */ public function testBeforeAssignCustomer() { diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php index af47f6276705b..7933da7c5fe37 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php @@ -92,7 +92,7 @@ protected function setUp() /** * @expectedException \InvalidArgumentException - * @ExceptedExceptionMessage The qty value is required to update quote item. + * @expectedExceptionMessage The qty value is required to update quote item. */ public function testUpdateNoQty() { diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php index e3d5528d62c70..89fea2bec73a8 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php @@ -102,7 +102,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expected ExceptionMessage error345 + * @expectedExceptionMessage error345 */ public function testSetAddressValidationFailed() { diff --git a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php index f62c07b149c0e..4532479c482b5 100644 --- a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php +++ b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php @@ -53,7 +53,7 @@ public function testSaveCreate() /** * @expectedException \Magento\Search\Model\Synonym\MergeConflictException - * @expecteExceptionMessage (c,d,e) + * @expectedExceptionMessage Merge conflict with existing synonym group(s): (a,b,c) */ public function testSaveCreateMergeConflict() { @@ -138,7 +138,7 @@ public function testSaveUpdate() /** * @expectedException \Magento\Search\Model\Synonym\MergeConflictException - * @expecteExceptionMessage (d,h,i) + * @expectedExceptionMessage (d,h,i) */ public function testSaveUpdateMergeConflict() { diff --git a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php index 5cb265d3d628b..c06e2626034a7 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php @@ -10,7 +10,6 @@ class ThemeTest extends \PHPUnit\Framework\TestCase { /** - * @true * @return void * @covers \Magento\Theme\Model\Theme\Source\Theme::__construct * @covers \Magento\Theme\Model\Theme\Source\Theme::getAllOptions diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php index f91401e43ea80..50d82b19d1045 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php @@ -66,7 +66,8 @@ public function testNotApplyFilterModifier() /** * @return void - * @assertException \Magento\Framework\Exception\LocalizedException + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Condition type "not_allowed" is not allowed */ public function testApplyFilterModifierWithNotAllowedCondition() { @@ -78,7 +79,7 @@ public function testApplyFilterModifierWithNotAllowedCondition() ] ]); $this->dataProvider->expects($this->never())->method('addFilter'); - $this->unit->applyFilterModifier($this->dataProvider, 'test'); + $this->unit->applyFilterModifier($this->dataProvider, 'filter'); } /** diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php index 4b904cc2b55bd..bba4d67ddd108 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php @@ -56,9 +56,9 @@ public function testHandlerException($errorNo, $errorPhrase) $errorFile = 'test_file'; $errorLine = 'test_error_line'; - $exceptedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); + $expectedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); $this->expectException('Exception'); - $this->expectExceptionMessage($exceptedExceptionMessage); + $this->expectExceptionMessage($expectedExceptionMessage); $this->object->handler($errorNo, $errorStr, $errorFile, $errorLine); } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php index 11e305f806ba2..7ad2f21c89d71 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php @@ -67,7 +67,7 @@ public function testCreateIfContentDoesntHaveRequiredKeys() /** * @expectedException \Exception - * @exceptedExceptionMessage File not found + * @expectedExceptionMessage File not found */ public function testCreateIfFileNotExist() { diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php index 807a70ecd7599..f39a91161c1f5 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php @@ -122,7 +122,7 @@ public function testGetLayout() /** * @expectedException \RuntimeException - * @exceptedExceptionMessage 'Layout must be loaded only once.' + * @expectedExceptionMessage Layout must be loaded only once. */ public function testLoadLayoutWhenLayoutAlreadyLoaded() { diff --git a/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php b/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php index d694697284f8e..df74eeec972ba 100644 --- a/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php +++ b/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php @@ -395,7 +395,7 @@ public function fetchDataProvider() /** * @expectedException \InvalidArgumentException - * @expectedMessage Timer "foo" doesn't exist. + * @expectedExceptionMessage Timer "foo" doesn't exist. */ public function testFetchInvalidTimer() { @@ -404,7 +404,7 @@ public function testFetchInvalidTimer() /** * @expectedException \InvalidArgumentException - * @expectedMessage Timer "foo" doesn't have value for "bar". + * @expectedExceptionMessage Timer "foo" doesn't have value for "bar". */ public function testFetchInvalidKey() { diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php index 76c5a6d031399..d429d0a0c9953 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php @@ -39,7 +39,7 @@ protected function setUp() * @param array $jsFiles * @param array $phpMap * @param array $jsMap - * @paran array $phraseFactoryMap + * @param array $phraseFactoryMap * @param array $expectedResult * @dataProvider addPhraseDataProvider */ From 4cf4884343010b2c0dc770ed3af6afb558b0d19b Mon Sep 17 00:00:00 2001 From: Rus0 <andonid88@gmail.com> Date: Fri, 26 Oct 2018 14:50:55 -0500 Subject: [PATCH 0845/1415] Resolves issue 6731 by adding a custom message for refunding shipping --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 0cc4143e569db..c62f6459a5e91 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -10,6 +10,7 @@ class Discount extends AbstractTotal /** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { @@ -26,6 +27,16 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * basing on how much shipping should be refunded. */ $baseShippingAmount = $this->getBaseShippingAmount($creditmemo); + + /** + * If credit memo's shipping amount is set and Order's shipping amount is 0, + * throw exception with differente message + */ + if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + ); + } if ($baseShippingAmount) { $baseShippingDiscount = $baseShippingAmount * $order->getBaseShippingDiscountAmount() / From b02dbc6f69ef9b2a48946218446302b204a6966e Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:32 -0500 Subject: [PATCH 0846/1415] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index c62f6459a5e91..d33374d5430ad 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -30,7 +30,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) /** * If credit memo's shipping amount is set and Order's shipping amount is 0, - * throw exception with differente message + * throw exception with different message */ if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { throw new \Magento\Framework\Exception\LocalizedException( From d3e576f9ff770aa0d9475ff24f29eb0c4c8780b9 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:43 -0500 Subject: [PATCH 0847/1415] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index d33374d5430ad..53faa4e23488c 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -32,7 +32,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * If credit memo's shipping amount is set and Order's shipping amount is 0, * throw exception with different message */ - if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) ); From 02dc040145559d88a86a971b5c0e08076735534c Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:57 -0500 Subject: [PATCH 0848/1415] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 53faa4e23488c..749a12f7d8b55 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -34,7 +34,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) */ if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.", []) ); } if ($baseShippingAmount) { From 73af54a06edfb2a2f4e2582f229dc4d301db9df4 Mon Sep 17 00:00:00 2001 From: Rus0 <andonid88@gmail.com> Date: Fri, 26 Oct 2018 16:16:29 -0500 Subject: [PATCH 0849/1415] Correcting Unit tests --- .../Order/Creditmemo/Total/DiscountTest.php | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php index 18efef38b204c..a9a859ea1b5d6 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php @@ -74,7 +74,7 @@ public function testCollect() $this->orderMock->expects($this->once()) ->method('getBaseShippingDiscountAmount') ->willReturn(1); - $this->orderMock->expects($this->exactly(2)) + $this->orderMock->expects($this->exactly(3)) ->method('getBaseShippingAmount') ->willReturn(1); $this->orderMock->expects($this->once()) @@ -150,7 +150,7 @@ public function testCollectNoBaseShippingAmount() $this->orderMock->expects($this->once()) ->method('getBaseShippingDiscountAmount') ->willReturn(1); - $this->orderMock->expects($this->exactly(2)) + $this->orderMock->expects($this->exactly(3)) ->method('getBaseShippingAmount') ->willReturn(1); $this->orderMock->expects($this->once()) @@ -269,4 +269,30 @@ public function testCollectZeroShipping() ); $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage You can not refund shipping if there is no shipping amount. + */ + public function testCollectNonZeroShipping() + { + $this->creditmemoMock->expects($this->once()) + ->method('setDiscountAmount') + ->willReturnSelf(); + $this->creditmemoMock->expects($this->once()) + ->method('setBaseDiscountAmount') + ->willReturnSelf(); + $this->creditmemoMock->expects($this->once()) + ->method('getOrder') + ->willReturn($this->orderMock); + $this->creditmemoMock->expects($this->once()) + ->method('getBaseShippingAmount') + ->willReturn('10.0000'); + $this->orderMock->expects($this->never()) + ->method('getBaseShippingDiscountAmount'); + $this->orderMock->expects($this->once()) + ->method('getBaseShippingAmount') + ->willReturn( '0.0000'); + $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); + } } From 2054fab1731a63728a6b4e573cefbbf3e64d6c85 Mon Sep 17 00:00:00 2001 From: Rus0 <andonid88@gmail.com> Date: Fri, 26 Oct 2018 16:25:02 -0500 Subject: [PATCH 0850/1415] Autoload for root folders --- app/autoload.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/autoload.php b/app/autoload.php index 54087d0255495..d6407083dc0b3 100644 --- a/app/autoload.php +++ b/app/autoload.php @@ -28,6 +28,9 @@ /* 'composer install' validation */ if (file_exists($vendorAutoload)) { $composerAutoloader = include $vendorAutoload; +} else if (file_exists("{$vendorDir}/autoload.php")) { + $vendorAutoload = "{$vendorDir}/autoload.php"; + $composerAutoloader = include $vendorAutoload; } else { throw new \Exception( 'Vendor autoload is not found. Please run \'composer install\' under application root directory.' From a3dfdd34cbe4209285c8bc785c5255406353e684 Mon Sep 17 00:00:00 2001 From: Wiard van Rij <vanrij@redkiwi.nl> Date: Fri, 26 Oct 2018 23:38:53 +0200 Subject: [PATCH 0851/1415] Updates php.ini sample --- php.ini.sample | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/php.ini.sample b/php.ini.sample index 8a7d13cf42b4e..17c8cb52abb70 100644 --- a/php.ini.sample +++ b/php.ini.sample @@ -1,32 +1,13 @@ ; Copyright © Magento, Inc. All rights reserved. ; See COPYING.txt for license details. -; This file is for CGI/FastCGI installations. -; Try copying it to php5.ini, if it doesn't work ; adjust memory limit +; Our detailed recommendations are: -memory_limit = 64M +; Compiling code or deploying static assets, 756M +; Installing and updating Magento components from Magento Marketplace, 2G +; Testing, ~3-4G -max_execution_time = 18000 +memory_limit = 2G -; disable automatic session start -; before autoload was initialized - -flag session.auto_start = off - -; enable resulting html compression - -zlib.output_compression = on - -; disable user agent verification to not break multiple image upload - -suhosin.session.cryptua = off - -; PHP for some reason ignores this setting in system php.ini -; and disables mcrypt if this line is missing in local php.ini - -extension=mcrypt.so - -; Disable PHP errors, notices and warnings output in production mode to prevent exposing sensitive information. - -display_errors = Off +; For further details refer to the technology stack requirements of your Magento installation \ No newline at end of file From e1a1c7b280bfbb6c8cbcaf205d0d7f7dbb882878 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 26 Oct 2018 16:50:31 -0500 Subject: [PATCH 0852/1415] ENGCOM-3292 catalog:images:resize total images count calculates incorrectly #18387: #18807 --- .../Magento/Catalog/Model/ResourceModel/Product/Image.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 5a290d5141e80..068580927b96a 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -12,6 +12,9 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; +/* + * Class for retrieval of all product images + */ class Image { /** @@ -73,6 +76,7 @@ public function getAllProductImages(): \Generator /** * Get the number of unique pictures of products + * * @return int */ public function getCountAllProductImages(): int @@ -88,6 +92,8 @@ public function getCountAllProductImages(): int } /** + * Return Select to fetch all products images + * * @return Select */ private function getVisibleImagesSelect(): Select From ba69bfec127bed8c39c7d9e7b73d10b54449b158 Mon Sep 17 00:00:00 2001 From: Wiard van Rij <wiard@outlook.com> Date: Sat, 27 Oct 2018 01:06:42 +0200 Subject: [PATCH 0853/1415] Fixes theme header logo and icon upload --- .../Theme/view/adminhtml/ui_component/design_config_form.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml index 8d4580f90c7b1..bc1f36222dd60 100644 --- a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml @@ -54,7 +54,7 @@ <collapsible>true</collapsible> <label translate="true">HTML Head</label> </settings> - <field name="head_shortcut_icon" formElement="fileUploader"> + <field name="head_shortcut_icon" formElement="imageUploader"> <settings> <notice translate="true">Not all browsers support all these formats!</notice> <label translate="true">Favicon Icon</label> @@ -151,7 +151,7 @@ <collapsible>true</collapsible> <label translate="true">Header</label> </settings> - <field name="header_logo_src" formElement="fileUploader"> + <field name="header_logo_src" formElement="imageUploader"> <settings> <label translate="true">Logo Image</label> <componentType>imageUploader</componentType> From cd97592752a02a6b3dcda3494f18557dcb93b6d3 Mon Sep 17 00:00:00 2001 From: speedy008 <kajal10395@gmail.com> Date: Sat, 27 Oct 2018 12:01:56 +0530 Subject: [PATCH 0854/1415] Downloadable products - Downloadable Information - Link design issue-#18854 --- .../adminhtml/Magento/backend/web/css/source/forms/_fields.less | 1 - 1 file changed, 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index b3e4a91180b96..3503abcc30468 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -520,7 +520,6 @@ & > .admin__field-label { #mix-grid .column(@field-label-grid__column, @field-grid__columns); - background: @color-white; cursor: pointer; left: 0; position: absolute; From cd243969b796e658edd844a3fe91d43cb308f72a Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Sat, 27 Oct 2018 15:42:40 +0530 Subject: [PATCH 0855/1415] #18192, Fixed rating issue website wise --- .../Review/Model/ResourceModel/Rating.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 3f54c17f6ff7c..5232a7fa33af4 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -34,12 +34,18 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $_logger; + /** + * @var \Magento\Framework\App\State + */ + protected $_state; + /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary + * @param \Magento\Framework\App\State * @param string $connectionName */ public function __construct( @@ -48,12 +54,14 @@ public function __construct( \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary, + \Magento\Framework\App\State $state, $connectionName = null ) { $this->moduleManager = $moduleManager; $this->_storeManager = $storeManager; $this->_logger = $logger; $this->_reviewSummary = $reviewSummary; + $this->_state = $state; parent::__construct($context, $connectionName); } @@ -425,9 +433,15 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); + if ($this->_state->getAreaCode() == "adminhtml") { + $currentStore = false; + } else { + $currentStore = $this->_storeManager->getStore()->setId(); + } + if ($onlyForCurrentStore) { foreach ($data as $row) { - if ($row['store_id'] == $this->_storeManager->getStore()->getId()) { + if ($row['store_id'] == $currentStore) { $object->addData($row); } } From cbbaf120f228d4499bdb7ead40a26f6a2f1c2330 Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Sat, 27 Oct 2018 18:51:56 +0530 Subject: [PATCH 0856/1415] updated code as per given instruction --- app/code/Magento/Review/Model/ResourceModel/Rating.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 5232a7fa33af4..79609a9afe41f 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -433,10 +433,9 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); + $currentStore = $this->_storeManager->getStore()->setId(); if ($this->_state->getAreaCode() == "adminhtml") { $currentStore = false; - } else { - $currentStore = $this->_storeManager->getStore()->setId(); } if ($onlyForCurrentStore) { From f6b0a2abfa0c95ce406a707a3ede42dbad5cfc22 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 27 Oct 2018 17:58:00 +0300 Subject: [PATCH 0857/1415] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix unit test - now it can test also not only full batches, but partial as well (139 images with batch size 100); --- .../Model/ResourceModel/Product/ImageTest.php | 170 +++++++++++------- 1 file changed, 109 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 9c783e237ab24..1866138cf16b6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -16,6 +16,11 @@ class ImageTest extends \PHPUnit\Framework\TestCase { + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + /** * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject */ @@ -31,41 +36,14 @@ class ImageTest extends \PHPUnit\Framework\TestCase */ protected $resourceMock; - /** - * @var Image - */ - protected $imageModel; - - /** - * @var int - */ - protected $imagesCount = 50; - - /** - * @var int - */ - protected $batchSize = 10; - protected function setUp(): void { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->connectionMock = $this->createMock(AdapterInterface::class); - $this->resourceMock = $this->createMock(ResourceConnection::class); $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); $this->resourceMock->method('getTableName')->willReturnArgument(0); - $this->generatorMock = $this->createMock(Generator::class); - - $this->imageModel = $objectManager->getObject( - Image::class, - [ - 'generator' => $this->generatorMock, - 'resourceConnection' => $this->resourceMock, - 'batchSize' => $this->batchSize - ] - ); } /** @@ -93,7 +71,11 @@ protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_M return $selectMock; } - public function testGetCountAllProductImages(): void + /** + * @param int $imagesCount + * @dataProvider dataProvider + */ + public function testGetCountAllProductImages(int $imagesCount): void { $selectMock = $this->getVisibleImagesSelectMock(); $selectMock->expects($this->exactly(2)) @@ -113,59 +95,125 @@ public function testGetCountAllProductImages(): void $this->connectionMock->expects($this->once()) ->method('fetchOne') ->with($selectMock) - ->willReturn($this->imagesCount); + ->willReturn($imagesCount); + + $imageModel = $this->objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock + ] + ); - $this->assertSame($this->imagesCount, $this->imageModel->getCountAllProductImages()); + $this->assertSame($imagesCount, $imageModel->getCountAllProductImages()); } - public function testGetAllProductImages(): void + /** + * @param int $imagesCount + * @param int $batchSize + * @dataProvider dataProvider + */ + public function testGetAllProductImages(int $imagesCount, int $batchSize): void { - $getBatchIteratorMock = function ($selectMock, $imagesCount, $batchSize): array { - $result = []; - $count = $imagesCount / $batchSize; - while ($count) { - $count--; - $result[$count] = $selectMock; - } - - return $result; - }; - - $getFetchResults = function ($batchSize): array { - $result = []; - $count = $batchSize; - while ($count) { - $count--; - $result[$count] = $count; - } - - return $result; - }; - $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); - $fetchResult = $getFetchResults($this->batchSize); - $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) + $batchCount = (int)ceil($imagesCount / $batchSize); + $fetchResultsCallback = $this->getFetchResultCallbackForBatches($imagesCount, $batchSize); + $this->connectionMock->expects($this->exactly($batchCount)) ->method('fetchAll') - ->willReturn($fetchResult); + ->will($this->returnCallback($fetchResultsCallback)); /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() ->getMock(); - $batchIteratorMock = $getBatchIteratorMock($selectMock, $this->imagesCount, $this->batchSize); $this->generatorMock->expects($this->once()) ->method('generate') ->with( 'value_id', $selectMock, - $this->batchSize, + $batchSize, \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR - )->willReturn($batchIteratorMock); + )->will($this->returnCallback($this->getBatchIteratorCallback($selectMock, $batchCount))); - $this->assertCount($this->imagesCount, $this->imageModel->getAllProductImages()); + $imageModel = $this->objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock, + 'batchSize' => $batchSize + ] + ); + + $this->assertCount($imagesCount, $imageModel->getAllProductImages()); + } + + /** + * @param int $imagesCount + * @param int $batchSize + * @return \Closure + */ + protected function getFetchResultCallbackForBatches(int $imagesCount, int $batchSize): \Closure + { + $fetchResultsCallback = function () use (&$imagesCount, $batchSize) { + $batchSize = ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; + $imagesCount -= $batchSize; + + $getFetchResults = function ($batchSize): array { + $result = []; + $count = $batchSize; + while ($count) { + $count--; + $result[$count] = $count; + } + + return $result; + }; + + return $getFetchResults($batchSize); + }; + + return $fetchResultsCallback; + } + + /** + * @param Select | \PHPUnit_Framework_MockObject_MockObject $selectMock + * @param int $batchCount + * @return \Closure + */ + protected function getBatchIteratorCallback( + \PHPUnit_Framework_MockObject_MockObject $selectMock, + int $batchCount + ): \Closure + { + $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { + $result = []; + $count = $batchCount; + while ($count) { + $count--; + $result[$count] = $selectMock; + } + + return $result; + }; + + return $getBatchIteratorCallback; + } + + /** + * Data Provider + * @return array + */ + public function dataProvider(): array + { + return [ + [300, 100], + [139, 100], + [67, 10], + [154, 47] + ]; } } From 546e7ce1c64fa8f0290eabd26070eac4837cb39e Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 27 Oct 2018 17:59:22 +0300 Subject: [PATCH 0858/1415] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix unit test - now it can test also not only full batches, but partial as well (139 images with batch size 100); --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1866138cf16b6..1a1eebf30f7f6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -210,10 +210,12 @@ protected function getBatchIteratorCallback( public function dataProvider(): array { return [ + [300, 300], [300, 100], [139, 100], [67, 10], - [154, 47] + [154, 47], + [0, 100] ]; } } From 84a48b431c6bd250466fff9c28a4053987e23f9c Mon Sep 17 00:00:00 2001 From: Wiard van Rij <wiard@outlook.com> Date: Sat, 27 Oct 2018 17:22:28 +0200 Subject: [PATCH 0859/1415] Removes php.ini.sample as its obsolete --- php.ini.sample | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 php.ini.sample diff --git a/php.ini.sample b/php.ini.sample deleted file mode 100644 index 17c8cb52abb70..0000000000000 --- a/php.ini.sample +++ /dev/null @@ -1,13 +0,0 @@ -; Copyright © Magento, Inc. All rights reserved. -; See COPYING.txt for license details. - -; adjust memory limit -; Our detailed recommendations are: - -; Compiling code or deploying static assets, 756M -; Installing and updating Magento components from Magento Marketplace, 2G -; Testing, ~3-4G - -memory_limit = 2G - -; For further details refer to the technology stack requirements of your Magento installation \ No newline at end of file From 4a283722cdb25ef030d8100bc20c3fa16c2e3d91 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Sat, 27 Oct 2018 19:36:06 +0300 Subject: [PATCH 0860/1415] resolve magento 2.3 update conflicts --- lib/internal/Magento/Framework/GraphQl/Config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index bfd8f330c6123..481d75ed35893 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -10,6 +10,7 @@ use Magento\Framework\Config\DataInterface; use Magento\Framework\GraphQl\Config\ConfigElementFactoryInterface; use Magento\Framework\GraphQl\Config\ConfigElementInterface; +use Magento\Framework\GraphQl\Query\Fields as QueryFields; /** * Provides access to typing information for a configured GraphQL schema. From b8d2663b72438fdda17dcd793c349681a5c784c6 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Sat, 27 Oct 2018 19:45:50 +0300 Subject: [PATCH 0861/1415] resolve magento 2.3 update conflicts --- lib/internal/Magento/Framework/GraphQl/Config.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 481d75ed35893..75b6c64e9d24f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -65,10 +65,12 @@ public function getConfigElement(string $configElementName) : ConfigElementInter } $fieldsInQuery = $this->queryFields->getFieldsUsedInQuery(); - if (isset($data['fields']) && !empty($fieldsInQuery)) { - foreach ($data['fields'] as $fieldName => $fieldConfig) { - if (!isset($fieldsInQuery[$fieldName])) { - unset($data['fields'][$fieldName]); + if (isset($data['fields'])) { + if (!empty($fieldsInQuery)) { + foreach ($data['fields'] as $fieldName => $fieldConfig) { + if (!isset($fieldsInQuery[$fieldName])) { + unset($data['fields'][$fieldName]); + } } } From d2f691dc08f48e1620a096648c94344f8ef189b3 Mon Sep 17 00:00:00 2001 From: Hugo <hugovk@users.noreply.github.com> Date: Sat, 27 Oct 2018 23:06:25 +0300 Subject: [PATCH 0862/1415] Fix spelling --- CHANGELOG.md | 8 ++++---- .../Controller/Adminhtml/Bulk/Details.php | 2 +- app/code/Magento/Backend/App/Request/BackendValidator.php | 2 +- .../Backend/Block/Widget/Grid/Column/Filter/Theme.php | 2 +- app/code/Magento/Backend/Block/Widget/Tabs.php | 2 +- .../Backend/Console/Command/AbstractCacheCommand.php | 2 +- .../Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php | 2 +- app/code/Magento/Backend/etc/adminhtml/system.xml | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc722b6d61b33..b86c7b79a0cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -157,7 +157,7 @@ To get detailed information about changes in Magento 2.1.0, please visit [Magent * Updated styles * Sample Data: * Improved sample data installation UX - * Updated sample data with Product Heros, color swatches, MAP and rule based product relations + * Updated sample data with Product Heroes, color swatches, MAP and rule based product relations * Improved sample data upgrade flow * Added the ability to log errors and set the error flag during sample data installation * Various improvements: @@ -2284,7 +2284,7 @@ Tests: * Fixed an issue where no results were found for Coupons reports * Fixed an issue with incremental Qty setting * Fixed an issue with allowing importing of negative weight values - * Fixed an issue with Inventory - Only X left Treshold being not dependent on Qty for Item's Status to Become Out of Stock + * Fixed an issue with Inventory - Only X left Threshold being not dependent on Qty for Item's Status to Become Out of Stock * Fixed an issue where the "Catalog Search Index index was rebuilt." message was displayed when reindexing the Catalog Search index * Search module: * Integrated the Search library to the advanced search functionality @@ -2706,7 +2706,7 @@ Tests: * Ability to support extensible service data objects * No Code Duplication in Root Templates * Fixed bugs: - * Persistance session application. Loggin out the customer + * Persistence session application. Logging out the customer * Placing the order with two terms and conditions * Saving of custom option by service catalogProductCustomOptionsWriteServiceV1 * Placing the order on frontend if enter in the street address line 1 and 2 255 symbols @@ -2965,7 +2965,7 @@ Tests: * Fixed an issue with incorrect items label for the cases when there are more than one item in the category * Fixed an issue when configurable product was out of stock in Google Shopping while being in stock in the Magento backend * Fixed an issue when swipe gesture in menu widget was not supported on mobile - * Fixed an issue when it was impossible to enter alpha-numeric zip code on the stage of estimating shipping and tax rates + * Fixed an issue when it was impossible to enter alphanumeric zip code on the stage of estimating shipping and tax rates * Fixed an issue when custom price was not applied when editing an order * Fixed an issue when items were not returned to stock after unsuccessful order was placed * Fixed an issue when error message appeared "Cannot save the credit memo” while creating credit memo diff --git a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php index 9e9dbd3dd67c5..5571c20f526cc 100644 --- a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php +++ b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php @@ -6,7 +6,7 @@ namespace Magento\AsynchronousOperations\Controller\Adminhtml\Bulk; /** - * Class View Opertion Details Controller + * Class View Operation Details Controller */ class Details extends \Magento\Backend\App\Action { diff --git a/app/code/Magento/Backend/App/Request/BackendValidator.php b/app/code/Magento/Backend/App/Request/BackendValidator.php index 878f9cb4dc4c1..eed4fbb643d3e 100644 --- a/app/code/Magento/Backend/App/Request/BackendValidator.php +++ b/app/code/Magento/Backend/App/Request/BackendValidator.php @@ -166,7 +166,7 @@ public function validate( ActionInterface $action ): void { if ($action instanceof AbstractAction) { - //Abstract Action has build-in validation. + //Abstract Action has built-in validation. if (!$action->_processUrlKeys()) { throw new InvalidRequestException($action->getResponse()); } diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php index d49ad2941146b..5db5dc59b4e5b 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php @@ -54,7 +54,7 @@ public function getHtml() } /** - * Retrieve options setted in column. + * Retrieve options set in column. * Or load if options was not set. * * @return array diff --git a/app/code/Magento/Backend/Block/Widget/Tabs.php b/app/code/Magento/Backend/Block/Widget/Tabs.php index 333904e398cf5..b390e2fa7d150 100644 --- a/app/code/Magento/Backend/Block/Widget/Tabs.php +++ b/app/code/Magento/Backend/Block/Widget/Tabs.php @@ -468,7 +468,7 @@ public function getTabContent($tab) } /** - * Mark tabs as dependant of each other + * Mark tabs as dependent of each other * Arbitrary number of tabs can be specified, but at least two * * @param string $tabOneId diff --git a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php index 70b01046f6afe..ecea5716f653d 100644 --- a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php +++ b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php @@ -17,7 +17,7 @@ abstract class AbstractCacheCommand extends Command { /** - * Input option bootsrap + * Input option bootstrap */ const INPUT_KEY_BOOTSTRAP = 'bootstrap'; diff --git a/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php b/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php index 260a38a481b3c..2b5f644e35977 100644 --- a/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php +++ b/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php @@ -168,6 +168,6 @@ public function testGetMenuGenericExceptionIsNotLogged() } catch (\Exception $e) { return; } - $this->fail("Generic \Exception was not throwed"); + $this->fail("Generic \Exception was not thrown"); } } diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index e061455acbe6b..cc12e138826ea 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -129,7 +129,7 @@ <field id="*/*/template_hints_storefront">1</field> <field id="*/*/template_hints_storefront_show_with_parameter">1</field> </depends> - <comment>Add the following paramater to the URL to show template hints ?templatehints=[parameter_value]</comment> + <comment>Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]</comment> </field> <field id="template_hints_admin" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Enabled Template Path Hints for Admin</label> From 3ba63db9b7fc2e1acad4d8d1c416399c471dfcea Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Sun, 28 Oct 2018 05:22:49 +0300 Subject: [PATCH 0863/1415] MAGETWO-95826: Zoomed part of images becomes distorted in case when image width/height ratio has ~2x difference - Changed the logic of calculating the coefficient of zoom --- lib/web/mage/gallery/gallery.less | 1 + lib/web/magnifier/magnifier.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/web/mage/gallery/gallery.less b/lib/web/mage/gallery/gallery.less index 3c35a772253bc..ebd6bdd003b81 100644 --- a/lib/web/mage/gallery/gallery.less +++ b/lib/web/mage/gallery/gallery.less @@ -764,6 +764,7 @@ max-width: inherit; position: absolute; top: 0; + object-fit: scale-down; } } diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index 150c8adf0b22b..a65fcd4669d80 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -542,7 +542,11 @@ showWrapper = true; bindEvents(eventType, thumb); data[idx].status = 2; - data[idx].zoom = largeObj.height / largeWrapper.height(); + if (largeObj.width > largeObj.height) { + data[idx].zoom = largeObj.width / largeWrapper.width(); + } else { + data[idx].zoom = largeObj.height / largeWrapper.height(); + } setThumbData(thumb, data[idx]); updateLensOnLoad(idx, thumb, largeObj, largeWrapper); } From afdcbb549e8b7faed858bfa9d9a94c03d180b657 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 28 Oct 2018 09:40:23 +0200 Subject: [PATCH 0864/1415] Remove duplicated selector --- .../luma/Magento_Checkout/web/css/source/module/_cart.less | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index 9e3a28be4c90e..cf7a909889584 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -628,9 +628,6 @@ &-item-details { padding-bottom: 35px; - } - - &-item-details { display: table-cell; vertical-align: top; white-space: normal; From dba69444975fab128a0764e4516af29331624e68 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 28 Oct 2018 11:42:31 +0200 Subject: [PATCH 0865/1415] Add missing unit test for WishlistSettings plugin --- .../Ui/DataProvider/WishlistSettingsTest.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php diff --git a/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php b/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php new file mode 100644 index 0000000000000..aa3b956e12153 --- /dev/null +++ b/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Test\Unit\Plugin\Ui\DataProvider; + +use Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider; +use Magento\Wishlist\Helper\Data; +use Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings; + +/** + * Covers \Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings + */ +class WishlistSettingsTest extends \PHPUnit\Framework\TestCase +{ + /** + * Testable Object + * + * @var WishlistSettings + */ + private $wishlistSettings; + + /** + * @var Data|\PHPUnit_Framework_MockObject_MockObject + */ + private $helperMock; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->helperMock = $this->createMock(Data::class); + $this->wishlistSettings = new WishlistSettings($this->helperMock); + } + + /** + * Test afterGetData method + * + * @return void + */ + public function testAfterGetData() + { + /** @var DataProvider|\PHPUnit_Framework_MockObject_MockObject $subjectMock */ + $subjectMock = $this->createMock(DataProvider::class); + $result = []; + $isAllow = true; + $this->helperMock->expects($this->once())->method('isAllow')->willReturn(true); + + $expected = ['allowWishlist' => $isAllow]; + $actual = $this->wishlistSettings->afterGetData($subjectMock, $result); + self::assertEquals($expected, $actual); + } +} From 22abbcbb6ac21b32ca25b93f55bba8079a2d56c9 Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Sun, 28 Oct 2018 15:37:38 +0530 Subject: [PATCH 0866/1415] fixed - can't import external http to https redirecting images by default csv import --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index 236585fa61384..e43f35b072f1d 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -36,6 +36,11 @@ public function isExists($path) $status = $headers[0]; + /* Handling 302 redirection */ + if (strpos($status, '302 Found') !== false && isset($headers[1])) { + $status = $headers[1]; + } + if (strpos($status, '200 OK') === false) { $result = false; } else { From 8720e236d553c09afca227eb0d2e623463be0075 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Sun, 28 Oct 2018 12:35:43 +0100 Subject: [PATCH 0867/1415] Bump MFTF version --- composer.json | 2 +- composer.lock | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index e2a646275d98b..7601bb34bb6ad 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.6", + "magento/magento2-functional-testing-framework": "2.3.9.x-dev", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 2550f70f0be81..2ebd20b84852a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18982aa4d36bcfd22cf073dfb578efdb", + "content-hash": "d9acbe01fc68b7e28ba36a164d59439f", "packages": [ { "name": "braintree/braintree_php", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.6", + "version": "2.3.9.x-dev", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce" + "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/57021e12ded213a0031c4d4f6293e06ce6f144ce", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9885925ea741d0b0eede35be09a45b62d9ef7c84", + "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-09-05T15:17:20+00:00" + "time": "2018-10-28T11:19:53+00:00" }, { "name": "moontoast/math", @@ -9041,6 +9041,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "magento/magento2-functional-testing-framework": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, From b0240f1588f6e4458a59d01e70c5d8d51d98aca4 Mon Sep 17 00:00:00 2001 From: Denis Papec <denis.papec@gmail.com> Date: Sun, 28 Oct 2018 20:04:33 +0000 Subject: [PATCH 0868/1415] Clean Up Magento/ImportExport/Controller/Adminhtml/History/Download --- .../ImportExport/Controller/Adminhtml/History/Download.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php index e490ee4018376..4dda5ebc4a310 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php @@ -15,6 +15,11 @@ class Download extends \Magento\ImportExport\Controller\Adminhtml\History */ protected $resultRawFactory; + /** + * @var \Magento\Framework\App\Response\Http\FileFactory + */ + private $fileFactory; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory From 0be96a84e22ae552f3aff29b5fab3df94a60c384 Mon Sep 17 00:00:00 2001 From: Denis Papec <denis.papec@gmail.com> Date: Sun, 28 Oct 2018 20:50:05 +0000 Subject: [PATCH 0869/1415] Removed parameter from \Magento\ImportExport\Model\Source\Import\Behavior\Custom constructor --- .../Test/Unit/Model/Source/Import/Behavior/CustomTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php index d073f3866bfe6..73b4f10b3b0f0 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php @@ -32,7 +32,7 @@ class CustomTest extends \Magento\ImportExport\Test\Unit\Model\Source\Import\Abs protected function setUp() { parent::setUp(); - $this->_model = new \Magento\ImportExport\Model\Source\Import\Behavior\Custom([]); + $this->_model = new \Magento\ImportExport\Model\Source\Import\Behavior\Custom(); } /** From dd8625e19b5e50d49f28a645a2a89b680be9bef6 Mon Sep 17 00:00:00 2001 From: Denis Papec <denis.papec@gmail.com> Date: Sun, 28 Oct 2018 21:02:49 +0000 Subject: [PATCH 0870/1415] Define $session propery --- app/code/Magento/ImportExport/Model/History.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/History.php b/app/code/Magento/ImportExport/Model/History.php index 3138f150d5fc5..617ca11e18f22 100644 --- a/app/code/Magento/ImportExport/Model/History.php +++ b/app/code/Magento/ImportExport/Model/History.php @@ -42,6 +42,11 @@ class History extends \Magento\Framework\Model\AbstractModel */ protected $reportHelper; + /** + * @var \Magento\Backend\Model\Auth\Session + */ + private $session; + /** * Class constructor * From a9622b53819f7f5d06b95f6c6922dcdb4c5add84 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Sun, 28 Oct 2018 18:28:44 +0100 Subject: [PATCH 0871/1415] Bump MFTF version - skip failing test --- .../Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 +++ composer.json | 2 +- composer.lock | 5 ++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 11bf03c1d5ee9..4b3d5c9258785 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,6 +17,9 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> + <skip> + <issueId value="MC-5371" /> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/composer.json b/composer.json index 7601bb34bb6ad..770e93fd17e70 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.9.x-dev", + "magento/magento2-functional-testing-framework": "2.3.9", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 2ebd20b84852a..43777f5c94864 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d9acbe01fc68b7e28ba36a164d59439f", + "content-hash": "b6dc9e7403d5f8b1c9d870e0ca0c8a12", "packages": [ { "name": "braintree/braintree_php", @@ -6351,7 +6351,7 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.9.x-dev", + "version": "2.3.9", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", @@ -9041,7 +9041,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "magento/magento2-functional-testing-framework": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, From 611969d9a56905613aefb981c8cd4be7efc24330 Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Mon, 29 Oct 2018 11:04:31 +0530 Subject: [PATCH 0872/1415] code modification --- app/code/Magento/Review/Model/ResourceModel/Rating.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 79609a9afe41f..debaf61c4dd4b 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -433,10 +433,7 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); - $currentStore = $this->_storeManager->getStore()->setId(); - if ($this->_state->getAreaCode() == "adminhtml") { - $currentStore = false; - } + $currentStore = ($this->_state->getAreaCode() == "adminhtml") ? false : $this->_storeManager->getStore()->getId(); if ($onlyForCurrentStore) { foreach ($data as $row) { From 48446c63090fd2d20c24ba2dede135001e600515 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 29 Oct 2018 09:24:32 +0200 Subject: [PATCH 0873/1415] ENGCOM-3161: [Forwardport] #4942 and bundle checkbox bug #18520. Fix functional tests. --- .../Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml index 4945308c26c4a..58806126aee30 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml @@ -95,7 +95,7 @@ <waitForPageLoad stepKey="waitForStorefront2"/> <!-- Check second one option to choose both of the options on the storefront --> - <click selector="{{StorefrontBundledSection.bundleOption('1','2')}}" stepKey="selectSecondBundleOption2"/> + <click selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}" stepKey="selectSecondBundleOption2"/> <waitForPageLoad stepKey="waitForPriceUpdate3"/> <see stepKey="seeDoublePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="2,460.00"/> From 7ca0246619db085938bc31e949c35124479e5c5e Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 29 Oct 2018 13:53:26 +0200 Subject: [PATCH 0874/1415] ENGCOM-3184: Fixed functional test. --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 8999b03b647a3..988d61986e3d2 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); + $productData['special_from_date'] = $this->getDateTimeFilter()->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 8a64a2991dc979ade0ec0907a9de29a022f0e857 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Mon, 29 Oct 2018 14:43:57 +0200 Subject: [PATCH 0875/1415] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - fixed - added test --- .../Integration/Plugin/Model/AdminUser.php | 8 +- .../Adminhtml/User/Role/SaveRole.php | 65 +++++++++++----- .../Adminhtml/User/Role/SaveRoleTest.php | 77 +++++++++++++++++++ .../User/_files/two_users_with_role.php | 52 +++++++++++++ .../_files/two_users_with_role_rollback.php | 21 +++++ 5 files changed, 201 insertions(+), 22 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php create mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php create mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php diff --git a/app/code/Magento/Integration/Plugin/Model/AdminUser.php b/app/code/Magento/Integration/Plugin/Model/AdminUser.php index df3766250caa7..7b2fa1981bce3 100644 --- a/app/code/Magento/Integration/Plugin/Model/AdminUser.php +++ b/app/code/Magento/Integration/Plugin/Model/AdminUser.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Integration\Plugin\Model; use Magento\Integration\Model\AdminTokenService; @@ -31,14 +32,15 @@ public function __construct( * * @param \Magento\User\Model\User $subject * @param \Magento\Framework\DataObject $object - * @return $this + * @return \Magento\User\Model\User + * @throws \Magento\Framework\Exception\LocalizedException */ public function afterSave( \Magento\User\Model\User $subject, \Magento\Framework\DataObject $object - ) { + ): \Magento\User\Model\User { $isActive = $object->getIsActive(); - if (isset($isActive) && $isActive == 0) { + if ($isActive !== null && $isActive == 0) { $this->adminTokenService->revokeAdminAccessToken($object->getId()); } return $subject; diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index acd3430f5c25a..97ecb778b8cb1 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -11,6 +11,7 @@ use Magento\Authorization\Model\Acl\Role\Group as RoleGroup; use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\State\UserLockedException; use Magento\Security\Model\SecurityCookie; @@ -77,10 +78,8 @@ public function execute() $rid = $this->getRequest()->getParam('role_id', false); $resource = $this->getRequest()->getParam('resource', false); - $roleUsers = $this->getRequest()->getParam('in_role_user', null); - parse_str($roleUsers, $roleUsers); - $roleUsers = array_keys($roleUsers); - + $oldRoleUsers = $this->parseRequestVariable('in_role_user_old'); + $roleUsers = $this->parseRequestVariable('in_role_user'); $isAll = $this->getRequest()->getParam('all'); if ($isAll) { $resource = [$this->_objectManager->get(\Magento\Framework\Acl\RootResource::class)->getId()]; @@ -106,13 +105,9 @@ public function execute() $role->save(); $this->_rulesFactory->create()->setRoleId($role->getId())->setResources($resource)->saveRel(); - - $this->processPreviousUsers($role); - - foreach ($roleUsers as $nRuid) { - $this->_addUserToRole($nRuid, $role->getId()); - } - $this->messageManager->addSuccess(__('You saved the role.')); + $this->processPreviousUsers($role, $oldRoleUsers); + $this->processCurrentUsers($role, $roleUsers); + $this->messageManager->addSuccessMessage(__('You saved the role.')); } catch (UserLockedException $e) { $this->_auth->logout(); $this->getSecurityCookie()->setLogoutReasonCookie( @@ -120,14 +115,14 @@ public function execute() ); return $resultRedirect->setPath('*'); } catch (\Magento\Framework\Exception\AuthenticationException $e) { - $this->messageManager->addError( + $this->messageManager->addErrorMessage( __('The password entered for the current user is invalid. Verify the password and try again.') ); return $this->saveDataToSessionAndRedirect($role, $this->getRequest()->getPostValue(), $resultRedirect); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { - $this->messageManager->addError(__('An error occurred while saving this role.')); + $this->messageManager->addErrorMessage(__('An error occurred while saving this role.')); } return $resultRedirect->setPath('*/*/'); @@ -151,19 +146,30 @@ protected function validateUser() return $this; } + /** + * Parse request value from string + * + * @param string $paramName + * @return array + */ + private function parseRequestVariable($paramName): array + { + $value = $this->getRequest()->getParam($paramName, null); + parse_str($value, $value); + $value = array_keys($value); + return $value; + } + /** * Process previous users * * @param \Magento\Authorization\Model\Role $role + * @param array $oldRoleUsers * @return $this * @throws \Exception */ - protected function processPreviousUsers(\Magento\Authorization\Model\Role $role) + protected function processPreviousUsers(\Magento\Authorization\Model\Role $role, array $oldRoleUsers): self { - $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old'); - parse_str($oldRoleUsers, $oldRoleUsers); - $oldRoleUsers = array_keys($oldRoleUsers); - foreach ($oldRoleUsers as $oUid) { $this->_deleteUserFromRole($oUid, $role->getId()); } @@ -171,12 +177,33 @@ protected function processPreviousUsers(\Magento\Authorization\Model\Role $role) return $this; } + /** + * Processes users to be assigned to roles + * + * @param \Magento\Authorization\Model\Role $role + * @param array $roleUsers + * @return $this + */ + private function processCurrentUsers(\Magento\Authorization\Model\Role $role, array $roleUsers): self + { + foreach ($roleUsers as $nRuid) { + try { + $this->_addUserToRole($nRuid, $role->getId()); + } catch (LocalizedException $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + } + } + + return $this; + } + /** * Assign user to role * * @param int $userId * @param int $roleId * @return bool + * @throws LocalizedException */ protected function _addUserToRole($userId, $roleId) { diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php new file mode 100644 index 0000000000000..50b28e2bac0a9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\User\Controller\Adminhtml\User\Role; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\Message\MessageInterface; +use Magento\User\Controller\Adminhtml\User\Role\SaveRole; + +/** + * Test class for \Magento\User\Controller\Adminhtml\User\Role. + * + * @magentoAppArea adminhtml + */ +class SaveRoleTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * Test execute method + * + * @magentoDataFixture Magento/User/_files/two_users_with_role.php + * @magentoDbIsolation disabled + */ + public function testExecute() + { + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\User\Model\User $currentAdmin */ + $currentAdmin = $objectManager->create(User::class) + ->loadByUsername('user'); + /** @var \Magento\Backend\Model\Auth\Session $authSession */ + $authSession = $objectManager->create(Session::class); + $authSession->setUser($currentAdmin); + $user1Id = $objectManager->create(User::class) + ->loadByUsername('johnAdmin')->getId(); + $user2Id = $objectManager->create(User::class) + ->loadByUsername('annAdmin')->getId(); + + /** @var \Magento\Authorization\Model\RoleFactory $roleFactory */ + $roleFactory = $objectManager->create(\Magento\Authorization\Model\RoleFactory::class); + $role = $roleFactory->create()->load(1); + + /** @var \Magento\AdminGws\Model\Role $gwsRole */ + $gwsRole = $objectManager->get(\Magento\AdminGws\Model\Role::class); + $gwsRole->setAdminRole($role); + $gwsRole->setStoreGroupIds([1]); + + $params = [ + 'role_id' => 1, + 'in_role_user_old'=> $user1Id . '=true&' . $user2Id . '=true', + 'in_role_user'=> $user1Id . '=true&' . $user2Id . '=true', + 'all' => 1, + 'current_password' => 'password1', + 'rolename' => 'Administrators', + ]; + + $post = [ + 'gws_is_all' => 1, + 'gws_store_groups' => ['1'], + ]; + + $this->getRequest()->setParams($params); + $this->getRequest()->setPostValue($post); + + $model = $objectManager->create(SaveRole::class); + $model->execute(); + $this->assertSessionMessages( + $this->equalTo(['You saved the role.']), + MessageInterface::TYPE_SUCCESS + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php new file mode 100644 index 0000000000000..3b9e9b66427eb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; + +/** + * Create an admin user with an assigned role + */ + +$objectManager = Bootstrap::getObjectManager(); + +/** @var \Magento\User\Model\ResourceModel\User $model */ +$userResource = $objectManager->create(\Magento\User\Model\ResourceModel\User::class); + +/** @var $user User */ +$user = $objectManager->create(User::class); +$user->setFirstname("John") + ->setIsActive(true) + ->setLastname("Doe") + ->setUsername('johnAdmin') + ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) + ->setEmail('JohnadminUser@example.com') + ->setRoleType('G') + ->setResourceId('Magento_Backend::all') + ->setPrivileges("") + ->setAssertId(0) + ->setRoleId(1) + ->setPermission('allow'); + +$userResource->save($user); + +/** @var $user User */ +$user = $objectManager->create(User::class); +$user->setFirstname("Ann") + ->setIsActive(true) + ->setLastname("Doe") + ->setUsername('annAdmin') + ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) + ->setEmail('JaneadminUser@example.com') + ->setRoleType('G') + ->setResourceId('Magento_Backend::all') + ->setPrivileges("") + ->setAssertId(0) + ->setRoleId(1) + ->setPermission('allow'); + +$userResource->save($user); diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php new file mode 100644 index 0000000000000..7d7d85c71a994 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; + +/** + * Create an admin user with an assigned role + */ + +/** @var $user User */ +$user = Bootstrap::getObjectManager()->create(User::class); +$user->loadByUsername('johnAdmin')->delete(); + +/** @var $user User */ +$user = Bootstrap::getObjectManager()->create(User::class); +$user->loadByUsername('annAdmin')->delete(); From 9c617290cf0ae20a2d7b74cb9b2f4dce9204f200 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 13:45:45 +0000 Subject: [PATCH 0876/1415] magento-engcom/import-export-improvements#54: update codee based on phpcs guidelines --- .../Magento/ImportExport/Model/Import/Entity/AbstractEntity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index 74e2c5626236c..1fc3257ff2c1e 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -830,6 +830,8 @@ public function validateData() } /** + * Get error aggregator object + * * @return ProcessingErrorAggregatorInterface */ public function getErrorAggregator() From 6b2a6d0cf51ac5046408ea599426feb468c10510 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 13:51:09 +0000 Subject: [PATCH 0877/1415] magento-engcom/import-export-improvements#93: update based on phpcs ruleset --- .../Magento/ImportExport/Controller/Adminhtml/Import/Start.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 06b69c512a194..e850f6af86cf9 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -96,7 +96,7 @@ public function execute() $noticeHtml = $this->historyModel->getSummary(); - if($this->historyModel->getErrorFile()) { + if ($this->historyModel->getErrorFile()) { $noticeHtml .= '<div class="import-error-wrapper">' . __('Only the first 100 errors are shown. ') . '<a href="' . $this->createDownloadUrlImportHistoryFile($this->historyModel->getErrorFile()) From b552406f8e1bd7cc5b33b37bdc4e8b757883e0de Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 16:45:18 +0000 Subject: [PATCH 0878/1415] magento-engcom/import-export-improvements#134: update file from phpcs feedback --- .../BundleImportExport/Model/Import/Product/Type/Bundle.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php index 77d331a8b5696..81a47d72602b7 100644 --- a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php +++ b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php @@ -20,6 +20,7 @@ /** * Class Bundle + * * @package Magento\BundleImportExport\Model\Import\Product\Type * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -349,6 +350,8 @@ protected function populateSelectionTemplate($selection, $optionId, $parentId, $ } /** + * Deprecated method for retrieving mapping between skus and products. + * * @deprecated Misspelled method * @see retrieveProductsByCachedSkus */ @@ -600,6 +603,7 @@ protected function insertOptions() /** * Populate array for insert option values + * * @param array $optionIds * @return array */ From 22594bd6cf742210b2d3b8483702510b25d7fa14 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 29 Oct 2018 11:47:50 -0500 Subject: [PATCH 0879/1415] MAGETWO-95883: [FT] [Klarna] Failed functional tests --- .../Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - .../Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - .../Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - 3 files changed, 3 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml index e4c0dce0c5b10..18aedfa97f9eb 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <checkbox> <selector>div[contains(@class,"field choice") and label[contains(.,"%product_name%")]]//input</selector> <strategy>xpath</strategy> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml index a66753c2adf23..f7bd155fd2d51 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <attribute> <selector>//div[@class="product-options"]//label[.="%s"]//following-sibling::*//select</selector> <strategy>xpath</strategy> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml index 7a7a6d2124cb7..2f721f05f5ee8 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <link> <selector>//*[@id="downloadable-links-list"]/*[contains(.,"%link_name%")]//input</selector> <strategy>xpath</strategy> From c8e0a4f796123b3b4b155bf97a6933d89e0794ae Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 29 Oct 2018 11:48:29 -0500 Subject: [PATCH 0880/1415] MAGETWO-95212: block call to getCurrentUrl method is returning ajax request value - Product list widget can be configured to use a base url for add to cart buttons - Added test section for this scenario --- .../Catalog/Block/Product/AbstractProduct.php | 8 +++++- .../Block/Product/ProductsList.php | 28 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php index 4102c82a0a316..fb45246ea3464 100644 --- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php @@ -125,6 +125,7 @@ public function __construct(\Magento\Catalog\Block\Product\Context $context, arr /** * Retrieve url for add product to cart + * * Will return product view page URL if product has required options * * @param \Magento\Catalog\Model\Product $product @@ -265,6 +266,7 @@ public function getProductUrl($product, $additional = []) if (!isset($additional['_escape'])) { $additional['_escape'] = true; } + $additional['useUencPlaceholder'] = true; return $product->getUrlModel()->getUrl($product, $additional); } @@ -473,7 +475,9 @@ public function getProductDetailsHtml(\Magento\Catalog\Model\Product $product) } /** - * @param null $type + * Get the renderer that will be used to render the details block + * + * @param string|null $type * @return bool|\Magento\Framework\View\Element\AbstractBlock */ public function getDetailsRenderer($type = null) @@ -489,6 +493,8 @@ public function getDetailsRenderer($type = null) } /** + * Return the list of details + * * @return \Magento\Framework\View\Element\RendererList */ protected function getDetailsRendererList() diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index ed17634aa48c1..2681381c5d771 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -11,11 +11,13 @@ use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Serialize\Serializer\Json; use Magento\Widget\Block\BlockInterface; +use Magento\Framework\Url\EncoderInterface; /** * Catalog Products List widget block * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implements BlockInterface, IdentityInterface { @@ -94,6 +96,11 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem */ private $json; + /** + * @var \Magento\Framework\Url\EncoderInterface|null + */ + private $urlEncoder; + /** * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory @@ -104,6 +111,7 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem * @param \Magento\Widget\Helper\Conditions $conditionsHelper * @param array $data * @param Json|null $json + * @param \Magento\Framework\Url\EncoderInterface|null $urlEncoder */ public function __construct( \Magento\Catalog\Block\Product\Context $context, @@ -114,7 +122,8 @@ public function __construct( \Magento\CatalogWidget\Model\Rule $rule, \Magento\Widget\Helper\Conditions $conditionsHelper, array $data = [], - Json $json = null + Json $json = null, + EncoderInterface $urlEncoder = null ) { $this->productCollectionFactory = $productCollectionFactory; $this->catalogProductVisibility = $catalogProductVisibility; @@ -123,6 +132,7 @@ public function __construct( $this->rule = $rule; $this->conditionsHelper = $conditionsHelper; $this->json = $json ?: ObjectManager::getInstance()->get(Json::class); + $this->urlEncoder = $urlEncoder ?: ObjectManager::getInstance()->get(EncoderInterface::class); parent::__construct( $context, $data @@ -417,4 +427,20 @@ private function getPriceCurrency() } return $this->priceCurrency; } + + /** + * @inheritdoc + */ + public function getAddToCartUrl($product, $additional = []) + { + $requestingPageUrl = $this->getRequest()->getParam('requesting_page_url'); + + if (!empty($requestingPageUrl)) { + $additional['useUencPlaceholder'] = true; + $url = parent::getAddToCartUrl($product, $additional); + return str_replace('%25uenc%25', $this->urlEncoder->encode($requestingPageUrl), $url); + } + + return parent::getAddToCartUrl($product, $additional); + } } From f38a4fc3e78208a8d63e545bffe81c444a1e09a8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 29 Oct 2018 12:58:56 -0500 Subject: [PATCH 0881/1415] ENGCOM-3292: catalog:images:resize total images count calculates incorrectly #18387: #18807 --- app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 068580927b96a..77f67480619e0 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -12,7 +12,7 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; -/* +/** * Class for retrieval of all product images */ class Image From 9043bc9c755268c63db304a499492867d4c91379 Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 29 Oct 2018 19:59:00 +0200 Subject: [PATCH 0882/1415] magento/graphql-ce#41: Updated global composer.json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 3f8f0a033c893..ab29199251172 100644 --- a/composer.json +++ b/composer.json @@ -201,6 +201,7 @@ "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": "*", From 12f839644f71915e165a2804f505a727cd477cfc Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 29 Oct 2018 12:59:37 -0500 Subject: [PATCH 0883/1415] ENGCOM-3292: catalog:images:resize total images count calculates incorrectly #18387: #18807 --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1a1eebf30f7f6..cf24998590ae8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -187,8 +187,7 @@ protected function getFetchResultCallbackForBatches(int $imagesCount, int $batch protected function getBatchIteratorCallback( \PHPUnit_Framework_MockObject_MockObject $selectMock, int $batchCount - ): \Closure - { + ): \Closure { $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { $result = []; $count = $batchCount; From e1ac7ceef44e6e5b7db99488850f9dfd8d20e65e Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 29 Oct 2018 13:14:19 -0500 Subject: [PATCH 0884/1415] MAGETWO-95876: Fatal Error during customer login --- .../Magento/Customer/Model/Authentication.php | 4 +-- .../Customer/Controller/AccountTest.php | 29 ++++++++++++++++ .../Customer/_files/customer_no_password.php | 33 +++++++++++++++++++ .../Framework/Encryption/Encryptor.php | 6 +++- 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/customer_no_password.php diff --git a/app/code/Magento/Customer/Model/Authentication.php b/app/code/Magento/Customer/Model/Authentication.php index 0967f1a0189e3..edd98bf9bee0e 100644 --- a/app/code/Magento/Customer/Model/Authentication.php +++ b/app/code/Magento/Customer/Model/Authentication.php @@ -161,12 +161,12 @@ public function isLocked($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function authenticate($customerId, $password) { $customerSecure = $this->customerRegistry->retrieveSecureData($customerId); - $hash = $customerSecure->getPasswordHash(); + $hash = $customerSecure->getPasswordHash() ?? ''; if (!$this->encryptor->validateHash($password, $hash)) { $this->processAuthenticationFailure($customerId); if ($this->isLocked($customerId)) { diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index ed40abd26c0b6..c94948e23ab4d 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -56,6 +56,35 @@ public function testIndexAction() $this->assertContains('Green str, 67', $body); } + /** + * @magentoDataFixture Magento/Customer/_files/customer_no_password.php + */ + public function testLoginWithIncorrectPassword() + { + $expectedMessage = 'The account sign-in was incorrect or your account is disabled temporarily. ' + . 'Please wait and try again later.'; + $this->getRequest() + ->setMethod('POST') + ->setPostValue( + [ + 'login' => [ + 'username' => 'customer@example.com', + 'password' => '123123q' + ] + ] + ); + + $this->dispatch('customer/account/loginPost'); + $this->assertRedirect($this->stringContains('customer/account/login')); + $this->assertSessionMessages( + $this->equalTo( + [ + $expectedMessage + ] + ) + ); + } + /** * Test sign up form displaying. */ diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_no_password.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_no_password.php new file mode 100644 index 0000000000000..0340f0f841ca6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_no_password.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +use Magento\Customer\Model\CustomerRegistry; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** @var $repository \Magento\Customer\Api\CustomerRepositoryInterface */ +$repository = $objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); +$customer = $objectManager->create(\Magento\Customer\Model\Customer::class); +/** @var CustomerRegistry $customerRegistry */ +$customerRegistry = $objectManager->get(CustomerRegistry::class); +/** @var Magento\Customer\Model\Customer $customer */ +$customer->setWebsiteId(1) + ->setId(1) + ->setEmail('customer@example.com') + ->setGroupId(1) + ->setStoreId(1) + ->setIsActive(1) + ->setPrefix('Mr.') + ->setFirstname('John') + ->setMiddlename('A') + ->setLastname('Smith') + ->setSuffix('Esq.') + ->setDefaultBilling(1) + ->setDefaultShipping(1) + ->setTaxvat('12') + ->setGender(0); + +$customer->isObjectNew(true); +$customer->save(); +$customerRegistry->remove($customer->getId()); diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index f7d52d5474ad7..919e710d4f2de 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -263,7 +263,11 @@ private function getPasswordSalt() */ private function getPasswordVersion() { - return array_map('intval', explode(self::DELIMITER, $this->passwordHashMap[self::PASSWORD_VERSION])); + return array_map('intval', explode( + self::DELIMITER, + (string)$this->passwordHashMap[self::PASSWORD_VERSION] + ) + ); } /** From 659e5ffc37c226e21c896a2db4a7e5fbafff8d75 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 29 Oct 2018 13:37:04 -0500 Subject: [PATCH 0885/1415] MAGETWO-95212: block call to getCurrentUrl method is returning ajax request value - Added missing section --- .../Test/Mftf/Section/ProductListWidgetSection.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml new file mode 100644 index 0000000000000..4e79334a94cd3 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="ProductListWidgetSection"> + <element name="AddToCartByName" type="button" selector="//*[contains(@class,'product-item-info')][descendant::a[contains(text(), '{{arg1}}')]]//button[contains(@class,'tocart')]" parameterized="true"/> + </section> +</sections> From 95c3579b9e2b2e6c732d676155953aff3de05702 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 29 Oct 2018 13:54:28 -0500 Subject: [PATCH 0886/1415] MAGETWO-95977: Magento 2.3.0-beta18: ReflectionException on Backend -> Stores -> Configuration -> Services -> OAuth page --- .../Integration/etc/adminhtml/system.xml | 2 +- .../System/Config/OauthSectionTest.php | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 5abec8efbfdd6..fe80fe105493a 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -54,7 +54,7 @@ <label>Maximum Login Failures to Lock Out Account</label> <comment>Maximum Number of authentication failures to lock out account.</comment> </field> - <field id="timeout" translate="label" type="text comment" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="timeout" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Lockout Time (seconds)</label> <comment>Period of time in seconds after which account will be unlocked.</comment> </field> diff --git a/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php b/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php new file mode 100644 index 0000000000000..ac5d8005180b4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\Integration\Block\Adminhtml\System\Config; + +class OauthSectionTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * Checks that OAuth Section in the system config is loaded + */ + public function testOAuthSection() + { + $this->dispatch('backend/admin/system_config/edit/section/oauth/'); + $body = $this->getResponse()->getBody(); + $this->assertContains('id="oauth_access_token_lifetime-head"', $body); + $this->assertContains('id="oauth_cleanup-head"', $body); + $this->assertContains('id="oauth_consumer-head"', $body); + $this->assertContains('id="oauth_authentication_lock-head"', $body); + } +} From 4c25f0e9fbac64044a4bf3cdda17362bac23ac6c Mon Sep 17 00:00:00 2001 From: ayaz <ayaz.mittaqi024@webkul.com> Date: Tue, 30 Oct 2018 10:58:20 +0530 Subject: [PATCH 0887/1415] issue #18931 fixed. --- app/code/Magento/Catalog/i18n/en_US.csv | 3 ++- app/code/Magento/Checkout/i18n/en_US.csv | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index f2a3ab8f83f24..06c072276f084 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -808,4 +808,5 @@ Details,Details "Product Name or SKU", "Product Name or SKU" "Start typing to find products", "Start typing to find products" "Product with ID: (%1) doesn't exist", "Product with ID: (%1) doesn't exist" -"Category with ID: (%1) doesn't exist", "Category with ID: (%1) doesn't exist" \ No newline at end of file +"Category with ID: (%1) doesn't exist", "Category with ID: (%1) doesn't exist" +"You added product %1 to the <a href=""%2"">comparison list</a>.","You added product %1 to the <a href=""%2"">comparison list</a>." \ No newline at end of file diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index a6ea2c13579a7..7f2f0b4390321 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -182,3 +182,4 @@ Payment,Payment "Items in Cart","Items in Cart" "Close","Close" "Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart" +"You added %1 to your <a href=""%2"">shopping cart</a>.","You added %1 to your <a href=""%2"">shopping cart</a>." \ No newline at end of file From 774164c2ae589e45fd3bdfcf09a6de4c6b0cba1a Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Tue, 30 Oct 2018 11:30:19 +0530 Subject: [PATCH 0888/1415] core modified as per instructions --- .../Magento/Review/Model/ResourceModel/Rating.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index debaf61c4dd4b..df138ed8173be 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -34,18 +34,12 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $_logger; - /** - * @var \Magento\Framework\App\State - */ - protected $_state; - /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary - * @param \Magento\Framework\App\State * @param string $connectionName */ public function __construct( @@ -54,14 +48,12 @@ public function __construct( \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary, - \Magento\Framework\App\State $state, $connectionName = null ) { $this->moduleManager = $moduleManager; $this->_storeManager = $storeManager; $this->_logger = $logger; $this->_reviewSummary = $reviewSummary; - $this->_state = $state; parent::__construct($context, $connectionName); } @@ -433,11 +425,11 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); - $currentStore = ($this->_state->getAreaCode() == "adminhtml") ? false : $this->_storeManager->getStore()->getId(); + $currentStore = ($this->_storeManager->isSingleStoreMode()) ? $this->_storeManager->getStore()->getId() : NULL ; if ($onlyForCurrentStore) { foreach ($data as $row) { - if ($row['store_id'] == $currentStore) { + if (!$row['store_id'] == NULL) { $object->addData($row); } } From 2ea37a87e250209d28d92b0987daddf068cfaf9c Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Tue, 30 Oct 2018 12:13:38 +0530 Subject: [PATCH 0889/1415] updated code --- app/code/Magento/Review/Model/ResourceModel/Rating.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index df138ed8173be..77a9727bd849e 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -429,7 +429,7 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) if ($onlyForCurrentStore) { foreach ($data as $row) { - if (!$row['store_id'] == NULL) { + if (!$row['store_id'] == $currentStore) { $object->addData($row); } } From ac8ca8b619372d1bdbdb9f9b66b6a19907df3a22 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Oct 2018 09:42:00 +0200 Subject: [PATCH 0890/1415] magento-engcom/magento2ce#2287: Code style fixes --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 7 ++++++- .../Unit/Model/Order/Creditmemo/Total/DiscountTest.php | 2 +- .../luma/Magento_Checkout/web/css/source/module/_cart.less | 2 +- .../frontend/js/model/cart/estimate-service.test.js | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 749a12f7d8b55..06bfbcf24daac 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -5,9 +5,14 @@ */ namespace Magento\Sales\Model\Order\Creditmemo\Total; +/** + * Discount total calculator + */ class Discount extends AbstractTotal { /** + * Collect discount + * * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @throws \Magento\Framework\Exception\LocalizedException @@ -34,7 +39,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) */ if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.", []) + __("You can not refund shipping if there is no shipping amount.") ); } if ($baseShippingAmount) { diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php index a9a859ea1b5d6..8a45aa8c7958e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php @@ -292,7 +292,7 @@ public function testCollectNonZeroShipping() ->method('getBaseShippingDiscountAmount'); $this->orderMock->expects($this->once()) ->method('getBaseShippingAmount') - ->willReturn( '0.0000'); + ->willReturn('0.0000'); $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); } } diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index cf7a909889584..58582d344e75a 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -627,8 +627,8 @@ } &-item-details { - padding-bottom: 35px; display: table-cell; + padding-bottom: 35px; vertical-align: top; white-space: normal; width: 99%; diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 31009555bd9f9..7c975bea34abd 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -152,7 +152,9 @@ define([ }); it('test subscribe when cart data was changed', function () { - mocks['Magento_Customer/js/customer-data'].get('cart')({ data_id: 2 }); + mocks['Magento_Customer/js/customer-data'].get('cart')({ + data_id: 2 + }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); }); From 0fe329b6c429e8fd4e84dc8653b66be40cb8296b Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 30 Oct 2018 09:45:23 +0200 Subject: [PATCH 0891/1415] ENGCOM-3161: [Forwardport] #4942 and bundle checkbox bug #18520. Fix static tests. --- .../Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php index ed6a4d1ad7209..7c63af0bd0e2e 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php @@ -230,6 +230,8 @@ public function getProduct() } /** + * Get bundle option price title. + * * @param \Magento\Catalog\Model\Product $selection * @param bool $includeContainer * @return string From b7513494fd58447c4418b4f3d29ea40944548ddb Mon Sep 17 00:00:00 2001 From: Kajal Solanki <kajal10395@gmail.com> Date: Mon, 29 Oct 2018 14:21:45 +0530 Subject: [PATCH 0892/1415] fixed-Global-search icon misaligned-#18913 --- .../web/css/source/module/header/actions-group/_search.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less index 5e65faec60d4e..ddc3cb455402b 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less @@ -153,7 +153,7 @@ background-color: transparent; border: 1px solid transparent; font-size: @search-global-input__font-size; - height: @search-global-input__height; + height: @search-global-input__height + .2; padding: @search-global-input__padding-top @search-global-input__padding-side @search-global-input__padding-bottom; position: absolute; right: 0; From 3895af04b1ddfcae81717b1bf5373ded7e76c7bf Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Tue, 30 Oct 2018 09:57:26 +0200 Subject: [PATCH 0893/1415] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- .../Controller/Adminhtml/ProductTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index d949993e7ea3c..acec996d0c406 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -8,6 +8,8 @@ use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Framework\Message\Manager; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Message\MessageInterface; /** * @magentoAppArea adminhtml @@ -24,7 +26,7 @@ public function testSaveActionWithDangerRequest() $this->dispatch('backend/catalog/product/save'); $this->assertSessionMessages( $this->equalTo(['The product was unable to be saved. Please try again.']), - \Magento\Framework\Message\MessageInterface::TYPE_ERROR + MessageInterface::TYPE_ERROR ); $this->assertRedirect($this->stringContains('/backend/catalog/product/new')); } @@ -44,7 +46,7 @@ public function testSaveActionAndNew() $this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/new/')); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -71,11 +73,11 @@ public function testSaveActionAndDuplicate() ); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); $this->assertSessionMessages( $this->contains('You duplicated the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -260,9 +262,7 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider() * @param array $postData * @param array $tierPrice * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php - * @magentoAppIsolation enabled * @magentoConfigFixture current_store catalog/price/scope 1 - * @magentoDbIsolation disabled */ public function testSaveActionTierPrice(array $postData, array $tierPrice) { @@ -272,7 +272,7 @@ public function testSaveActionTierPrice(array $postData, array $tierPrice) $this->dispatch('backend/catalog/product/save/id/' . $postData['id']); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -349,8 +349,8 @@ public function saveActionTierPriceDataProvider() */ private function getProductData(array $tierPrice) { - $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); - $product = $repository->get('tier_prices')->getData(); + $productRepositoryInterface = $this->_objectManager->get(ProductRepositoryInterface::class); + $product = $productRepositoryInterface->get('tier_prices')->getData(); $product['tier_price'] = $tierPrice; unset($product['entity_id']); return $product; From 34163dca8d82ee4adbc4387c169215ef8d62d9c2 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 30 Oct 2018 11:49:19 +0200 Subject: [PATCH 0894/1415] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - moved test --- .../Adminhtml/User/Role/SaveRoleTest.php | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php deleted file mode 100644 index 50b28e2bac0a9..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\User\Controller\Adminhtml\User\Role; - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; -use Magento\Backend\Model\Auth\Session; -use Magento\Framework\Message\MessageInterface; -use Magento\User\Controller\Adminhtml\User\Role\SaveRole; - -/** - * Test class for \Magento\User\Controller\Adminhtml\User\Role. - * - * @magentoAppArea adminhtml - */ -class SaveRoleTest extends \Magento\TestFramework\TestCase\AbstractBackendController -{ - /** - * Test execute method - * - * @magentoDataFixture Magento/User/_files/two_users_with_role.php - * @magentoDbIsolation disabled - */ - public function testExecute() - { - $objectManager = Bootstrap::getObjectManager(); - /** @var \Magento\User\Model\User $currentAdmin */ - $currentAdmin = $objectManager->create(User::class) - ->loadByUsername('user'); - /** @var \Magento\Backend\Model\Auth\Session $authSession */ - $authSession = $objectManager->create(Session::class); - $authSession->setUser($currentAdmin); - $user1Id = $objectManager->create(User::class) - ->loadByUsername('johnAdmin')->getId(); - $user2Id = $objectManager->create(User::class) - ->loadByUsername('annAdmin')->getId(); - - /** @var \Magento\Authorization\Model\RoleFactory $roleFactory */ - $roleFactory = $objectManager->create(\Magento\Authorization\Model\RoleFactory::class); - $role = $roleFactory->create()->load(1); - - /** @var \Magento\AdminGws\Model\Role $gwsRole */ - $gwsRole = $objectManager->get(\Magento\AdminGws\Model\Role::class); - $gwsRole->setAdminRole($role); - $gwsRole->setStoreGroupIds([1]); - - $params = [ - 'role_id' => 1, - 'in_role_user_old'=> $user1Id . '=true&' . $user2Id . '=true', - 'in_role_user'=> $user1Id . '=true&' . $user2Id . '=true', - 'all' => 1, - 'current_password' => 'password1', - 'rolename' => 'Administrators', - ]; - - $post = [ - 'gws_is_all' => 1, - 'gws_store_groups' => ['1'], - ]; - - $this->getRequest()->setParams($params); - $this->getRequest()->setPostValue($post); - - $model = $objectManager->create(SaveRole::class); - $model->execute(); - $this->assertSessionMessages( - $this->equalTo(['You saved the role.']), - MessageInterface::TYPE_SUCCESS - ); - } -} From fbca4dd480841013d112118e5417a8ed4c7e8a69 Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Tue, 30 Oct 2018 11:03:02 +0100 Subject: [PATCH 0895/1415] Fixed annotations - Magento\Catalog\Model\ResourceModel\Product\Collection::addAttributeToFilter() - Magento\Quote\Model\QuoteAddress::setCollectShippingRates() --- .../Catalog/Model/ResourceModel/Product/Collection.php | 2 +- app/code/Magento/Quote/Model/Quote/Address.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 5afac59b25db6..14ae38667d873 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1534,7 +1534,7 @@ public function addPriceData($customerGroupId = null, $websiteId = null) /** * Add attribute to filter * - * @param \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|string $attribute + * @param \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|string|array $attribute * @param array $condition * @param string $joinType * @return $this diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 3eb5d68885035..f34cfbbf5fd26 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -28,8 +28,8 @@ * @method Address setAddressType(string $value) * @method int getFreeShipping() * @method Address setFreeShipping(int $value) - * @method int getCollectShippingRates() - * @method Address setCollectShippingRates(int $value) + * @method bool getCollectShippingRates() + * @method Address setCollectShippingRates(bool $value) * @method Address setShippingMethod(string $value) * @method string getShippingDescription() * @method Address setShippingDescription(string $value) From 42b235827941fb1713a360edcdbeebb0a95a35d4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 30 Oct 2018 11:45:50 +0100 Subject: [PATCH 0896/1415] Consolidated cart address information provider --- .../Resolver/Address/AddressDataProvider.php | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php index d401f296cb465..80fe973c4e449 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php @@ -10,6 +10,7 @@ use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Model\Quote\Address as QuoteAddress; /** * Class AddressDataProvider @@ -49,22 +50,45 @@ public function getCartAddresses(CartInterface $cart): array if ($shippingAddress) { $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); $shippingData['address_type'] = 'SHIPPING'; - $shippingData['selected_shipping_method'] = [ - 'code' => $shippingAddress->getShippingMethod(), - 'label' => $shippingAddress->getShippingDescription(), - 'free_shipping' => $shippingAddress->getFreeShipping(), - ]; - $shippingData['items_weight'] = $shippingAddress->getWeight(); - $shippingData['customer_notes'] = $shippingAddress->getCustomerNotes(); - $addressData[] = $shippingData; + $addressData[] = array_merge($shippingData, $this->extractAddressData($shippingAddress)); } if ($billingAddress) { $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); $billingData['address_type'] = 'BILLING'; - $addressData[] = $billingData; + $addressData[] = array_merge($billingData, $this->extractAddressData($billingAddress)); } return $addressData; } + + /** + * Extract the necessary address fields from address model + * + * @param QuoteAddress $address + * @return array + */ + private function extractAddressData(QuoteAddress $address): array + { + $addressData = [ + 'country' => [ + 'code' => $address->getCountryId(), + 'label' => $address->getCountry() + ], + 'region' => [ + 'code' => $address->getRegionCode(), + 'label' => $address->getRegion() + ], + 'street' => $address->getStreet(), + 'selected_shipping_method' => [ + 'code' => $address->getShippingMethod(), + 'label' => $address->getShippingDescription(), + 'free_shipping' => $address->getFreeShipping(), + ], + 'items_weight' => $address->getWeight(), + 'customer_notes' => $address->getCustomerNotes() + ]; + + return $addressData; + } } From 7e42eba3b9a2003e227404b33a29b728ae48a62a Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 30 Oct 2018 12:57:31 +0200 Subject: [PATCH 0897/1415] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - moved files --- .../User/_files/two_users_with_role.php | 52 ------------------- .../_files/two_users_with_role_rollback.php | 21 -------- 2 files changed, 73 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php delete mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php deleted file mode 100644 index 3b9e9b66427eb..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; - -/** - * Create an admin user with an assigned role - */ - -$objectManager = Bootstrap::getObjectManager(); - -/** @var \Magento\User\Model\ResourceModel\User $model */ -$userResource = $objectManager->create(\Magento\User\Model\ResourceModel\User::class); - -/** @var $user User */ -$user = $objectManager->create(User::class); -$user->setFirstname("John") - ->setIsActive(true) - ->setLastname("Doe") - ->setUsername('johnAdmin') - ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) - ->setEmail('JohnadminUser@example.com') - ->setRoleType('G') - ->setResourceId('Magento_Backend::all') - ->setPrivileges("") - ->setAssertId(0) - ->setRoleId(1) - ->setPermission('allow'); - -$userResource->save($user); - -/** @var $user User */ -$user = $objectManager->create(User::class); -$user->setFirstname("Ann") - ->setIsActive(true) - ->setLastname("Doe") - ->setUsername('annAdmin') - ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) - ->setEmail('JaneadminUser@example.com') - ->setRoleType('G') - ->setResourceId('Magento_Backend::all') - ->setPrivileges("") - ->setAssertId(0) - ->setRoleId(1) - ->setPermission('allow'); - -$userResource->save($user); diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php deleted file mode 100644 index 7d7d85c71a994..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; - -/** - * Create an admin user with an assigned role - */ - -/** @var $user User */ -$user = Bootstrap::getObjectManager()->create(User::class); -$user->loadByUsername('johnAdmin')->delete(); - -/** @var $user User */ -$user = Bootstrap::getObjectManager()->create(User::class); -$user->loadByUsername('annAdmin')->delete(); From 1cfa17f2de57c9a095f248d8e9aa81e5fa3ca35b Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Tue, 30 Oct 2018 13:24:01 +0200 Subject: [PATCH 0898/1415] magento/graphql-ce#41: Updated composer.lock hash --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 1d101c8aaaf15..bc2160a2b18bd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6640ddfd342feceaec44c406c056f57", + "content-hash": "edf8aa5e66649f1a221f027a3600d41e", "packages": [ { "name": "braintree/braintree_php", From 61d81a8e07b627eb7f3850529767e1427461f52b Mon Sep 17 00:00:00 2001 From: Andrii Dimov <adimov@adobe.com> Date: Fri, 12 Oct 2018 20:59:40 +0300 Subject: [PATCH 0899/1415] MAGETWO-95651: Narrow number of top menu cache versions --- app/code/Magento/Theme/Block/Html/Topmenu.php | 4 +--- app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 0dca0f8606a8c..6961a89b41e08 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -369,9 +369,7 @@ public function getIdentities() */ public function getCacheKeyInfo() { - $keyInfo = parent::getCacheKeyInfo(); - $keyInfo[] = $this->getUrl('*/*/*', ['_current' => true, '_query' => '']); - return $keyInfo; + return parent::getCacheKeyInfo(); } /** diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php index 91c3ce47fc8b8..023c741492752 100644 --- a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php +++ b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php @@ -189,7 +189,6 @@ public function testGetCacheKeyInfo() $treeFactory = $this->createMock(\Magento\Framework\Data\TreeFactory::class); $topmenu = new Topmenu($this->context, $nodeFactory, $treeFactory); - $this->urlBuilder->expects($this->once())->method('getUrl')->with('*/*/*')->willReturn('123'); $this->urlBuilder->expects($this->once())->method('getBaseUrl')->willReturn('baseUrl'); $store = $this->getMockBuilder(\Magento\Store\Model\Store::class) ->disableOriginalConstructor() @@ -199,7 +198,7 @@ public function testGetCacheKeyInfo() $this->storeManager->expects($this->once())->method('getStore')->willReturn($store); $this->assertEquals( - ['BLOCK_TPL', '321', null, 'base_url' => 'baseUrl', 'template' => null, '123'], + ['BLOCK_TPL', '321', null, 'base_url' => 'baseUrl', 'template' => null], $topmenu->getCacheKeyInfo() ); } From fcb3d675ea3df97f8935cc5a560a396ac9ae7db2 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 30 Oct 2018 14:31:32 +0200 Subject: [PATCH 0900/1415] MAGETWO-95651: Narrow number of top menu cache versions --- app/code/Magento/Theme/Block/Html/Topmenu.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 6961a89b41e08..242947d19b321 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -361,17 +361,6 @@ public function getIdentities() return $this->identities; } - /** - * Get cache key informative items - * - * @return array - * @since 100.1.0 - */ - public function getCacheKeyInfo() - { - return parent::getCacheKeyInfo(); - } - /** * Get tags array for saving cache * From b272c4e4bf5e3ee39ecc6376ee425f4e7ae5d27a Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 08:44:10 -0400 Subject: [PATCH 0901/1415] Removed unused properties --- .../ResourceModel/Import/Customer/Storage.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php index 38890de643295..58af2c5c1ca6e 100644 --- a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php +++ b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php @@ -44,30 +44,13 @@ class Storage protected $_byPagesIterator; /** - * @var CustomerCollectionFactory - */ - private $customerCollectionFactory; - - /** - * Customer collection. - * - * @var \Magento\Customer\Model\ResourceModel\Customer\Collection - */ - private $_customerCollection; - - /** - * @param CustomerCollectionFactory $collectionFactory * @param CollectionByPagesIteratorFactory $colIteratorFactory * @param array $data */ public function __construct( - CustomerCollectionFactory $collectionFactory, CollectionByPagesIteratorFactory $colIteratorFactory, array $data = [] ) { - $this->_customerCollection = isset( - $data['customer_collection'] - ) ? $data['customer_collection'] : $collectionFactory->create(); $this->_pageSize = isset($data['page_size']) ? $data['page_size'] : 0; $this->_byPagesIterator = isset( $data['collection_by_pages_iterator'] From e32808beebefcbf43d541bcf37aa96460bee519b Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 08:57:34 -0400 Subject: [PATCH 0902/1415] Extracted websiteString property to local variable --- .../Import/AdvancedPricing/Validator/WebsiteTest.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php index 41ac72bd8dacc..d78c4f5e61af3 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php @@ -25,11 +25,6 @@ class WebsiteTest extends \PHPUnit\Framework\TestCase */ protected $website; - /** - * @var \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website|\PHPUnit_Framework_MockObject_MockObject - */ - protected $websiteString; - protected function setUp() { $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\Website::class) @@ -108,13 +103,13 @@ public function testGetAllWebsitesValue() $this->webSiteModel->expects($this->once())->method('getBaseCurrency')->willReturn($currency); $expectedResult = AdvancedPricing::VALUE_ALL_WEBSITES . ' [' . $currencyCode . ']'; - $this->websiteString = $this->getMockBuilder( + $websiteString = $this->getMockBuilder( \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website::class ) ->setMethods(['_clearMessages', '_addMessages']) ->setConstructorArgs([$this->storeResolver, $this->webSiteModel]) ->getMock(); - $result = $this->websiteString->getAllWebsitesValue(); + $result = $websiteString->getAllWebsitesValue(); $this->assertEquals($expectedResult, $result); } From 6789eb495f0ab9c8e7c532a20826e43da518f2a5 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 09:09:04 -0400 Subject: [PATCH 0903/1415] Removed unused connection property, added PHPMD.UnusedFormalParameter directive --- .../DownloadableImportExport/Helper/Uploader.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php index 9420aeb51d41c..5fc4df1d03c49 100644 --- a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php +++ b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php @@ -38,13 +38,6 @@ class Uploader extends \Magento\Framework\App\Helper\AbstractHelper */ protected $parameters = []; - /** - * Connection resource. - * - * @var \Magento\Framework\DB\Adapter\AdapterInterface - */ - protected $connection = []; - /** * Construct * @@ -53,6 +46,8 @@ class Uploader extends \Magento\Framework\App\Helper\AbstractHelper * @param \Magento\CatalogImportExport\Model\Import\UploaderFactory $uploaderFactory * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Framework\Filesystem $filesystem + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -67,7 +62,6 @@ public function __construct( $this->fileUploader->init(); $this->fileUploader->setAllowedExtensions($this->getAllowedExtensions()); $this->fileUploader->removeValidateCallback('catalog_product_image'); - $this->connection = $resource->getConnection('write'); $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); } From 2f5fc9742ed261a0e3440db0ce87963f502644e5 Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Tue, 30 Oct 2018 14:11:05 +0100 Subject: [PATCH 0904/1415] Fixed annotations - Magento\Customer\Model\Address\AbstractAddress::getCountry() - Magento\Customer\Model\Address\AbstractAddress::getCountryId() --- app/code/Magento/Customer/Model/Address/AbstractAddress.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 6408276630c3f..3ee284a705b16 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -23,7 +23,7 @@ * @method string getFirstname() * @method string getMiddlename() * @method string getLastname() - * @method int getCountryId() + * @method string getCountryId() * @method string getCity() * @method string getTelephone() * @method string getCompany() @@ -425,7 +425,7 @@ public function getRegionId() } /** - * @return int + * @return string */ public function getCountry() { From d0c4c6411343a0dbebd2e3a2b0aa8d5be9a94ac1 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 09:14:07 -0400 Subject: [PATCH 0905/1415] Fixed property type in docblock --- .../Magento/CustomerImportExport/Model/Import/Address.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index 9ba50738ebc1a..a8ca6969a6ea1 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -104,9 +104,9 @@ class Address extends AbstractCustomer /** * Region collection instance * - * @var string + * @var \Magento\Directory\Model\ResourceModel\Region\Collection */ - protected $_regionCollection; + private $_regionCollection; /** * Countries and regions From e9730955a3029c4f75f0a80bad31e9f2cc2480cd Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 09:21:07 -0400 Subject: [PATCH 0906/1415] Added back customerCollectionFactory property --- .../Model/ResourceModel/Import/Customer/Storage.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php index 58af2c5c1ca6e..c5d28240c3068 100644 --- a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php +++ b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php @@ -44,10 +44,17 @@ class Storage protected $_byPagesIterator; /** + * @var CustomerCollectionFactory + */ + private $customerCollectionFactory; + + /** + * @param CustomerCollectionFactory $collectionFactory * @param CollectionByPagesIteratorFactory $colIteratorFactory * @param array $data */ public function __construct( + CustomerCollectionFactory $collectionFactory, CollectionByPagesIteratorFactory $colIteratorFactory, array $data = [] ) { From c95ce3ca53529c1a1e38f2ec5b187c64f45029e6 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Mon, 11 Dec 2017 14:11:02 +0200 Subject: [PATCH 0907/1415] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix code style; --- .../Model/ResourceModel/Product/ImageTest.php | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1a1eebf30f7f6..4fce12dc2de89 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -13,6 +13,8 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; use Magento\Catalog\Model\ResourceModel\Product\Gallery; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\Framework\DB\Query\BatchIteratorInterface; class ImageTest extends \PHPUnit\Framework\TestCase { @@ -22,34 +24,37 @@ class ImageTest extends \PHPUnit\Framework\TestCase protected $objectManager; /** - * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + * @var AdapterInterface | MockObject */ protected $connectionMock; /** - * @var Generator | \PHPUnit_Framework_MockObject_MockObject + * @var Generator | MockObject */ protected $generatorMock; /** - * @var ResourceConnection | \PHPUnit_Framework_MockObject_MockObject + * @var ResourceConnection | MockObject */ protected $resourceMock; protected function setUp(): void { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->objectManager = + new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->connectionMock = $this->createMock(AdapterInterface::class); $this->resourceMock = $this->createMock(ResourceConnection::class); - $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); - $this->resourceMock->method('getTableName')->willReturnArgument(0); + $this->resourceMock->method('getConnection') + ->willReturn($this->connectionMock); + $this->resourceMock->method('getTableName') + ->willReturnArgument(0); $this->generatorMock = $this->createMock(Generator::class); } /** - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ - protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_MockObject + protected function getVisibleImagesSelectMock(): MockObject { $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() @@ -105,7 +110,10 @@ public function testGetCountAllProductImages(int $imagesCount): void ] ); - $this->assertSame($imagesCount, $imageModel->getCountAllProductImages()); + $this->assertSame( + $imagesCount, + $imageModel->getCountAllProductImages() + ); } /** @@ -113,8 +121,10 @@ public function testGetCountAllProductImages(int $imagesCount): void * @param int $batchSize * @dataProvider dataProvider */ - public function testGetAllProductImages(int $imagesCount, int $batchSize): void - { + public function testGetAllProductImages( + int $imagesCount, + int $batchSize + ): void { $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); @@ -125,7 +135,7 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void ->method('fetchAll') ->will($this->returnCallback($fetchResultsCallback)); - /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ + /** @var Select | MockObject $selectMock */ $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() ->getMock(); @@ -136,8 +146,12 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void 'value_id', $selectMock, $batchSize, - \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR - )->will($this->returnCallback($this->getBatchIteratorCallback($selectMock, $batchCount))); + BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR + )->will( + $this->returnCallback( + $this->getBatchIteratorCallback($selectMock, $batchCount) + ) + ); $imageModel = $this->objectManager->getObject( Image::class, @@ -156,10 +170,13 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void * @param int $batchSize * @return \Closure */ - protected function getFetchResultCallbackForBatches(int $imagesCount, int $batchSize): \Closure - { + protected function getFetchResultCallbackForBatches( + int $imagesCount, + int $batchSize + ): \Closure { $fetchResultsCallback = function () use (&$imagesCount, $batchSize) { - $batchSize = ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; + $batchSize = + ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; $imagesCount -= $batchSize; $getFetchResults = function ($batchSize): array { @@ -180,16 +197,15 @@ protected function getFetchResultCallbackForBatches(int $imagesCount, int $batch } /** - * @param Select | \PHPUnit_Framework_MockObject_MockObject $selectMock + * @param Select | MockObject $selectMock * @param int $batchCount * @return \Closure */ protected function getBatchIteratorCallback( - \PHPUnit_Framework_MockObject_MockObject $selectMock, + MockObject $selectMock, int $batchCount - ): \Closure - { - $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { + ): \Closure { + $iteratorCallback = function () use ($batchCount, $selectMock): array { $result = []; $count = $batchCount; while ($count) { @@ -200,7 +216,7 @@ protected function getBatchIteratorCallback( return $result; }; - return $getBatchIteratorCallback; + return $iteratorCallback; } /** From 1e304992e950945394ea331004fe700b6173a909 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 30 Oct 2018 15:46:55 +0200 Subject: [PATCH 0908/1415] MAGETWO-94835: Automate with MFTF Filter shared catalogs by 'Created By' field --- .../Mftf/Section/CheckoutShippingSection.xml | 1 + .../AdminDeleteUserActionGroup.xml | 28 +++++++++++++++++++ .../Magento/User/Test/Mftf/Data/UserData.xml | 14 ++++++++++ .../User/Test/Mftf/Metadata/user-meta.xml | 5 +++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index ff7f8995c0681..fb9a79bc93865 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -33,5 +33,6 @@ <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="state" type="button" selector="//*[text()='Alabama']"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml new file mode 100644 index 0000000000000..70c0a772ec341 --- /dev/null +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCustomUserActionGroup"> + <arguments> + <argument name="user"/> + </arguments> + <amOnPage url="{{AdminUsersPage.url}}" stepKey="navigateToUserGrid" /> + <fillField selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="{{user.username}}" stepKey="enterUserName" /> + <click selector="{{AdminUserGridSection.searchButton}}" stepKey="clickSearch" /> + <waitForPageLoad stepKey="waitForGridToLoad"/> + <see selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="{{user.username}}" stepKey="seeUser" /> + <click selector="{{AdminUserGridSection.searchResultFirstRow}}" stepKey="openUserEdit"/> + <waitForPageLoad stepKey="waitForUserEditPageLoad"/> + <fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterThePassword" /> + <click selector="{{AdminMainActionsSection.delete}}" stepKey="deleteUser"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="waitForSave" /> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the user." stepKey="seeUserDeleteMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/User/Test/Mftf/Data/UserData.xml b/app/code/Magento/User/Test/Mftf/Data/UserData.xml index 03ae3dba21840..80c1cc3022964 100644 --- a/app/code/Magento/User/Test/Mftf/Data/UserData.xml +++ b/app/code/Magento/User/Test/Mftf/Data/UserData.xml @@ -18,4 +18,18 @@ <data key="lastName">Smith</data> <data key="password">admin123</data> </entity> + <entity name="Admin3" type="user"> + <data key="username" unique="suffix">admin3</data> + <data key="firstname">admin3</data> + <data key="lastname">admin3</data> + <data key="email" unique="prefix">admin3WebUser@example.com</data> + <data key="password">123123q</data> + <data key="password_confirmation">123123q</data> + <data key="interface_local">en_US</data> + <data key="is_active">true</data> + <data key="current_password">123123q</data> + <array key="roles"> + <item>1</item> + </array> + </entity> </entities> diff --git a/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml b/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml index 2e1e5f6f5a97d..1ee29be6b3d76 100644 --- a/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml +++ b/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml @@ -6,7 +6,7 @@ */ --> <operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> <operation name="CreateUser" dataType="user" type="create" auth="adminFormKey" url="/admin/user/save/" method="POST" successRegex="/messages-message-success/" returnRegex="" > <contentType>application/x-www-form-urlencoded</contentType> @@ -19,5 +19,8 @@ <field key="interface_locale">string</field> <field key="is_active">boolean</field> <field key="current_password">string</field> + <array key="roles"> + <value>string</value> + </array> </operation> </operations> From 152b0924d652de96bb49a93959bb3b304e2601ba Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Tue, 30 Oct 2018 16:34:52 +0200 Subject: [PATCH 0909/1415] Fix Notice and Exception while adding image to product programmatically --- .../Model/Product/Gallery/Processor.php | 24 +++++++++++++++---- composer.json | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index c6c7fbda7e9ec..225c502830695 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Model\Product\Gallery; +use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem\DriverInterface; @@ -183,6 +184,13 @@ public function addImage( $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); $position = 0; + + $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); + $imageMimeType = mime_content_type($absoluteFilePath); + $imageContent = file_get_contents($absoluteFilePath); + $imageBase64 = base64_encode($imageContent); + $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; } @@ -195,11 +203,19 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'label' => '', - 'disabled' => (int)$exclude, + 'types' => $mediaAttribute, + 'content' => [ + 'data' => [ + ImageContentInterface::NAME => $imageName, + ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, + ImageContentInterface::TYPE => $imageMimeType, + ] + ] ]; $product->setData($attrCode, $mediaGalleryData); diff --git a/composer.json b/composer.json index e2a646275d98b..68bf1f1d8a8b0 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", + "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 124164e3a2e667e40814af444d0d0cf68b952867 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Oct 2018 16:46:36 +0200 Subject: [PATCH 0910/1415] magento-engcom/magento2ce#2287: Code style fixes --- .../Checkout/frontend/js/model/cart/estimate-service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 7c975bea34abd..ce9c98c9d2560 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -153,7 +153,7 @@ define([ it('test subscribe when cart data was changed', function () { mocks['Magento_Customer/js/customer-data'].get('cart')({ - data_id: 2 + dataId: 2 }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); From 898d2a507a283c15af63dedf2c837bbba03ba89c Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 30 Oct 2018 17:52:51 +0300 Subject: [PATCH 0911/1415] MAGETWO-91650: Translation not working for product alerts - Replacing name with referenceId --- app/code/Magento/ProductAlert/etc/db_schema.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index c6dd8db321b54..820a8029e2d95 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -52,7 +52,7 @@ <index referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -99,7 +99,7 @@ <index referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> From fab32c6f68410e507b721206a8902ea77d1ce506 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Tue, 30 Oct 2018 15:32:35 +0000 Subject: [PATCH 0912/1415] Fix PHPCS check for "Short description must start with a capital letter" --- .../Magento/CustomerImportExport/Model/Import/Address.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index a8ca6969a6ea1..7a1a09efaa7b6 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -788,7 +788,7 @@ public static function getDefaultAddressAttributeMapping() } /** - * check if address for import is empty (for customer composite mode) + * Check if address for import is empty (for customer composite mode) * * @param array $rowData * @return array @@ -947,7 +947,7 @@ protected function _checkRowDuplicate($customerId, $addressId) } /** - * set customer attributes + * Set customer attributes * * @param array $customerAttributes * @return $this From 052d0cc0dda65fa2a014cd0c6a3925b2d14c3f12 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 30 Oct 2018 13:20:37 -0500 Subject: [PATCH 0913/1415] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - add error message for incorrect product items --- .../Item/Validation/CreationQuantityValidator.php | 4 ++++ app/code/Magento/Sales/Model/Order/ItemRepository.php | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php index 0c2adfff80a2b..fdc5e2658b9ed 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php @@ -53,6 +53,10 @@ public function validate($entity) return [__('The creditmemo contains product item that is not part of the original order.')]; } + if ($orderItem->isDummy()) { + return [__('The creditmemo contains incorrect product items.')]; + } + if (!$this->isQtyAvailable($orderItem, $entity->getQty())) { return [__('The quantity to refund must not be greater than the unrefunded quantity.')]; } diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 7916eb9db2b80..2ea9831336cc2 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -228,6 +228,12 @@ private function addParentItem(OrderItemInterface $orderItem) { if ($parentId = $orderItem->getParentItemId()) { $orderItem->setParentItem($this->get($parentId)); + } else { + foreach ($orderItem->getOrder()->getAllItems() as $item) { + if($item->getParentItemId() === $orderItem->getItemId()) { + $item->setParentItem($orderItem); + } + } } } From 970a746e1274419973be563ffd8e3a49a8cb26ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:13:56 +0200 Subject: [PATCH 0914/1415] Update _module.less code clean up --- .../Magento_MultipleWishlist/web/css/source/_module.less | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less index 145dc10263fb1..cb341f3f479ba 100644 --- a/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less @@ -185,7 +185,7 @@ } .form-wishlist-search { - .lib-css(margin-bottom, @indent__l*2); + margin-bottom: @indent__l * 2; max-width: 500px; .fieldset { @@ -216,8 +216,9 @@ .block-wishlist-info-items { .block-title { - .lib-css(margin-bottom, @indent__base); .lib-font-size(22); + margin-bottom: @indent__base; + > strong { font-weight: @font-weight__light; } From c7aa2f7def099baefda795e3ff64ea26e8ce1d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:24:33 +0200 Subject: [PATCH 0915/1415] Update _module.less --- .../Magento_MultipleWishlist/web/css/source/_module.less | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_MultipleWishlist/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_MultipleWishlist/web/css/source/_module.less index 6ab7a8e47a174..0b01c54a64378 100644 --- a/app/design/frontend/Magento/luma/Magento_MultipleWishlist/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_MultipleWishlist/web/css/source/_module.less @@ -40,6 +40,7 @@ .items { padding: 6px 0; text-align: left; + .item { > span { display: block; @@ -47,6 +48,7 @@ } } + li { padding: 0; } @@ -115,6 +117,7 @@ &.split, &.toggle { .lib-css(color, @link__color); + &:before { display: none; } @@ -135,6 +138,7 @@ &.overlay { .lib-window-overlay(); + &.active { display: block; } @@ -254,7 +258,7 @@ } .form-wishlist-search { - .lib-css(margin-bottom, @indent__l*2); + margin-bottom: @indent__l * 2; max-width: 500px; .fieldset { @@ -281,7 +285,7 @@ .block-wishlist-info-items { .block-title { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; .lib-font-size(22px); > strong { @@ -352,6 +356,7 @@ // Select wish list &-select { margin: 0 -@layout__width-xs-indent 20px; + .wishlist-name { .lib-font-size(16); &:extend(.abs-toggling-title-mobile all); From b0fca1d57b6b9352e62f8059e58f5d62bf8c45d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:31:16 +0200 Subject: [PATCH 0916/1415] Update _widgets.less --- .../Magento/blank/Magento_Banner/web/css/source/_widgets.less | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Banner/web/css/source/_widgets.less b/app/design/frontend/Magento/blank/Magento_Banner/web/css/source/_widgets.less index 80ac77e42fc04..c961d49c5b589 100644 --- a/app/design/frontend/Magento/blank/Magento_Banner/web/css/source/_widgets.less +++ b/app/design/frontend/Magento/blank/Magento_Banner/web/css/source/_widgets.less @@ -8,7 +8,6 @@ // _____________________________________________ & when (@media-common = true) { - .block-banners, .block-banners-inline { &:extend(.abs-margin-for-blocks-and-widgets); @@ -22,7 +21,7 @@ } .banner-item-content { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; img { display: block; From b198d34bda628bc022bef79767cacbb075c1d62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:37:50 +0200 Subject: [PATCH 0917/1415] Update _minicart.less --- .../web/css/source/module/_minicart.less | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less index 7bd27106b67d9..2219db1cf694d 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less @@ -125,7 +125,7 @@ float: right; .block-minicart { - .lib-css(padding, 25px @minicart__padding-horizontal); + padding: 25px @minicart__padding-horizontal; .block-title { display: none; @@ -148,10 +148,10 @@ .action { &.close { .lib-button-icon( - @icon-remove, - @_icon-font-size: 32px, - @_icon-font-line-height: 32px, - @_icon-font-text-hide: true + @icon-remove, + @_icon-font-size: 32px, + @_icon-font-line-height: 32px, + @_icon-font-text-hide: true ); .lib-button-reset(); height: 40px; @@ -205,8 +205,8 @@ } .minicart-items-wrapper { - .lib-css(border, 1px solid @minicart__border-color); - .lib-css(margin, 0 -@minicart__padding-horizontal); + border: 1px solid @minicart__border-color; + margin: 0 -@minicart__padding-horizontal; border-left: 0; border-right: 0; overflow-x: auto; @@ -220,7 +220,7 @@ padding: @indent__base 0; &:not(:first-child) { - .lib-css(border-top, 1px solid @minicart__border-color); + border-top: 1px solid @minicart__border-color; } &:first-child { @@ -254,12 +254,12 @@ .toggle { .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 28px, - @_icon-font-line-height: 16px, - @_icon-font-text-hide: false, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 28px, + @_icon-font-line-height: 16px, + @_icon-font-text-hide: false, + @_icon-font-position: after, + @_icon-font-display: block ); cursor: pointer; position: relative; @@ -274,8 +274,8 @@ &.active { > .toggle { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } @@ -304,6 +304,7 @@ .weee[data-label] { .lib-font-size(11); + .label { &:extend(.abs-no-display all); } @@ -317,12 +318,12 @@ .product.options { .tooltip.toggle { .lib-icon-font( - @icon-down, - @_icon-font-size: 28px, - @_icon-font-line-height: 28px, - @_icon-font-text-hide: true, - @_icon-font-margin: -3px 0 0 7px, - @_icon-font-position: after + @icon-down, + @_icon-font-size: 28px, + @_icon-font-line-height: 28px, + @_icon-font-text-hide: true, + @_icon-font-margin: -3px 0 0 7px, + @_icon-font-position: after ); .details { @@ -357,19 +358,19 @@ &.edit, &.delete { .lib-icon-font( - @icon-settings, - @_icon-font-size: 28px, - @_icon-font-line-height: 28px, - @_icon-font-text-hide: true, - @_icon-font-color: @color-gray19, - @_icon-font-color-hover: @color-gray19, - @_icon-font-color-active: @color-gray19 + @icon-settings, + @_icon-font-size: 28px, + @_icon-font-line-height: 28px, + @_icon-font-text-hide: true, + @_icon-font-color: @color-gray19, + @_icon-font-color-hover: @color-gray19, + @_icon-font-color-active: @color-gray19 ); } &.delete { .lib-icon-font-symbol( - @_icon-font-content: @icon-trash + @_icon-font-content: @icon-trash ); } } @@ -399,6 +400,7 @@ .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { .minicart-wrapper { margin-left: 13px; + .block-minicart { right: -15px; width: 390px; From b48b95f0c6027e7bf93ce49297c4cb04b567b577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:42:18 +0200 Subject: [PATCH 0918/1415] Update _minicart.less --- .../web/css/source/module/_minicart.less | 77 ++++++++++--------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less index 03e4bfff3ba9c..14db9dd868e00 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less @@ -107,28 +107,28 @@ .minicart-wrapper { .lib-dropdown( - @_toggle-selector: ~'.action.showcart', - @_options-selector: ~'.block-minicart', - @_dropdown-list-width: 320px, - @_dropdown-list-position-right: 0px, - @_dropdown-list-pointer-position: right, - @_dropdown-list-pointer-position-left-right: 26px, - @_dropdown-list-z-index: 101, - @_dropdown-toggle-icon-content: @icon-cart, - @_dropdown-toggle-active-icon-content: @icon-cart, - @_dropdown-list-item-padding: false, - @_dropdown-list-item-hover: false, - @_icon-font-position: before, - @_icon-font-size: 22px, - @_icon-font-line-height: 28px, - @_icon-font-color: @minicart-icons-color, - @_icon-font-color-hover: @minicart-icons-color-hover, - @_icon-font-color-active: @minicart-icons-color + @_toggle-selector: ~'.action.showcart', + @_options-selector: ~'.block-minicart', + @_dropdown-list-width: 320px, + @_dropdown-list-position-right: 0px, + @_dropdown-list-pointer-position: right, + @_dropdown-list-pointer-position-left-right: 26px, + @_dropdown-list-z-index: 101, + @_dropdown-toggle-icon-content: @icon-cart, + @_dropdown-toggle-active-icon-content: @icon-cart, + @_dropdown-list-item-padding: false, + @_dropdown-list-item-hover: false, + @_icon-font-position: before, + @_icon-font-size: 22px, + @_icon-font-line-height: 28px, + @_icon-font-color: @minicart-icons-color, + @_icon-font-color-hover: @minicart-icons-color-hover, + @_icon-font-color-active: @minicart-icons-color ); float: right; .block-minicart { - .lib-css(padding, 25px @minicart__padding-horizontal); + padding: 25px @minicart__padding-horizontal; .block-title { display: none; @@ -216,8 +216,8 @@ } .minicart-items-wrapper { - .lib-css(border, 1px solid @minicart__border-color); - .lib-css(margin, 0 -@minicart__padding-horizontal); + border: 1px solid @minicart__border-color; + margin: 0 -@minicart__padding-horizontal; border-left: 0; border-right: 0; overflow-x: auto; @@ -226,11 +226,12 @@ .minicart-items { .lib-list-reset-styles(); + .product-item { padding: @indent__base 0; &:not(:first-child) { - .lib-css(border-top, 1px solid @minicart__border-color); + border-top: 1px solid @minicart__border-color; } &:first-child { @@ -297,13 +298,14 @@ .toggle { &:extend(.abs-toggling-title all); + border: 0; + padding: 0 @indent__xl @indent__xs 0; + &:after { .lib-css(color, @color-gray56); margin: 0 0 0 @indent__xs; position: static; } - border: 0; - padding: 0 @indent__xl @indent__xs 0; } .active { @@ -323,14 +325,15 @@ .toggle { &.tooltip { .lib-icon-font( - @icon-down, - @_icon-font-size: 12px, - @_icon-font-line-height: 12px, - @_icon-font-text-hide: true, - @_icon-font-margin: -3px 0 0 7px, - @_icon-font-position: after + @icon-down, + @_icon-font-size: 12px, + @_icon-font-line-height: 12px, + @_icon-font-text-hide: true, + @_icon-font-margin: -3px 0 0 7px, + @_icon-font-position: after ); } + > span { &:extend(.abs-visually-hidden-reset all); } @@ -368,19 +371,19 @@ &.edit, &.delete { .lib-icon-font( - @icon-edit, - @_icon-font-size: 18px, - @_icon-font-line-height: 20px, - @_icon-font-text-hide: true, - @_icon-font-color: @minicart-icons-color, - @_icon-font-color-hover: @primary__color, - @_icon-font-color-active: @minicart-icons-color + @icon-edit, + @_icon-font-size: 18px, + @_icon-font-line-height: 20px, + @_icon-font-text-hide: true, + @_icon-font-color: @minicart-icons-color, + @_icon-font-color-hover: @primary__color, + @_icon-font-color-active: @minicart-icons-color ); } &.delete { .lib-icon-font-symbol( - @_icon-font-content: @icon-trash + @_icon-font-content: @icon-trash ); } } From ecaabe44f4264d90a63c3fb3624bb04e47f9e661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:50:39 +0200 Subject: [PATCH 0919/1415] Update _module.less --- .../Magento_Review/web/css/source/_module.less | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/_module.less index 7d5b79bc5a091..69ec01d71e104 100644 --- a/app/design/frontend/Magento/blank/Magento_Review/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Review/web/css/source/_module.less @@ -15,9 +15,9 @@ // _____________________________________________ & when (@media-common = true) { - .rating-summary { .lib-rating-summary(); + .rating-result { margin-left: -5px; } @@ -165,10 +165,10 @@ .review-details { .customer-review-rating { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; .item { - .lib-css(margin-bottom, @indent__s); + margin-bottom: @indent__s; &:last-child { margin-bottom: 0; @@ -178,12 +178,12 @@ .review-title { .lib-heading(h3); - .lib-css(font-weight, @font-weight__semibold); - .lib-css(margin-bottom, @indent__base); + font-weight: @font-weight__semibold; + margin-bottom: @indent__base; } .review-content { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; } } @@ -271,7 +271,7 @@ &-field-rating { .control { - margin-bottom: 1.2*@indent__xl; + margin-bottom: 1.2 * @indent__xl; margin-top: @indent__s; } } From a02c49ffeddd25852bc6bb2b5709c513c946c5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 21:56:32 +0200 Subject: [PATCH 0920/1415] Update _module.less --- .../web/css/source/_module.less | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Review/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Review/web/css/source/_module.less index da78406f92212..2c66420f65fbd 100644 --- a/app/design/frontend/Magento/luma/Magento_Review/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Review/web/css/source/_module.less @@ -14,7 +14,6 @@ // _____________________________________________ & when (@media-common = true) { - .data.switch .counter { .lib-css(color, @text__color__muted); @@ -118,13 +117,13 @@ strong { display: block; - font-weight: 600; + font-weight: @font-weight__semibold; } } .fieldset &-field-ratings { > .label { - font-weight: 600; + font-weight: @font-weight__semibold; margin-bottom: @indent__s; padding: 0; } @@ -140,11 +139,11 @@ &-field-rating { .label { - font-weight: 600; + font-weight: @font-weight__semibold; } .control { - margin-bottom: 1.2*@indent__xl; + margin-bottom: 1.2 * @indent__xl; margin-top: @indent__s; } } @@ -181,7 +180,7 @@ display: inline; .review-details-value { - font-weight: 400; + font-weight: @font-weight__regular; } } @@ -341,7 +340,7 @@ .block-reviews-dashboard { .items { .item { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; &:last-child { margin-bottom: 0; @@ -353,14 +352,14 @@ display: inline-block; &:not(:last-child) { - .lib-css(margin-bottom, @indent__xs); + margin-bottom: @indent__xs; } } .rating-summary { .label { - .lib-css(font-weight, @font-weight__semibold); - .lib-css(margin-right, @indent__s); + font-weight: @font-weight__semibold; + margin-right: @indent__s; } } } @@ -368,7 +367,7 @@ .table-reviews, .block-reviews-dashboard { .product-name { - .lib-css(font-weight, @font-weight__regular); + font-weight: @font-weight__regular; } } @@ -416,6 +415,7 @@ .product-details { &:extend(.abs-add-clearfix all); &:extend(.abs-margin-for-blocks-and-widgets all); + .rating-average-label { &:extend(.abs-visually-hidden all); } @@ -436,9 +436,10 @@ } .customer-review-rating { - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; + .item { - .lib-css(margin-bottom, @indent__s); + margin-bottom: @indent__s; &:last-child { margin-bottom: 0; @@ -450,13 +451,13 @@ .review-title { .lib-heading(h3); - .lib-css(font-weight, @font-weight__semibold); - .lib-css(margin-bottom, @indent__base); + font-weight: @font-weight__semibold; + margin-bottom: @indent__base; } .review-content { margin: 0; - .lib-css(margin-bottom, @indent__base); + margin-bottom: @indent__base; } .review-date { @@ -473,13 +474,13 @@ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) { .customer-review { .product-name { - .lib-css(margin-bottom, @indent__xs); + margin-bottom: @indent__xs; } .product-reviews-summary { .rating-summary { display: block; - .lib-css(margin-bottom, @indent__xs); + margin-bottom: @indent__xs; } } } From 59a88f3509bba27c988fc89f874cdaf7f0d5c29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 22:08:34 +0200 Subject: [PATCH 0921/1415] Update _extends.less --- .../blank/web/css/source/_extends.less | 191 +++++++++--------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/app/design/frontend/Magento/blank/web/css/source/_extends.less b/app/design/frontend/Magento/blank/web/css/source/_extends.less index 13da4a4d996cc..4b328ab1015ed 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_extends.less +++ b/app/design/frontend/Magento/blank/web/css/source/_extends.less @@ -162,7 +162,7 @@ & when (@media-common = true) { .abs-login-block-title { strong { - font-weight: 500; + font-weight: @font-weight__heavier; } .lib-font-size(18); @@ -178,11 +178,11 @@ & when (@media-common = true) { .abs-block-title { + margin-bottom: 15px; + > strong { .lib-heading(h3); } - - margin-bottom: 15px; } } @@ -194,6 +194,7 @@ .abs-account-blocks { .block-title { &:extend(.abs-block-title all); + > .action { margin-left: 15px; } @@ -208,7 +209,7 @@ } > .action { - font-weight: 400; + font-weight: @font-weight__regular; margin-left: @indent__s; } } @@ -232,10 +233,10 @@ & when (@media-common = true) { .abs-dropdown-simple { .lib-dropdown( - @_dropdown-list-item-padding: 5px 5px 5px 23px, - @_dropdown-list-min-width: 200px, - @_icon-font-margin: 0 0 0 5px, - @_icon-font-vertical-align: middle + @_dropdown-list-item-padding: 5px 5px 5px 23px, + @_dropdown-list-min-width: 200px, + @_icon-font-margin: 0 0 0 5px, + @_icon-font-vertical-align: middle ); } } @@ -268,13 +269,13 @@ & when (@media-common = true) { .abs-remove-button-for-blocks { .lib-icon-font( - @icon-remove, - @_icon-font-size: 26px, - @_icon-font-line-height: 15px, - @_icon-font-text-hide: true, - @_icon-font-color: @color-gray19, - @_icon-font-color-hover: @color-gray19, - @_icon-font-color-active: @color-gray19 + @icon-remove, + @_icon-font-size: 26px, + @_icon-font-line-height: 15px, + @_icon-font-text-hide: true, + @_icon-font-color: @color-gray19, + @_icon-font-color-hover: @color-gray19, + @_icon-font-color-active: @color-gray19 ); } } @@ -289,14 +290,14 @@ > a { .lib-link( - @_link-color: @product-name-link__color, - @_link-text-decoration: @product-name-link__text-decoration, - @_link-color-visited: @product-name-link__color__visited, - @_link-text-decoration-visited: @product-name-link__text-decoration__visited, - @_link-color-hover: @product-name-link__color__hover, - @_link-text-decoration-hover: @product-name-link__text-decoration__hover, - @_link-color-active: @product-name-link__color__active, - @_link-text-decoration-active: @product-name-link__text-decoration__active + @_link-color: @product-name-link__color, + @_link-text-decoration: @product-name-link__text-decoration, + @_link-color-visited: @product-name-link__color__visited, + @_link-text-decoration-visited: @product-name-link__text-decoration__visited, + @_link-color-hover: @product-name-link__color__hover, + @_link-text-decoration-hover: @product-name-link__text-decoration__hover, + @_link-color-active: @product-name-link__color__active, + @_link-text-decoration-active: @product-name-link__text-decoration__active ); } } @@ -613,11 +614,11 @@ & when (@media-common = true) { .abs-navigation-icon { .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 34px, - @_icon-font-line-height: 1.2, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 34px, + @_icon-font-line-height: 1.2, + @_icon-font-position: after, + @_icon-font-display: block ); &:after { @@ -635,8 +636,8 @@ & when (@media-common = true) { .abs-split-button { .lib-dropdown-split( - @_options-selector : ~'.items', - @_dropdown-split-button-border-radius-fix: true + @_options-selector : ~'.items', + @_dropdown-split-button-border-radius-fix: true ); vertical-align: middle; } @@ -654,13 +655,13 @@ .abs-actions-addto-gridlist { .lib-icon-font( - @_icon-font-content: '', - @_icon-font-size: 29px, - @_icon-font-color: @addto-color, - @_icon-font-color-hover: @addto-hover-color, - @_icon-font-text-hide: true, - @_icon-font-vertical-align: middle, - @_icon-font-line-height: 24px + @_icon-font-content: '', + @_icon-font-size: 29px, + @_icon-font-color: @addto-color, + @_icon-font-color-hover: @addto-hover-color, + @_icon-font-text-hide: true, + @_icon-font-vertical-align: middle, + @_icon-font-line-height: 24px ); } } @@ -762,11 +763,11 @@ padding-right: 12px; position: relative; .lib-icon-font( - @icon-down, - @_icon-font-size: 26px, - @_icon-font-line-height: 10px, - @_icon-font-margin: 3px 0 0 0, - @_icon-font-position: after + @icon-down, + @_icon-font-size: 26px, + @_icon-font-line-height: 10px, + @_icon-font-margin: 3px 0 0 0, + @_icon-font-position: after ); &:after { @@ -777,16 +778,16 @@ &-expanded { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } .abs-tax-total-expanded { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } @@ -867,10 +868,10 @@ & when (@media-common = true) { .abs-icon-add { .lib-icon-font( - @_icon-font-content: @icon-expand, - @_icon-font-size: 10px, - @_icon-font-line-height: 10px, - @_icon-font-vertical-align: middle + @_icon-font-content: @icon-expand, + @_icon-font-size: 10px, + @_icon-font-line-height: 10px, + @_icon-font-vertical-align: middle ); } } @@ -878,12 +879,12 @@ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .abs-icon-add-mobile { .lib-icon-font( - @_icon-font-content: @icon-expand, - @_icon-font-size: 10px, - @_icon-font-line-height: 10px, - @_icon-font-vertical-align: middle, - @_icon-font-margin: 0 5px 0 0, - @_icon-font-display: block + @_icon-font-content: @icon-expand, + @_icon-font-size: 10px, + @_icon-font-line-height: 10px, + @_icon-font-vertical-align: middle, + @_icon-font-margin: 0 5px 0 0, + @_icon-font-display: block ); } } @@ -924,11 +925,11 @@ position: relative; .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 28px, - @_icon-font-text-hide: false, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 28px, + @_icon-font-text-hide: false, + @_icon-font-position: after, + @_icon-font-display: block ); &:after { @@ -1068,12 +1069,12 @@ font-weight: @font-weight__bold; .lib-link-as-button(); .lib-button( - @_button-padding: 7px 15px 7px 0, - @_button-icon-use: true, - @_button-font-content: @icon-prev, - @_button-icon-font-size: 32px, - @_button-icon-font-line-height: 16px, - @_button-icon-font-position: before + @_button-padding: 7px 15px 7px 0, + @_button-icon-use: true, + @_button-font-content: @icon-prev, + @_button-icon-font-size: 32px, + @_button-icon-font-line-height: 16px, + @_button-icon-font-position: before ); &:active { @@ -1083,9 +1084,9 @@ &.update { .lib-button-icon( - @icon-update, - @_icon-font-size: 32px, - @_icon-font-line-height: 16px + @icon-update, + @_icon-font-size: 32px, + @_icon-font-line-height: 16px ); padding-left: @indent__xs; } @@ -1160,7 +1161,7 @@ & when (@media-common = true) { .abs-field-date-input { - .lib-css(margin-right, @indent__s); + margin-right: @indent__s; width: calc(~'100% -' @icon-calendar__font-size + @indent__s); } } @@ -1175,7 +1176,7 @@ position: relative; input { - .lib-css(margin-right, @indent__s); + margin-right: @indent__s; width: calc(~'100% -' @checkout-tooltip-icon__font-size + @indent__s + @indent__xs); } } @@ -1193,12 +1194,12 @@ &:before, &:after { .lib-arrow( - @_position: top, - @_size: @checkout-tooltip-icon-arrow__font-size, - @_color: @checkout-tooltip-content__background-color + @_position: top, + @_size: @checkout-tooltip-icon-arrow__font-size, + @_color: @checkout-tooltip-content__background-color ); .lib-css(margin-top, @checkout-tooltip-icon-arrow__left); - .lib-css(right, @indent__s); + right: @indent__s; left: auto; top: 0; } @@ -1234,11 +1235,11 @@ .lib-css(border-bottom, @checkout-step-title__border); .lib-css(padding-bottom, @checkout-step-title__padding); .lib-typography( - @_font-size: @checkout-step-title__font-size, - @_font-weight: @checkout-step-title__font-weight, - @_font-family: false, - @_font-style: false, - @_line-height: false + @_font-size: @checkout-step-title__font-size, + @_font-weight: @checkout-step-title__font-weight, + @_font-family: false, + @_font-style: false, + @_line-height: false ); } } @@ -1299,11 +1300,11 @@ .amount .price { .lib-icon-font( - @icon-down, - @_icon-font-size: 30px, - @_icon-font-text-hide: true, - @_icon-font-position: after, - @_icon-font-display: block + @icon-down, + @_icon-font-size: 30px, + @_icon-font-text-hide: true, + @_icon-font-position: after, + @_icon-font-display: block ); padding-right: @indent__m; position: relative; @@ -1323,8 +1324,8 @@ .amount .price { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } } @@ -1332,7 +1333,7 @@ &-details { display: none; - .lib-css(border-bottom, @border-width__base solid @border-color__base); + border-bottom: @border-width__base solid @border-color__base; &.shown { display: table-row; @@ -1357,10 +1358,10 @@ cursor: pointer; font-weight: @font-weight__semibold; .lib-icon-font( - @_icon-font-content: @icon-down, - @_icon-font-size: 30px, - @_icon-font-position: after, - @_icon-font-display: block + @_icon-font-content: @icon-down, + @_icon-font-size: 30px, + @_icon-font-position: after, + @_icon-font-display: block ); margin-bottom: 0; overflow: hidden; @@ -1388,8 +1389,8 @@ &.active { > .title { .lib-icon-font-symbol( - @_icon-font-content: @icon-up, - @_icon-font-position: after + @_icon-font-content: @icon-up, + @_icon-font-position: after ); } From 8485195aaee3d02e0d4c3a5a5ed5694dab6ff3dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Tue, 30 Oct 2018 22:11:16 +0200 Subject: [PATCH 0922/1415] Update _toolbar.less --- .../web/css/source/module/_toolbar.less | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less index aceccb06d47f7..2468d2a3104e4 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less @@ -4,14 +4,17 @@ // */ // -// Common -// _____________________________________________ +// Variables +// --------------------------------------------- @toolbar-mode-icon-font-size: 24px; @toolbar-element-background: @panel__background-color; -& when (@media-common = true) { +// +// Common +// _____________________________________________ +& when (@media-common = true) { .page-products { .columns { position: relative; @@ -72,12 +75,12 @@ .sorter-action { vertical-align: top; .lib-icon-font( - @icon-arrow-up, - @_icon-font-size: 28px, - @_icon-font-line-height: 32px, - @_icon-font-color: @header-icons-color, - @_icon-font-color-hover: @header-icons-color-hover, - @_icon-font-text-hide: true + @icon-arrow-up, + @_icon-font-size: 28px, + @_icon-font-line-height: 32px, + @_icon-font-color: @header-icons-color, + @_icon-font-color-hover: @header-icons-color-hover, + @_icon-font-text-hide: true ); } @@ -99,7 +102,7 @@ } .limiter-label { - font-weight: 400; + font-weight: @font-weight__regular; } .limiter { @@ -176,11 +179,11 @@ } .lib-icon-font( - @icon-grid, - @_icon-font-size: @toolbar-mode-icon-font-size, - @_icon-font-text-hide: true, - @_icon-font-color: @text__color__muted, - @_icon-font-color-hover: @text__color__muted + @icon-grid, + @_icon-font-size: @toolbar-mode-icon-font-size, + @_icon-font-text-hide: true, + @_icon-font-color: @text__color__muted, + @_icon-font-color-hover: @text__color__muted ); } From 54f4802d5a9ef58418e395e8d12ab4931907d6eb Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Tue, 30 Oct 2018 21:32:40 +0100 Subject: [PATCH 0923/1415] #18956 Fixes for set root_category_id --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 513ba04802985..3142955ac5988 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,8 +177,8 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - $group->setData($groupData); $group->setRootCategoryId(0); + $group->setData($groupData); $group->getResource()->save($group); $group->getResource()->addCommitCallback(function () use ($data, $group, $website) { From d64351b30bf3ab566d42a4acf312c9b1a08045da Mon Sep 17 00:00:00 2001 From: Ayaz Mittaqi <ayaz.mittaqi024@webkul.com> Date: Wed, 31 Oct 2018 03:20:22 +0530 Subject: [PATCH 0924/1415] removed old string from catalog translation file --- app/code/Magento/Catalog/i18n/en_US.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index 06c072276f084..ed27dfd646cb2 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -233,7 +233,6 @@ Products,Products "This attribute set no longer exists.","This attribute set no longer exists." "You saved the attribute set.","You saved the attribute set." "Something went wrong while saving the attribute set.","Something went wrong while saving the attribute set." -"You added product %1 to the comparison list.","You added product %1 to the comparison list." "You cleared the comparison list.","You cleared the comparison list." "Something went wrong clearing the comparison list.","Something went wrong clearing the comparison list." "You removed product %1 from the comparison list.","You removed product %1 from the comparison list." From bbc75173ae7ae2b32139714de7616b07da51c845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Wed, 31 Oct 2018 09:06:08 +0200 Subject: [PATCH 0925/1415] Code clean up --- .../Magento_Checkout/web/css/source/module/_minicart.less | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less index 2219db1cf694d..d7ff3ba1e5732 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less @@ -125,7 +125,7 @@ float: right; .block-minicart { - padding: 25px @minicart__padding-horizontal; + .lib-css(padding, 25px @minicart__padding-horizontal); .block-title { display: none; @@ -205,8 +205,8 @@ } .minicart-items-wrapper { - border: 1px solid @minicart__border-color; - margin: 0 -@minicart__padding-horizontal; + .lib-css(border, 1px solid @minicart__border-color); + .lib-css(margin, 0 -@minicart__padding-horizontal); border-left: 0; border-right: 0; overflow-x: auto; @@ -220,7 +220,7 @@ padding: @indent__base 0; &:not(:first-child) { - border-top: 1px solid @minicart__border-color; + .lib-css(border-top, 1px solid @minicart__border-color); } &:first-child { From 0d5150ff3edd3544161841076d1f70a7ad8c72b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Wed, 31 Oct 2018 09:09:38 +0200 Subject: [PATCH 0926/1415] Code clean up --- app/design/frontend/Magento/blank/web/css/source/_extends.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/web/css/source/_extends.less b/app/design/frontend/Magento/blank/web/css/source/_extends.less index 4b328ab1015ed..5f24c0db8cc88 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_extends.less +++ b/app/design/frontend/Magento/blank/web/css/source/_extends.less @@ -1332,8 +1332,8 @@ } &-details { + .lib-css(border-bottom, @border-width__base solid @border-color__base); display: none; - border-bottom: @border-width__base solid @border-color__base; &.shown { display: table-row; From 93af83615f677eaa17eab74f9828fb2f8a7db0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Wed, 31 Oct 2018 09:13:02 +0200 Subject: [PATCH 0927/1415] code clean up --- .../Magento_Checkout/web/css/source/module/_minicart.less | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less index 14db9dd868e00..17fbdc8ba495b 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less @@ -128,7 +128,7 @@ float: right; .block-minicart { - padding: 25px @minicart__padding-horizontal; + .lib-css(padding, 25px @minicart__padding-horizontal); .block-title { display: none; @@ -216,8 +216,8 @@ } .minicart-items-wrapper { - border: 1px solid @minicart__border-color; - margin: 0 -@minicart__padding-horizontal; + .lib-css(border, 1px solid @minicart__border-color); + .lib-css(margin, 0 -@minicart__padding-horizontal); border-left: 0; border-right: 0; overflow-x: auto; @@ -231,7 +231,7 @@ padding: @indent__base 0; &:not(:first-child) { - border-top: 1px solid @minicart__border-color; + .lib-css(border-top, 1px solid @minicart__border-color); } &:first-child { From b135ec9c010f6a06649da1a30bf7778a52988a03 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 10:43:01 +0300 Subject: [PATCH 0928/1415] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fix unit test --- .../Test/Unit/Model/Condition/Sql/BuilderTest.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index 5d18ccef17e54..13bba8a6a28ab 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -119,13 +119,12 @@ public function testAttachConditionAsHtmlToCollection() \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, [ 'getResource', - 'getSelect', - 'getStoreId', - 'getDefaultStoreId', + 'getSelect' ] ); - $combine = $this->createPartialMock(\Magento\Rule\Model\Condition\Combine::class, + $combine = $this->createPartialMock( + \Magento\Rule\Model\Condition\Combine::class, [ 'getConditions', 'getValue', @@ -153,14 +152,6 @@ public function testAttachConditionAsHtmlToCollection() ->method('getResource') ->will($this->returnValue($resource)); - $collection->expects($this->once()) - ->method('getStoreId') - ->willReturn(1); - - $collection->expects($this->once()) - ->method('getDefaultStoreId') - ->willReturn(1); - $resource->expects($this->once()) ->method('getConnection') ->will($this->returnValue($connection)); From 8641218ebe978623fb1aa731544b76be99003448 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 31 Oct 2018 11:09:20 +0200 Subject: [PATCH 0929/1415] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../view/adminhtml/templates/browser/content/uploader.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index df0a74c48ac23..414d42cb45382 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -19,9 +19,9 @@ foreach ($filters as $media_type) { $resizeConfig = $block->getImageUploadConfigData()->getIsResizeEnabled() ? "{action: 'resize', maxWidth: " - . $block->getImageUploadMaxWidth() + . $block->escapeHtml($block->getImageUploadMaxWidth()) . ", maxHeight: " - . $block->getImageUploadMaxHeight() + . $block->escapeHtml($block->getImageUploadMaxHeight()) . "}" : "{action: 'resize'}"; ?> @@ -153,7 +153,7 @@ require([ fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 }, - <?= $block->escapeHtml($resizeConfig) ?>, + <?= /* @noEscape */ $resizeConfig ?>, { action: 'save' }] From 7fd52e7ea8f7c7f77702d1b7a4665e715eee1ac3 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Wed, 31 Oct 2018 11:31:19 +0200 Subject: [PATCH 0930/1415] Remove all possible native php functions & use framework components --- .../Model/Product/Gallery/Processor.php | 33 ++++++++++++------- composer.json | 1 - 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 225c502830695..048ad55985b72 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -57,25 +57,34 @@ class Processor */ protected $resourceModel; + /** + * @var \Magento\Framework\File\Mime + */ + protected $mime; + /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + * @param \Magento\Framework\File\Mime $mime + * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, - \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, + \Magento\Framework\File\Mime $mime ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; + $this->mime = $mime; } /** @@ -186,10 +195,10 @@ public function addImage( $position = 0; $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); - $imageMimeType = mime_content_type($absoluteFilePath); - $imageContent = file_get_contents($absoluteFilePath); + $imageMimeType = $this->mime->getMimeType($absoluteFilePath); + $imageContent = $this->mediaDirectory->readFile($absoluteFilePath); $imageBase64 = base64_encode($imageContent); - $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + $imageName = $pathinfo['filename']; if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; @@ -203,17 +212,17 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, - 'label' => '', - 'disabled' => (int)$exclude, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'types' => $mediaAttribute, - 'content' => [ + 'types' => $mediaAttribute, + 'content' => [ 'data' => [ - ImageContentInterface::NAME => $imageName, + ImageContentInterface::NAME => $imageName, ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, - ImageContentInterface::TYPE => $imageMimeType, + ImageContentInterface::TYPE => $imageMimeType, ] ] ]; diff --git a/composer.json b/composer.json index 68bf1f1d8a8b0..e2a646275d98b 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,6 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", - "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 88edd10e3cb93937e49fb04e30f4bd55ed3c7fd6 Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Wed, 31 Oct 2018 10:56:49 +0100 Subject: [PATCH 0931/1415] Fix numeric translation keys being dissolved by array_merge --- lib/internal/Magento/Framework/App/Language/Dictionary.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Language/Dictionary.php b/lib/internal/Magento/Framework/App/Language/Dictionary.php index 294490a665cbe..d9a5ccb00d892 100644 --- a/lib/internal/Magento/Framework/App/Language/Dictionary.php +++ b/lib/internal/Magento/Framework/App/Language/Dictionary.php @@ -111,7 +111,9 @@ public function getDictionary($languageCode) /** @var Config $languageConfig */ $languageConfig = $packInfo['language']; $dictionary = $this->readPackCsv($languageConfig->getVendor(), $languageConfig->getPackage()); - $result = array_merge($result, $dictionary); + foreach ($dictionary as $key => $value) { + $result[$key] = $value; + } } return $result; } From 64606aaa1d5ee4b57605b8572f641dbf471aec0d Mon Sep 17 00:00:00 2001 From: Sergey Shvets <wert2all@gmail.com> Date: Wed, 31 Oct 2018 12:21:47 +0200 Subject: [PATCH 0932/1415] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../Checkout/view/frontend/web/js/view/billing-address.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6a2f329d095d6..6f9a1a46826da 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -73,9 +73,7 @@ function ( quote.paymentMethod.subscribe(function () { checkoutDataResolver.resolveBillingAddress(); }, this); - shippingRatesValidator.initFields( - 'checkout.steps.billing-step.payment.payments-list.checkmo-form.form-fields' - ); + shippingRatesValidator.initFields(this.get('name') + '.form-fields'); }, /** From 3bfe826e29ea0d1a16416aa8c6bc164c562fb643 Mon Sep 17 00:00:00 2001 From: Peter Samoilov <samoilov@aheadworks.com> Date: Wed, 31 Oct 2018 13:56:29 +0300 Subject: [PATCH 0933/1415] Added default value(y) for confirmation question --- setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php index 64b934061b6c1..69c369f1ec9f6 100644 --- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php +++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php @@ -84,7 +84,8 @@ protected function execute(InputInterface $input, OutputInterface $output) if (($currentValue !== null) && ($inputOptions[$option->getName()] !== null)) { $dialog = $this->getHelperSet()->get('question'); $question = new Question( - '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]</question>' + '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]</question>', + 'y' ); if (strtolower($dialog->ask($input, $output, $question)) !== 'y') { $inputOptions[$option->getName()] = null; From bdce1b6d8bb67c00312e5d1c1693a0ca7b708a34 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 31 Oct 2018 13:23:05 +0200 Subject: [PATCH 0934/1415] ENGCOM-1928: Refactoring. --- app/code/Magento/Store/Block/Switcher.php | 20 ------ app/code/Magento/Store/ViewModel/Switcher.php | 72 +++++++++++++++++++ .../frontend/templates/switch/languages.phtml | 2 +- .../Theme/view/frontend/layout/default.xml | 7 +- 4 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 app/code/Magento/Store/ViewModel/Switcher.php diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php index e162a2a0abe16..f15349f11066d 100644 --- a/app/code/Magento/Store/Block/Switcher.php +++ b/app/code/Magento/Store/Block/Switcher.php @@ -265,24 +265,4 @@ public function getTargetStorePostData(Store $store, $data = []) $data ); } - - /** - * Returns target store redirect url. - * - * @param Store $store - * @return string - */ - public function getTargetStoreRedirectUrl(Store $store) - { - return $this->getUrl( - 'stores/store/redirect', - [ - '___store' => $store->getCode(), - '___from_store' => $this->getCurrentStoreCode(), - ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl( - $store->getCurrentUrl(false) - ), - ] - ); - } } diff --git a/app/code/Magento/Store/ViewModel/Switcher.php b/app/code/Magento/Store/ViewModel/Switcher.php new file mode 100644 index 0000000000000..b0d08f064073d --- /dev/null +++ b/app/code/Magento/Store/ViewModel/Switcher.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Store\ViewModel; + +use Magento\Framework\App\ActionInterface; +use Magento\Framework\Url\EncoderInterface; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Provides target store redirect url. + */ +class SwitcherUrlProvider implements \Magento\Framework\View\Element\Block\ArgumentInterface +{ + /** + * @var EncoderInterface + */ + private $encoder; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var UrlInterface + */ + private $urlBuilder; + + /** + * @param EncoderInterface $encoder + * @param StoreManagerInterface $storeManager + * @param UrlInterface $urlBuilder + */ + public function __construct( + EncoderInterface $encoder, + StoreManagerInterface $storeManager, + UrlInterface $urlBuilder + ) { + $this->encoder = $encoder; + $this->storeManager = $storeManager; + $this->urlBuilder = $urlBuilder; + } + + /** + * Returns target store redirect url. + * + * @param Store $store + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function getTargetStoreRedirectUrl(Store $store): string + { + return $this->urlBuilder->getUrl( + 'stores/store/redirect', + [ + '___store' => $store->getCode(), + '___from_store' => $this->storeManager->getStore()->getCode(), + ActionInterface::PARAM_NAME_URL_ENCODED => $this->encoder->encode( + $store->getCurrentUrl(false) + ), + ] + ); + } +} diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 411a1ef3c9a32..a620c2ce71407 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?= $block->escapeHtml($_lang->getCode()) ?> switcher-option"> - <a href="<?= $block->escapeUrl($block->getTargetStoreRedirectUrl($_lang)) ?>"> + <a href="<?= $block->escapeUrl($block->getViewModel()->getTargetStoreRedirectUrl($_lang)) ?>"> <?= $block->escapeHtml($_lang->getName()) ?> </a> </li> diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index 716341f5a64a4..d6ec289edaa92 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -39,7 +39,11 @@ <argument name="label" translate="true" xsi:type="string">Skip to Content</argument> </arguments> </block> - <block class="Magento\Store\Block\Switcher" name="store_language" as="store_language" template="Magento_Store::switch/languages.phtml"/> + <block class="Magento\Store\Block\Switcher" name="store_language" as="store_language" template="Magento_Store::switch/languages.phtml"> + <arguments> + <argument name="view_model" xsi:type="object">Magento\Store\ViewModel\SwitcherUrlProvider</argument> + </arguments> + </block> <block class="Magento\Customer\Block\Account\Navigation" name="top.links"> <arguments> <argument name="css_class" xsi:type="string">header links</argument> @@ -82,6 +86,7 @@ <block class="Magento\Store\Block\Switcher" name="store.settings.language" template="Magento_Store::switch/languages.phtml"> <arguments> <argument name="id_modifier" xsi:type="string">nav</argument> + <argument name="view_model" xsi:type="object">Magento\Store\ViewModel\SwitcherUrlProvider</argument> </arguments> </block> <block class="Magento\Directory\Block\Currency" name="store.settings.currency" template="Magento_Directory::currency.phtml"> From 80da4ea87544caa583ab1c90ed251ea946a8be51 Mon Sep 17 00:00:00 2001 From: prakashpatel07 <prakash.patel@krishtechnolabs.com> Date: Wed, 31 Oct 2018 13:38:55 +0000 Subject: [PATCH 0935/1415] Fixed Last Logged-in date when customer authenticate via REST API. --- .../Integration/Model/CustomerTokenService.php | 13 ++++++++++++- .../Test/Unit/Model/CustomerTokenServiceTest.php | 8 +++++++- .../Magento/Integration/etc/webapi_rest/events.xml | 12 ++++++++++++ .../Magento/Integration/etc/webapi_soap/events.xml | 12 ++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Integration/etc/webapi_rest/events.xml create mode 100644 app/code/Magento/Integration/etc/webapi_soap/events.xml diff --git a/app/code/Magento/Integration/Model/CustomerTokenService.php b/app/code/Magento/Integration/Model/CustomerTokenService.php index 3c245804a9f6e..35d0424d3b4fa 100644 --- a/app/code/Magento/Integration/Model/CustomerTokenService.php +++ b/app/code/Magento/Integration/Model/CustomerTokenService.php @@ -14,6 +14,7 @@ use Magento\Integration\Model\ResourceModel\Oauth\Token\CollectionFactory as TokenCollectionFactory; use Magento\Integration\Model\Oauth\Token\RequestThrottler; use Magento\Framework\Exception\AuthenticationException; +use Magento\Framework\Event\ManagerInterface; class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServiceInterface { @@ -24,6 +25,11 @@ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServ */ private $tokenModelFactory; + /** + * @var Magento\Framework\Event\ManagerInterface + */ + private $eventManager; + /** * Customer Account Service * @@ -55,17 +61,21 @@ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServ * @param AccountManagementInterface $accountManagement * @param TokenCollectionFactory $tokenModelCollectionFactory * @param \Magento\Integration\Model\CredentialsValidator $validatorHelper + * @param \Magento\Framework\Event\ManagerInterface $eventManager */ public function __construct( TokenModelFactory $tokenModelFactory, AccountManagementInterface $accountManagement, TokenCollectionFactory $tokenModelCollectionFactory, - CredentialsValidator $validatorHelper + CredentialsValidator $validatorHelper, + ManagerInterface $eventManager = null ) { $this->tokenModelFactory = $tokenModelFactory; $this->accountManagement = $accountManagement; $this->tokenModelCollectionFactory = $tokenModelCollectionFactory; $this->validatorHelper = $validatorHelper; + $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(ManagerInterface::class); } /** @@ -86,6 +96,7 @@ public function createCustomerAccessToken($username, $password) ) ); } + $this->eventManager->dispatch('customer_login', ['customer' => $customerDataObject]); $this->getRequestThrottler()->resetAuthenticationFailuresCount($username, RequestThrottler::USER_TYPE_CUSTOMER); return $this->tokenModelFactory->create()->createCustomerToken($customerDataObject->getId())->getToken(); } diff --git a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php index 1a7c819343294..1bc7d4247080f 100644 --- a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php +++ b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php @@ -32,6 +32,9 @@ class CustomerTokenServiceTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Integration\Model\Oauth\Token|\PHPUnit_Framework_MockObject_MockObject */ private $_tokenMock; + /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $manager; + protected function setUp() { $this->_tokenFactoryMock = $this->getMockBuilder(\Magento\Integration\Model\Oauth\TokenFactory::class) @@ -67,11 +70,14 @@ protected function setUp() \Magento\Integration\Model\CredentialsValidator::class )->disableOriginalConstructor()->getMock(); + $this->manager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); + $this->_tokenService = new \Magento\Integration\Model\CustomerTokenService( $this->_tokenFactoryMock, $this->_accountManagementMock, $this->_tokenModelCollectionFactoryMock, - $this->validatorHelperMock + $this->validatorHelperMock, + $this->manager ); } diff --git a/app/code/Magento/Integration/etc/webapi_rest/events.xml b/app/code/Magento/Integration/etc/webapi_rest/events.xml new file mode 100644 index 0000000000000..e978698734277 --- /dev/null +++ b/app/code/Magento/Integration/etc/webapi_rest/events.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> + <event name="customer_login"> + <observer name="customer_log_login" instance="Magento\Customer\Observer\LogLastLoginAtObserver" /> + </event> +</config> diff --git a/app/code/Magento/Integration/etc/webapi_soap/events.xml b/app/code/Magento/Integration/etc/webapi_soap/events.xml new file mode 100644 index 0000000000000..e978698734277 --- /dev/null +++ b/app/code/Magento/Integration/etc/webapi_soap/events.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> + <event name="customer_login"> + <observer name="customer_log_login" instance="Magento\Customer\Observer\LogLastLoginAtObserver" /> + </event> +</config> From 02192264fb25a7bf4d61326650d03a7205b0c940 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 16:45:01 +0300 Subject: [PATCH 0936/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static test --- .../view/adminhtml/web/js/grouped-product-grid.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c1a35cb0afede..f257cb2df729e 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -9,6 +9,7 @@ define([ 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid' ], function (_, registry, dynamicRowsGrid) { 'use strict'; + return dynamicRowsGrid.extend({ /** @@ -191,15 +192,6 @@ define([ return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); }, - /** - * Returns start index for current page - * - * @return {number} - */ - getStartIndex() { - return (~~this.currentPage() - 1) * this.pageSize; - }, - /** * Return Page Boundary * @@ -214,7 +206,7 @@ define([ * * @return {number} */ - getGlobalMaxPosition() { + getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { return ~~r.position })); From fff8dd3fae6aa65e19d7a5f539123b71d40c7078 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 16:54:25 +0300 Subject: [PATCH 0937/1415] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fix static test --- .../Unit/Model/Condition/Sql/BuilderTest.php | 79 ++++--------------- 1 file changed, 17 insertions(+), 62 deletions(-) diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index 13bba8a6a28ab..9dcbbd18c4c20 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -91,30 +91,13 @@ public function testAttachConditionAsHtmlToCollection() ['getOperatorForValidate', 'getMappedSqlField', 'getAttribute', 'getBindArgumentValue'] ); - $abstractCondition->expects($this->once()) - ->method('getMappedSqlField') - ->will($this->returnValue('argument')); - - $abstractCondition->expects($this->once()) - ->method('getOperatorForValidate') - ->will($this->returnValue('>')); - - $abstractCondition->expects($this->at(1)) - ->method('getAttribute') - ->will($this->returnValue('attribute')); - - $abstractCondition->expects($this->at(2)) - ->method('getAttribute') - ->will($this->returnValue('attribute')); - - $abstractCondition->expects($this->once()) - ->method('getBindArgumentValue') - ->will($this->returnValue(10)); - - $conditions = [ - $abstractCondition - ]; + $abstractCondition->expects($this->once())->method('getMappedSqlField')->will($this->returnValue('argument')); + $abstractCondition->expects($this->once())->method('getOperatorForValidate')->will($this->returnValue('>')); + $abstractCondition->expects($this->at(1))->method('getAttribute')->will($this->returnValue('attribute')); + $abstractCondition->expects($this->at(2))->method('getAttribute')->will($this->returnValue('attribute')); + $abstractCondition->expects($this->once())->method('getBindArgumentValue')->will($this->returnValue(10)); + $conditions = [$abstractCondition]; $collection = $this->createPartialMock( \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, [ @@ -122,7 +105,6 @@ public function testAttachConditionAsHtmlToCollection() 'getSelect' ] ); - $combine = $this->createPartialMock( \Magento\Rule\Model\Condition\Combine::class, [ @@ -131,10 +113,10 @@ public function testAttachConditionAsHtmlToCollection() 'getAggregator' ] ); + $resource = $this->createPartialMock(\Magento\Framework\DB\Adapter\Pdo\Mysql::class, ['getConnection']); $select = $this->createPartialMock(\Magento\Framework\DB\Select::class, ['where']); - $select->expects($this->never()) - ->method('where'); + $select->expects($this->never())->method('where'); $connection = $this->getMockForAbstractClass( \Magento\Framework\DB\Adapter\AdapterInterface::class, @@ -143,42 +125,15 @@ public function testAttachConditionAsHtmlToCollection() false ); - $connection->expects($this->once()) - ->method('quoteInto') - ->with(' > ?', 10) - ->will($this->returnValue(' > 10')); - - $collection->expects($this->once()) - ->method('getResource') - ->will($this->returnValue($resource)); - - $resource->expects($this->once()) - ->method('getConnection') - ->will($this->returnValue($connection)); - - $combine->expects($this->once()) - ->method('getValue') - ->willReturn('attribute'); - - $combine->expects($this->once()) - ->method('getAggregator') - ->willReturn(' AND '); - - $combine->expects($this->at(0)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(1)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(2)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(3)) - ->method('getConditions') - ->will($this->returnValue($conditions)); + $connection->expects($this->once())->method('quoteInto')->with(' > ?', 10)->will($this->returnValue(' > 10')); + $collection->expects($this->once())->method('getResource')->will($this->returnValue($resource)); + $resource->expects($this->once())->method('getConnection')->will($this->returnValue($connection)); + $combine->expects($this->once())->method('getValue')->willReturn('attribute'); + $combine->expects($this->once())->method('getAggregator')->willReturn(' AND '); + $combine->expects($this->at(0))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(1))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(2))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(3))->method('getConditions')->will($this->returnValue($conditions)); $this->_builder->attachConditionToCollection($collection, $combine); } From 9f568fb21b4c211c85fcf675fb504d2c1971be4d Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Wed, 31 Oct 2018 16:15:03 +0200 Subject: [PATCH 0938/1415] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepository.php | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index 43ae2db0c2163..a053eee5cd09b 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -8,69 +8,80 @@ use Magento\Customer\Api\CustomerMetadataInterface; use Magento\Customer\Api\Data\CustomerInterface; -use Magento\Customer\Model\Delegation\Data\NewOperation; +use Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Customer\Model\CustomerFactory; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Customer\Model\Data\CustomerSecureFactory; use Magento\Customer\Model\Customer\NotificationStorage; +use Magento\Customer\Model\Delegation\Data\NewOperation; +use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\Api\ImageProcessorInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Event\ManagerInterface; use Magento\Customer\Model\Delegation\Storage as DelegatedStorage; use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\StoreManagerInterface; /** * Customer repository. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ -class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInterface +class CustomerRepository implements CustomerRepositoryInterface { /** - * @var \Magento\Customer\Model\CustomerFactory + * @var CustomerFactory */ protected $customerFactory; /** - * @var \Magento\Customer\Model\Data\CustomerSecureFactory + * @var CustomerSecureFactory */ protected $customerSecureFactory; /** - * @var \Magento\Customer\Model\CustomerRegistry + * @var CustomerRegistry */ protected $customerRegistry; /** - * @var \Magento\Customer\Model\ResourceModel\AddressRepository + * @var AddressRepository */ protected $addressRepository; /** - * @var \Magento\Customer\Model\ResourceModel\Customer + * @var Customer */ protected $customerResourceModel; /** - * @var \Magento\Customer\Api\CustomerMetadataInterface + * @var CustomerMetadataInterface */ protected $customerMetadata; /** - * @var \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory + * @var CustomerSearchResultsInterfaceFactory */ protected $searchResultsFactory; /** - * @var \Magento\Framework\Event\ManagerInterface + * @var ManagerInterface */ protected $eventManager; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $storeManager; /** - * @var \Magento\Framework\Api\ExtensibleDataObjectConverter + * @var ExtensibleDataObjectConverter */ protected $extensibleDataObjectConverter; @@ -85,7 +96,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte protected $imageProcessor; /** - * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface + * @var JoinProcessorInterface */ protected $extensionAttributesJoinProcessor; @@ -105,38 +116,38 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte private $delegatedStorage; /** - * @param \Magento\Customer\Model\CustomerFactory $customerFactory - * @param \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory - * @param \Magento\Customer\Model\CustomerRegistry $customerRegistry - * @param \Magento\Customer\Model\ResourceModel\AddressRepository $addressRepository - * @param \Magento\Customer\Model\ResourceModel\Customer $customerResourceModel - * @param \Magento\Customer\Api\CustomerMetadataInterface $customerMetadata - * @param \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory - * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter + * @param CustomerFactory $customerFactory + * @param CustomerSecureFactory $customerSecureFactory + * @param CustomerRegistry $customerRegistry + * @param AddressRepository $addressRepository + * @param Customer $customerResourceModel + * @param CustomerMetadataInterface $customerMetadata + * @param CustomerSearchResultsInterfaceFactory $searchResultsFactory + * @param ManagerInterface $eventManager + * @param StoreManagerInterface $storeManager + * @param ExtensibleDataObjectConverter $extensibleDataObjectConverter * @param DataObjectHelper $dataObjectHelper * @param ImageProcessorInterface $imageProcessor - * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param JoinProcessorInterface $extensionAttributesJoinProcessor * @param CollectionProcessorInterface $collectionProcessor * @param NotificationStorage $notificationStorage * @param DelegatedStorage|null $delegatedStorage * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Customer\Model\CustomerFactory $customerFactory, - \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory, - \Magento\Customer\Model\CustomerRegistry $customerRegistry, - \Magento\Customer\Model\ResourceModel\AddressRepository $addressRepository, - \Magento\Customer\Model\ResourceModel\Customer $customerResourceModel, - \Magento\Customer\Api\CustomerMetadataInterface $customerMetadata, - \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory, - \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, + CustomerFactory $customerFactory, + CustomerSecureFactory $customerSecureFactory, + CustomerRegistry $customerRegistry, + AddressRepository $addressRepository, + Customer $customerResourceModel, + CustomerMetadataInterface $customerMetadata, + CustomerSearchResultsInterfaceFactory $searchResultsFactory, + ManagerInterface $eventManager, + StoreManagerInterface $storeManager, + ExtensibleDataObjectConverter $extensibleDataObjectConverter, DataObjectHelper $dataObjectHelper, ImageProcessorInterface $imageProcessor, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor, NotificationStorage $notificationStorage, DelegatedStorage $delegatedStorage = null @@ -156,8 +167,7 @@ public function __construct( $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; $this->collectionProcessor = $collectionProcessor; $this->notificationStorage = $notificationStorage; - $this->delegatedStorage = $delegatedStorage - ?? ObjectManager::getInstance()->get(DelegatedStorage::class); + $this->delegatedStorage = $delegatedStorage ?? ObjectManager::getInstance()->get(DelegatedStorage::class); } /** @@ -200,13 +210,13 @@ public function save(CustomerInterface $customer, $passwordHash = null) $customerModel->setRpToken(null); $customerModel->setRpTokenCreatedAt(null); } - if (!array_key_exists('default_billing', $customerArr) + if (!array_key_exists('addresses', $customerArr) && null !== $prevCustomerDataArr && array_key_exists('default_billing', $prevCustomerDataArr) ) { $customerModel->setDefaultBilling($prevCustomerDataArr['default_billing']); } - if (!array_key_exists('default_shipping', $customerArr) + if (!array_key_exists('addresses', $customerArr) && null !== $prevCustomerDataArr && array_key_exists('default_shipping', $prevCustomerDataArr) ) { @@ -371,15 +381,12 @@ public function deleteById($customerId) * Helper function that adds a FilterGroup to the collection. * * @deprecated 100.2.0 - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param \Magento\Customer\Model\ResourceModel\Customer\Collection $collection + * @param FilterGroup $filterGroup + * @param Collection $collection * @return void - * @throws \Magento\Framework\Exception\InputException */ - protected function addFilterGroupToCollection( - \Magento\Framework\Api\Search\FilterGroup $filterGroup, - \Magento\Customer\Model\ResourceModel\Customer\Collection $collection - ) { + protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) + { $fields = []; foreach ($filterGroup->getFilters() as $filter) { $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; From 24b690fbc3610641c674f88893fd01b0aab70118 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 17:19:46 +0300 Subject: [PATCH 0939/1415] MAGETWO-91649: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fix static test --- .../Observer/CategoryUrlPathAutogeneratorObserver.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index 5c7a8b16a666e..d692918aff6a6 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -14,6 +14,9 @@ use Magento\Framework\Event\ObserverInterface; use Magento\Store\Model\Store; +/** + * Class for set or update url path. + */ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface { /** @@ -55,6 +58,8 @@ public function __construct( } /** + * Method for update/set url path. + * * @param \Magento\Framework\Event\Observer $observer * @return void * @throws \Magento\Framework\Exception\LocalizedException @@ -81,6 +86,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) } /** + * Update url path for children category. + * * @param Category $category * @return void */ @@ -121,6 +128,8 @@ protected function isGlobalScope($storeId) } /** + * Update url path for category. + * * @param Category $category * @return void */ From 7daec41bcf5451b2ca7cb11b3e4784a9049f090c Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 31 Oct 2018 09:39:34 -0500 Subject: [PATCH 0940/1415] MAGETWO-94313: Random test failures on jenkins - unskip Magento\Reports\Test\TestCase\ProductsInCartReportEntityTest --- .../Reports/Test/TestCase/ProductsInCartReportEntityTest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml index fd0d169967161..e13d31342dba1 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml @@ -8,14 +8,12 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Reports\Test\TestCase\ProductsInCartReportEntityTest" summary="Products In Cart Report" ticketId="MAGETWO-27952"> <variation name="ProductsInCartReportEntityVariation1"> - <data name="issue" xsi:type="string">MQE-1160</data> <data name="product/dataset" xsi:type="string">default</data> <data name="carts" xsi:type="string">1</data> <data name="isGuest" xsi:type="string">0</data> <constraint name="Magento\Reports\Test\Constraint\AssertProductInCartResult" /> </variation> <variation name="ProductsInCartReportEntityVariation2"> - <data name="issue" xsi:type="string">MQE-1160</data> <data name="product/dataset" xsi:type="string">default</data> <data name="carts" xsi:type="string">2</data> <data name="isGuest" xsi:type="string">1</data> From 07c2d7a3447e6c8079e02e331777e00ba835e6ed Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Wed, 31 Oct 2018 16:53:51 +0200 Subject: [PATCH 0941/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../Test/Mftf/Page/AdminProductCreatePage.xml | 1 + ...minProductFormAdvancedInventorySection.xml | 37 +++++++++ .../Mftf/Section/AdminProductFormSection.xml | 1 + ...IncrementsWorkWithDecimalinventoryTest.xml | 75 +++++++++++++++++++ .../Section/StorefrontQuickSearchSection.xml | 2 +- 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml index fc776b49ba213..b3ed3f478f810 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml @@ -17,5 +17,6 @@ <section name="AdminProductMessagesSection"/> <section name="AdminProductFormRelatedUpSellCrossSellSection"/> <section name="AdminProductFormAdvancedPricingSection"/> + <section name="AdminProductFormAdvancedInventorySection"/> </page> </pages> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml new file mode 100644 index 0000000000000..e1272899b78ab --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminProductFormAdvancedInventorySection"> + <!--<element name="customerGroupPriceAddButton" type="button" selector="[data-action='add_new_row']" timeout="30"/>--> + <!--<element name="customerGroupPriceDeleteButton" type="button" selector="[data-action='remove_row']" timeout="30"/>--> + <!--<element name="advancedPricingCloseButton" type="button" selector=".product_form_product_form_advanced_pricing_modal button.action-close" timeout="30"/>--> + <!--<element name="productTierPriceWebsiteSelect" type="select" selector="[name='product[tier_price][{{var1}}][website_id]']" parameterized="true"/>--> + <!--<element name="productTierPriceCustGroupSelect" type="select" selector="[name='product[tier_price][{{var1}}][cust_group]']" parameterized="true"/>--> + <!--<element name="productTierPriceQtyInput" type="input" selector="[name='product[tier_price][{{var1}}][price_qty]']" parameterized="true"/>--> + <!--<element name="productTierPriceValueTypeSelect" type="select" selector="[name='product[tier_price][{{var1}}][value_type]']" parameterized="true"/>--> + <!--<element name="productTierPriceFixedPriceInput" type="input" selector="[name='product[tier_price][{{var1}}][price]']" parameterized="true"/>--> + <!--<element name="productTierPricePercentageValuePriceInput" type="input" selector="[name='product[tier_price][{{var1}}][percentage_value]']" parameterized="true"/>--> + <!--<element name="specialPrice" type="input" selector="input[name='product[special_price]']"/>--> + + <element name="enableQtyIncrements" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']"/> + <element name="enableQtyIncrementsOptions" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> + <element name="enableQtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_enable_qty_inc]']"/> + <element name="qtyUsesDecimals" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']"/> + <element name="qtyUsesDecimalsOptions" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> + <element name="qtyIncrements" type="input" selector="//input[@name='product[stock_data][qty_increments]']"/> + <element name="qtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_qty_increments]']"/> + + <element name="doneButton" type="button" selector="//aside[contains(@class,'product_form_product_form_advanced_inventory_modal')]//button[contains(@data-role,'action')]" timeout="5"/> + </section> +</sections> + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 03df9d2a88107..9ec0dbf9f262c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -28,6 +28,7 @@ <element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/> <element name="categoriesDropdown" type="multiselect" selector="div[data-index='category_ids']"/> <element name="productQuantity" type="input" selector=".admin__field[data-index=qty] input"/> + <element name="advancedInventoryLink" type="input" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> <element name="productStockStatus" type="select" selector="select[name='product[quantity_and_stock_status][is_in_stock]']"/> <element name="productWeight" type="input" selector=".admin__field[data-index=weight] input"/> <element name="productWeightSelect" type="select" selector="select[name='product[product_has_weight]']"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml new file mode 100644 index 0000000000000..7a774c585c9cd --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -0,0 +1,75 @@ +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> + <annotations> + <features value="Tiered pricing and quantity increments work with decimal inventory"/> + <stories value="Tiered pricing and quantity increments work with decimal inventory"/> + <title value="Tiered pricing and quantity increments work with decimal inventory"/> + <description value="Tiered pricing and quantity increments work with decimal inventory"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-91178"/> + <group value="product"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct" stepKey="createPreReqSimpleProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + </before> + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqSimpleProduct" stepKey="deletePreReqSimpleProduct"/> + </after> + <!--Step1. Login as admin. Go to Catalog > Products page. Filtering *prod1*. Open *prod1* to edit--> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin" /> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions"> + <argument name="product" value="SimpleProduct"/> + </actionGroup> + <click selector="{{AdminProductGridSection.productGridNameProduct('$$createPreReqSimpleProduct.name$$')}}" + stepKey="clickOpenProductForEdit"/> + <waitForPageLoad time="30" stepKey="waitForProductEditOpen"/> + <!--Step2. Open *Advanced Inventory* pop-up (Click on *Advanced Inventory* link). Set *Qty Uses Decimals* to *Yes*. Click on button *Done* --> + <click selector="{{AdminProductFormSection.advancedInventoryLink}}" stepKey="clickOnAdvancedInventoryLink"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimals}}" stepKey="scrollToQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimals}}" stepKey="clickOnQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimalsOptions('1')}}" stepKey="chooseYesOnQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton"/> + <!--Step3. Open *Advanced Pricing* pop-up (Click on *Advanced Pricing* link). Click on *Add* button. Fill *0.5* in *Quantity*--> + <scrollTo selector="{{AdminProductFormSection.productName}}" stepKey="scrollToProductName"/> + <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink1"/> + <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="clickOnCustomerGroupPriceAddButton"/> + <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="0.5" stepKey="fillProductTierPriceQty"/> + <!--Step4. Close *Advanced Pricing* (Click on button *Done*). Save *prod1* (Click on button *Save*)--> + <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickOnDoneButton2"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton"/> + + <!--The code should be uncommented after fix MAGETWO-96016--> + <!--<click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink2"/>--> + <!--<seeInField userInput="0.5" selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" stepKey="seeInField1"/>--> + <!--<click selector="{{AdminProductFormAdvancedPricingSection.advancedPricingCloseButton}}" stepKey="clickOnCloseButton"/>--> + + <!--Step5. Open *Advanced Inventory* pop-up. Set *Enable Qty Increments* to *Yes*. Fill *.5* in *Qty Increments*--> + <click selector="{{AdminProductFormSection.advancedInventoryLink}}" stepKey="clickOnAdvancedInventoryLink2"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="scrollToEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsUseConfigSettings}}" stepKey="clickOnEnableQtyIncrementsUseConfigSettingsCheckbox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="clickOnEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsOptions(('1'))}}" stepKey="chooseYesOnEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="clickOnQtyIncrementsUseConfigSettings"/> + <fillField selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" userInput=".5" stepKey="fillQtyIncrements"/> + <!--Step6. Close *Advanced Inventory* (Click on button *Done*). Save *prod1* (Click on button *Save*) --> + <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton3"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton2"/> + <!--Step7. Open *Customer view* (Go to *Store Front*). Open *prod1* page (Find via search and click on product name) --> + <amOnPage url="{{StorefrontHomePage.url}}$$createPreReqSimpleProduct.custom_attributes[url_key]$$.html" stepKey="amOnProductPage"/> + <!--Step8. Fill *1.5* in *Qty*. Click on button *Add to Cart*--> + <fillField selector="{{StorefrontProductPageSection.qtyInput}}" userInput="1.5" stepKey="fillQty"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="clickOnAddToCart"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createPreReqSimpleProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <!--Step9. Click on *Cart* icon. Click on *View and Edit Cart* link. Change *Qty* value to *5.5*--> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToShoppingCartFromMinicart"/> + <fillField selector="{{CheckoutCartProductSection.ProductQuantityByName(('$$createPreReqSimpleProduct.name$$'))}}" userInput="5.5" stepKey="fillQty2"/> + <click selector="{{CheckoutCartProductSection.updateShoppingCartButton}}" stepKey="clickOnUpdateShoppingCartButton"/> + <seeInField userInput="5.5" selector="{{CheckoutCartProductSection.ProductQuantityByName(('$$createPreReqSimpleProduct.name$$'))}}" stepKey="seeInField2"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml index 2b08e9b4b85ec..6baa3ff54fca0 100644 --- a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml +++ b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontQuickSearchSection"> + <section name="StorefrontQuickSearchSection">/ <element name="searchPhrase" type="input" selector="#search"/> <element name="searchButton" type="button" selector="button.action.search" timeout="30"/> </section> From 3e94424757aa1b8ad2febc89617f5b199057b8ec Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Wed, 31 Oct 2018 17:12:26 +0200 Subject: [PATCH 0942/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../AdminProductFormAdvancedInventorySection.xml | 12 ------------ .../Mftf/Section/StorefrontQuickSearchSection.xml | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml index e1272899b78ab..0314534dcddfb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml @@ -9,17 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductFormAdvancedInventorySection"> - <!--<element name="customerGroupPriceAddButton" type="button" selector="[data-action='add_new_row']" timeout="30"/>--> - <!--<element name="customerGroupPriceDeleteButton" type="button" selector="[data-action='remove_row']" timeout="30"/>--> - <!--<element name="advancedPricingCloseButton" type="button" selector=".product_form_product_form_advanced_pricing_modal button.action-close" timeout="30"/>--> - <!--<element name="productTierPriceWebsiteSelect" type="select" selector="[name='product[tier_price][{{var1}}][website_id]']" parameterized="true"/>--> - <!--<element name="productTierPriceCustGroupSelect" type="select" selector="[name='product[tier_price][{{var1}}][cust_group]']" parameterized="true"/>--> - <!--<element name="productTierPriceQtyInput" type="input" selector="[name='product[tier_price][{{var1}}][price_qty]']" parameterized="true"/>--> - <!--<element name="productTierPriceValueTypeSelect" type="select" selector="[name='product[tier_price][{{var1}}][value_type]']" parameterized="true"/>--> - <!--<element name="productTierPriceFixedPriceInput" type="input" selector="[name='product[tier_price][{{var1}}][price]']" parameterized="true"/>--> - <!--<element name="productTierPricePercentageValuePriceInput" type="input" selector="[name='product[tier_price][{{var1}}][percentage_value]']" parameterized="true"/>--> - <!--<element name="specialPrice" type="input" selector="input[name='product[special_price]']"/>--> - <element name="enableQtyIncrements" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']"/> <element name="enableQtyIncrementsOptions" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> <element name="enableQtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_enable_qty_inc]']"/> @@ -27,7 +16,6 @@ <element name="qtyUsesDecimalsOptions" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> <element name="qtyIncrements" type="input" selector="//input[@name='product[stock_data][qty_increments]']"/> <element name="qtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_qty_increments]']"/> - <element name="doneButton" type="button" selector="//aside[contains(@class,'product_form_product_form_advanced_inventory_modal')]//button[contains(@data-role,'action')]" timeout="5"/> </section> </sections> diff --git a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml index 6baa3ff54fca0..2b08e9b4b85ec 100644 --- a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml +++ b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontQuickSearchSection">/ + <section name="StorefrontQuickSearchSection"> <element name="searchPhrase" type="input" selector="#search"/> <element name="searchButton" type="button" selector="button.action.search" timeout="30"/> </section> From d70ff4be68f9e084cc4e11de4092a6775e452b92 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 31 Oct 2018 10:38:14 -0500 Subject: [PATCH 0943/1415] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - fix unit and static tests --- .../Validation/CreationQuantityValidator.php | 5 +++++ .../Sales/Model/Order/ItemRepository.php | 4 ++-- .../Unit/Model/Order/ItemRepositoryTest.php | 22 +++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php index fdc5e2658b9ed..93a4e701e0322 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php @@ -30,6 +30,7 @@ class CreationQuantityValidator implements ValidatorInterface /** * ItemCreationQuantityValidator constructor. + * * @param OrderItemRepositoryInterface $orderItemRepository * @param mixed $context */ @@ -65,6 +66,8 @@ public function validate($entity) } /** + * Check the quantity to refund is greater than the unrefunded quantity + * * @param Item $orderItem * @param int $qty * @return bool @@ -75,6 +78,8 @@ private function isQtyAvailable(Item $orderItem, $qty) } /** + * Check to see if Item is part of the order + * * @param OrderItemInterface $orderItem * @return bool */ diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 2ea9831336cc2..b1ff747d4f487 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -95,7 +95,7 @@ public function __construct( } /** - * load entity + * Load entity * * @param int $id * @return OrderItemInterface @@ -230,7 +230,7 @@ private function addParentItem(OrderItemInterface $orderItem) $orderItem->setParentItem($this->get($parentId)); } else { foreach ($orderItem->getOrder()->getAllItems() as $item) { - if($item->getParentItemId() === $orderItem->getItemId()) { + if ($item->getParentItemId() === $orderItem->getItemId()) { $item->setParentItem($orderItem); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index 8be2c3c8612d7..c19b4cbc3cb50 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -156,18 +156,27 @@ public function testGet() $productOption = $this->getProductOptionMock(); $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); + $orderMock->expects($this->once()) + ->method('getAllItems') + ->willReturn([$orderItemMock]); + $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) + $orderItemMock->expects($this->exactly(2)) ->method('getItemId') ->willReturn($orderItemId); + $orderItemMock->expects($this->once()) + ->method('getOrder') + ->willReturn($orderMock); $this->metadata->expects($this->once()) ->method('getNewInstance') ->willReturn($orderItemMock); + $model = $this->getModel($orderItemMock, $productType); $this->assertSame($orderItemMock, $model->get($orderItemId)); @@ -213,11 +222,17 @@ public function testDeleteById() $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) ->disableOriginalConstructor() ->getMock(); + + $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); + $orderMock->expects($this->once()) + ->method('getAllItems') + ->willReturn([$orderItemMock]); + $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) + $orderItemMock->expects($this->exactly(2)) ->method('getItemId') ->willReturn($orderItemId); $orderItemMock->expects($this->once()) @@ -226,6 +241,9 @@ public function testDeleteById() $orderItemMock->expects($this->once()) ->method('getBuyRequest') ->willReturn($requestMock); + $orderItemMock->expects($this->once()) + ->method('getOrder') + ->willReturn($orderMock); $orderItemResourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) ->disableOriginalConstructor() From 413a03686976ccf06c240783ddfdd2632af6d7cc Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 31 Oct 2018 13:15:39 -0500 Subject: [PATCH 0944/1415] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - remove empty line --- .../Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index c19b4cbc3cb50..5e1b49c0013e3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -176,7 +176,6 @@ public function testGet() ->method('getNewInstance') ->willReturn($orderItemMock); - $model = $this->getModel($orderItemMock, $productType); $this->assertSame($orderItemMock, $model->get($orderItemId)); From 9cd11c65105f64cdcbced489739221b7bc6312f9 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Wed, 31 Oct 2018 13:37:42 -0500 Subject: [PATCH 0945/1415] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT - Attempt to fix other test failures that happened during the PR --- .../Test/Mftf/Test/AdminResetCustomerPasswordTest.xml | 6 ++++-- .../ChangeStatusProductUsingProductGridActionGroup.xml | 7 +++---- .../Quote/Test/Mftf/Section/AdminProductGridSection.xml | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml index 0ca1d72a3ae1d..fb67838e941b6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -10,8 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminResetCustomerPasswordTest"> <annotations> - <features value="Customer"/> - <stories value="Admin should be able to reset an existing customer's password"/> + <stories value="Reset password"/> + <title value="Admin should be able to reset customer password"/> <description value="Admin should be able to reset customer password"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-30875"/> @@ -25,6 +25,8 @@ <deleteData createDataKey="customer" stepKey="deleteCustomer"/> <actionGroup ref="logout" stepKey="logout"/> </after> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> <!--Edit customer info--> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> <argument name="customer" value="$$customer$$"/> diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml index dba4a94f3db2a..9698f9cef4219 100644 --- a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -6,8 +6,7 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!--Disabled a product by filtering grid and using change status action--> <actionGroup name="ChangeStatusProductUsingProductGridActionGroup"> <arguments> @@ -23,10 +22,10 @@ <see selector="{{AdminProductGridSection.productGridCell('1', 'SKU')}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> - <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickChangeStatusAction"/> - <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled" parameterized="true"/> + <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled"/> + <waitForPageLoad stepKey="waitForDisable"/> <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> </actionGroup> diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml index 32ac73aca7c03..0ca252aa73545 100644 --- a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml +++ b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml @@ -7,8 +7,8 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductGridSection"> - <element name="changeStatus" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" stepKey="clickChangeStatus" parameterized="true"/> + <element name="changeStatus" type="button" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" parameterized="true"/> </section> </sections> From 5d84640f097dd94a361a6b0b1085e13da472a360 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 31 Oct 2018 20:17:21 -0500 Subject: [PATCH 0946/1415] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest --- .../OnePageCheckoutOfflinePaymentMethodsTest.xml | 11 ++++------- .../Test/TestStep/SelectCheckoutMethodStep.php | 11 +++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml index 7c12b546d1359..361c5031f3317 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml @@ -22,7 +22,6 @@ <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> </variation> <variation name="OnePageCheckoutUsingRegisterLink" summary="Customer is redirected to checkout on login if guest is disabled, flow with registration new Customer" ticketId="MAGETWO-49917"> - <data name="issue" xsi:type="string">MAGETWO-59816: Redirect works improperly in a browser incognito mode</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">register_customer</data> @@ -57,7 +56,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation2" summary="US customer during checkout using coupon for all customer groups"> - <data name="tag" xsi:type="string">stable:no, severity:S0</data> + <data name="tag" xsi:type="string">severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups</data> <data name="customer/dataset" xsi:type="string">default</data> @@ -79,7 +78,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation3" summary="Checkout as UK guest with simple product" ticketId="MAGETWO-42603, MAGETWO-43282, MAGETWO-43318"> - <data name="tag" xsi:type="string">severity:S1, stable:no</data> + <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_qty_25</data> <data name="expectedQty/0" xsi:type="string">0</data> <data name="expectedStockStatus/0" xsi:type="string">out of stock</data> @@ -92,7 +91,7 @@ <item name="grandTotal" xsi:type="string">375.00</item> </data> <data name="payment/method" xsi:type="string">banktransfer</data> - <data name="status" xsi:type="string">Precessing</data> + <data name="status" xsi:type="string">Processing</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">banktransfer_specificcountry_gb, can_subtract_and_can_back_in_stock</data> <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> @@ -102,10 +101,8 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> - <data name="issue" xsi:type="string">MAGETWO-66737: Magento\Checkout\Test\TestCase\OnePageCheckoutTest with OnePageCheckoutTestVariation3 and 4 is not stable</data> </variation> <variation name="OnePageCheckoutTestVariation4" summary="One Page Checkout Products with Special Prices" ticketId="MAGETWO-12429"> - <data name="issue" xsi:type="string">MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest</data> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_special_price</data> <data name="products/1" xsi:type="string">configurableProduct::product_with_special_price</data> @@ -211,7 +208,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with different shipping/billing address and Tier Prices" ticketId="MAGETWO-42604"> - <data name="tag" xsi:type="string">stable:no, severity:S1</data> + <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_order_qty_3</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="checkoutMethod" xsi:type="string">login</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php index d951d84bab78d..f79cf8d7eb7fa 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php @@ -59,6 +59,13 @@ class SelectCheckoutMethodStep implements TestStepInterface */ private $customerAccountCreatePage; + /** + * Proceed to checkout from minicart step + * + * @var proceedToCheckoutFromMiniShoppingCartStep + */ + private $proceedToCheckoutFromMiniShoppingCartStep; + /** * @constructor * @param CheckoutOnepage $checkoutOnepage @@ -66,6 +73,7 @@ class SelectCheckoutMethodStep implements TestStepInterface * @param Customer $customer * @param LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend * @param ClickProceedToCheckoutStep $clickProceedToCheckoutStep + * @param ProceedToCheckoutFromMiniShoppingCartStep $proceedToCheckoutFromMiniShoppingCartStep * @param string $checkoutMethod */ public function __construct( @@ -74,6 +82,7 @@ public function __construct( Customer $customer, LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend, ClickProceedToCheckoutStep $clickProceedToCheckoutStep, + ProceedToCheckoutFromMiniShoppingCartStep $proceedToCheckoutFromMiniShoppingCartStep, $checkoutMethod ) { $this->checkoutOnepage = $checkoutOnepage; @@ -82,6 +91,7 @@ public function __construct( $this->logoutCustomerOnFrontend = $logoutCustomerOnFrontend; $this->clickProceedToCheckoutStep = $clickProceedToCheckoutStep; $this->checkoutMethod = $checkoutMethod; + $this->proceedToCheckoutFromMiniShoppingCartStep = $proceedToCheckoutFromMiniShoppingCartStep; } /** @@ -129,6 +139,7 @@ private function processRegister() if ($this->checkoutMethod === 'register_before_checkout') { $this->checkoutOnepage->getAuthenticationPopupBlock()->createAccount(); $this->customerAccountCreatePage->getRegisterForm()->registerCustomer($this->customer); + $this->proceedToCheckoutFromMiniShoppingCartStep->run(); } } From a0bb0fcf965d47f617cc801187f6290d8bdf22a6 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 1 Nov 2018 09:45:21 +0200 Subject: [PATCH 0947/1415] graphQl: updated shipping address coverage content --- .../MultiShipping.php | 69 ++++++++++++++++--- .../MultiShipping/ShippingItemsMapper.php | 43 ++++++++++++ .../SingleShipping.php | 47 +++++++++++-- .../SetShippingAddressesOnCart.php | 32 +++------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 4 ++ 5 files changed, 157 insertions(+), 38 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php index 71560a26c03ee..318fd9361af5a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php @@ -1,23 +1,76 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Multishipping\Model\Checkout\Type\Multishipping as MultishippingModel; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping\ShippingItemsMapper; + class MultiShipping { /** + * @var MultishippingModel + */ + private $multishippingModel; + + /** + * @var ShippingItemsMapper + */ + private $shippingItemsInformationMapper; + + /** + * @param MultishippingModel $multishippingModel + * @param ShippingItemsMapper $shippingItemsInformationMapper + */ + public function __construct( + MultishippingModel $multishippingModel, + ShippingItemsMapper $shippingItemsInformationMapper + ) { + $this->multishippingModel = $multishippingModel; + $this->shippingItemsInformationMapper = $shippingItemsInformationMapper; + } + + /** + * @param ContextInterface $context * @param int $cartId - * @param array $cartItems - * @param int|null $customerAddressId - * @param array|null $address - * @return void + * @param array $shippingAddresses */ - public function setAddress(int $cartId, array $cartItems, ?int $customerAddressId, ?array $address): void + public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void { - //TODO: implement multi shipping + if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { + throw new GraphQlAuthorizationException( + __( + 'Multishipping allowed only for authorized customers' + ) + ); + } + + $shippingItemsInformation = []; + foreach ($shippingAddresses as $shippingAddress) { + $customerAddressId = $shippingAddress['customer_address_id'] ?? null; + $cartItems = $shippingAddress['cart_items'] ?? null; + if (!$customerAddressId) { + throw new GraphQlInputException(__('Parameter "customer_address_id" is required for multishipping')); + } + if (!$cartItems) { + throw new GraphQlInputException(__('Parameter "cart_items" is required for multishipping')); + } + + $shippingItemsInformation = array_merge( + $shippingItemsInformation, + $this->shippingItemsInformationMapper->map($shippingAddress) + ); + } + + //TODO: multishipping model works with session. Do we need to avoid it? + $this->multishippingModel->setShippingItemsInformation($shippingItemsInformation); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php new file mode 100644 index 0000000000000..c9cefc421a544 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; + +/** + * Shipping address to shipping items mapper + */ +class ShippingItemsMapper +{ + + /** + * Converts shipping address input array into shipping items information array + * Array structure: + * array( + * $cartItemId => array( + * 'qty' => $qty, + * 'address' => $customerAddressId + * ) + * ) + * + * @param array $shippingAddress + * @return array + */ + public function map(array $shippingAddress): array + { + $shippingItemsInformation = []; + foreach ($shippingAddress['cart_items'] as $cartItem) { + $shippingItemsInformation[] = [ + $cartItem['cart_item_id'] => [ + 'qty' => $cartItem['quantity'], + 'address' => $shippingAddress['customer_address_id'] + ] + ]; + } + + return $shippingItemsInformation; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php index 536a907541b1a..feeb333683f76 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php @@ -1,12 +1,17 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; @@ -44,18 +49,46 @@ public function __construct( } /** + * @param ContextInterface $context * @param int $cartId - * @param int|null $customerAddressId - * @param array|null $address + * @param array $shippingAddress * @return void */ - public function setAddress(int $cartId, ?int $customerAddressId, ?array $address): void + public function setAddress(ContextInterface $context, int $cartId, array $shippingAddress): void { - if($customerAddressId) { + $customerAddressId = $shippingAddress['customer_address_id'] ?? null; + $addressInput = $shippingAddress['address'] ?? null; + + if (!$customerAddressId && !$addressInput) { + throw new GraphQlInputException( + __('Shipping address should contain either "customer_address_id" or "address" input.') + ); + } + if ($customerAddressId && $addressInput) { + throw new GraphQlInputException( + __('Shipping address can\'t contain "customer_address_id" and "address" input at the same time.') + ); + } + if ($customerAddressId) { + if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { + throw new GraphQlAuthorizationException( + __( + 'Address management allowed only for authorized customers' + ) + ); + } + /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); + if ($context->getUserId() !== (int)$customerAddress->getCustomerId()) { + throw new GraphQlInputException( + __( + 'Address is not applicable for current customer' + ) + ); + } $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } else { - $shippingAddress = $this->addressModel->addData($address); + $shippingAddress = $this->addressModel->addData($addressInput); } $this->shippingAddressManagement->assign($cartId, $shippingAddress); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php index f3960f66d2792..7ffa6c4950b3d 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -7,7 +7,6 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; -use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -22,11 +21,6 @@ */ class SetShippingAddressesOnCart implements ResolverInterface { - /** - * @var DataObjectHelper - */ - private $dataObjectHelper; - /** * @var MaskedQuoteIdToQuoteIdInterface */ @@ -48,20 +42,17 @@ class SetShippingAddressesOnCart implements ResolverInterface private $shippingAddressManagement; /** - * @param DataObjectHelper $dataObjectHelper * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId * @param MultiShipping $multiShipping * @param SingleShipping $singleShipping * @param ShippingAddressManagementInterface $shippingAddressManagement */ public function __construct( - DataObjectHelper $dataObjectHelper, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, MultiShipping $multiShipping, SingleShipping $singleShipping, - ShippingAddressManagementInterface $shippingAddressManagement + ShippingAddressManagementInterface $shippingAddressManagement ) { - $this->dataObjectHelper = $dataObjectHelper; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->multiShipping = $multiShipping; $this->singleShipping = $singleShipping; @@ -76,23 +67,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!isset($args['input']['cart_id'])) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } + if (!isset($args['input']['shipping_addresses'])) { + throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); + } + + $shippingAddressesInput = $args['input']['shipping_addresses']; $maskedCartId = $args['input']['cart_id']; $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $customerAddressId = $args['input']['customer_address_id'] ?? null; - $address = $args['input']['address'] ?? null; - $cartItems = $args['input']['cart_items'] ?? []; - - if (!$customerAddressId && !$address) { - throw new GraphQlInputException(__('Query should contain either address id or address input.')); - } - - //TODO: how to determine whether is multi shipping or not - if (!$cartItems) { - //TODO: assign cart items - $this->singleShipping->setAddress($cartId, $customerAddressId, $address); + if (count($shippingAddressesInput) === 1) { + $this->singleShipping->setAddress($context, $cartId, current($shippingAddressesInput)); } else { - $this->multiShipping->setAddress($cartId, $cartItems, $customerAddressId, $address); + $this->multiShipping->setAddresses($context, $cartId, $shippingAddressesInput); } //TODO: implement Cart object in the separate resolver diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index d13240a23140b..d99182ed10988 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -16,6 +16,10 @@ type Mutation { input SetShippingAddressesOnCartInput { cart_id: String! + shipping_addresses: [ShippingAddressInput!]! +} + +input ShippingAddressInput { customer_address_id: Int # Can be provided in one-page checkout and is required for multi-shipping checkout address: CartAddressInput cart_items: [CartItemQuantityInput!] From 71983df468f7d5a9ff35e915c59d56c4d33a414b Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Thu, 1 Nov 2018 10:50:59 +0200 Subject: [PATCH 0948/1415] Fix backward incompatibility --- .../Catalog/Model/Product/Gallery/Processor.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 048ad55985b72..9cd5073f4357c 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -9,7 +9,7 @@ use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\App\ObjectManager; /** * Catalog product Media Gallery attribute processor. @@ -60,7 +60,7 @@ class Processor /** * @var \Magento\Framework\File\Mime */ - protected $mime; + private $mime; /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository @@ -68,7 +68,7 @@ class Processor * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel - * @param \Magento\Framework\File\Mime $mime + * @param \Magento\Framework\File\Mime|null $mime * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -77,14 +77,14 @@ public function __construct( \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, - \Magento\Framework\File\Mime $mime + \Magento\Framework\File\Mime $mime = null ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; - $this->mime = $mime; + $this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class); } /** From 75e2547a7835330128bdf79e37e314b25f1fc30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20H=C3=BCbner?= <mjh@bergwerk.ag> Date: Mon, 20 Aug 2018 18:37:40 +0300 Subject: [PATCH 0949/1415] Prevent rendering of "Ship here" button to select a shipping item if it is already selected - checks if the item is selected, if it is it does not render the button - removes the css which hides the button currently, because it is not needed anymore --- .../template/shipping-address/address-renderer/default.html | 2 ++ .../web/css/source/module/checkout/_shipping.less | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index 2a5dc27328a43..cf64c0140b955 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -35,7 +35,9 @@ click="editAddress"> <span translate="'Edit'"></span> </button> + <!-- ko if: (!isSelected()) --> <button type="button" click="selectAddress" class="action action-select-shipping-item"> <span translate="'Ship Here'"></span> </button> + <!-- /ko --> </div> diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less index 0a463a95e3182..158cb0ebc0ed1 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -98,11 +98,6 @@ text-align: center; top: 0; } - - .action-select-shipping-item { - &:extend(.abs-no-display-s all); - visibility: hidden; - } } } From a537b009bbece04073700df55bbd1a0abaf31821 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 11:32:05 +0200 Subject: [PATCH 0950/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- ...gAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 7a774c585c9cd..e9158e91432fa 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -1,3 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> From fe82167bb54618ebc7818d5995533f0a55ffdaaa Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 11:41:26 +0200 Subject: [PATCH 0951/1415] magento/magento2#17638: [Forwardport]Bundle Special Prices not correctly rounded. --- .../Product/Form/Modifier/Eav.php | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index d84f496e81915..7379600011bcf 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -11,6 +11,7 @@ use Magento\Catalog\Model\Attribute\ScopeOverriddenValue; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Type as ProductType; use Magento\Catalog\Model\ResourceModel\Eav\Attribute as EavAttribute; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory as EavAttributeFactory; use Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules; @@ -419,7 +420,7 @@ public function modifyData(array $data) foreach ($attributes as $attribute) { if (null !== ($attributeValue = $this->setupAttributeData($attribute))) { - if ($attribute->getFrontendInput() === 'price' && is_scalar($attributeValue)) { + if ($this->isPriceAttribute($attribute, $attributeValue)) { $attributeValue = $this->formatPrice($attributeValue); } $data[$productId][self::DATA_SOURCE_DEFAULT][$attribute->getAttributeCode()] = $attributeValue; @@ -430,6 +431,32 @@ public function modifyData(array $data) return $data; } + /** + * Obtain if given attribute is a price + * + * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute + * @param string|integer $attributeValue + * @return bool + */ + private function isPriceAttribute(ProductAttributeInterface $attribute, $attributeValue) + { + return $attribute->getFrontendInput() === 'price' + && is_scalar($attributeValue) + && !$this->isBundleSpecialPrice($attribute); + } + + /** + * Obtain if current product is bundle and given attribute is special_price + * + * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute + * @return bool + */ + private function isBundleSpecialPrice(ProductAttributeInterface $attribute) + { + return $this->locator->getProduct()->getTypeId() === ProductType::TYPE_BUNDLE + && $attribute->getAttributeCode() === ProductAttributeInterface::CODE_SPECIAL_PRICE; + } + /** * Resolve data persistence * From f359bbcd3d734f5296f88c7078c1a2b6c3b00017 Mon Sep 17 00:00:00 2001 From: Misha Medzhytov <mdg12v@gmail.com> Date: Sun, 2 Sep 2018 20:16:50 +0300 Subject: [PATCH 0952/1415] #17890: show correct text swatch values per store view --- app/code/Magento/Swatches/Helper/Data.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index 38879178235c0..ac19ad5116cc3 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -488,6 +488,8 @@ private function addFallbackOptions(array $fallbackValues, array $swatches) && $swatches[$optionId]['type'] === $optionsArray[$currentStoreId]['type'] ) { $swatches[$optionId] = $optionsArray[$currentStoreId]; + } elseif (isset($optionsArray[$currentStoreId])) { + $swatches[$optionId] = $optionsArray[$currentStoreId]; } elseif (isset($optionsArray[self::DEFAULT_STORE_ID])) { $swatches[$optionId] = $optionsArray[self::DEFAULT_STORE_ID]; } From daffedf8638585ac230aacd2c1cea18c437a3810 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 1 Nov 2018 11:45:35 +0200 Subject: [PATCH 0953/1415] MAGETWO-95818: [Magento Cloud] Default value for category URL path does not save - Added reseting category url_path attribute if url_key was set to default value --- .../Model/CategoryUrlPathGenerator.php | 15 +++-- .../CategoryUrlPathAutogeneratorObserver.php | 59 +++++++++++++++---- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php index ee20b0e934b5d..cba9218ce7c72 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/CategoryUrlPathGenerator.php @@ -8,6 +8,9 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Model\Category; +/** + * Class for generation category url_path + */ class CategoryUrlPathGenerator { /** @@ -61,9 +64,11 @@ public function __construct( * Build category URL path * * @param \Magento\Catalog\Api\Data\CategoryInterface|\Magento\Framework\Model\AbstractModel $category + * @param null|\Magento\Catalog\Api\Data\CategoryInterface|\Magento\Framework\Model\AbstractModel $parentCategory * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function getUrlPath($category) + public function getUrlPath($category, $parentCategory = null) { if (in_array($category->getParentId(), [Category::ROOT_CATEGORY_ID, Category::TREE_ROOT_ID])) { return ''; @@ -77,15 +82,17 @@ public function getUrlPath($category) return $category->getUrlPath(); } if ($this->isNeedToGenerateUrlPathForParent($category)) { - $parentPath = $this->getUrlPath( - $this->categoryRepository->get($category->getParentId(), $category->getStoreId()) - ); + $parentCategory = $parentCategory === null ? + $this->categoryRepository->get($category->getParentId(), $category->getStoreId()) : $parentCategory; + $parentPath = $this->getUrlPath($parentCategory); $path = $parentPath === '' ? $path : $parentPath . '/' . $path; } return $path; } /** + * Define whether we should generate URL path for parent + * * @param \Magento\Catalog\Model\Category $category * @return bool */ diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index eb54f0427c11a..b9585fd40ae8b 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -13,6 +13,9 @@ use Magento\Framework\Event\ObserverInterface; use Magento\Store\Model\Store; +/** + * Class observer to initiate generation category url_path + */ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface { /** @@ -46,6 +49,8 @@ public function __construct( } /** + * Generate Category Url Path + * * @param \Magento\Framework\Event\Observer $observer * @return void * @throws \Magento\Framework\Exception\LocalizedException @@ -57,21 +62,40 @@ public function execute(\Magento\Framework\Event\Observer $observer) $useDefaultAttribute = !$category->isObjectNew() && !empty($category->getData('use_default')['url_key']); if ($category->getUrlKey() !== false && !$useDefaultAttribute) { $resultUrlKey = $this->categoryUrlPathGenerator->getUrlKey($category); - if (empty($resultUrlKey)) { - throw new \Magento\Framework\Exception\LocalizedException(__('Invalid URL key')); - } - $category->setUrlKey($resultUrlKey) - ->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); - if (!$category->isObjectNew()) { - $category->getResource()->saveAttribute($category, 'url_path'); - if ($category->dataHasChangedFor('url_path')) { - $this->updateUrlPathForChildren($category); - } + $this->updateUrlKey($category, $resultUrlKey); + } else if ($useDefaultAttribute) { + $resultUrlKey = $category->formatUrlKey($category->getOrigData('name')); + $this->updateUrlKey($category, $resultUrlKey); + $category->setUrlKey(null)->setUrlPath(null); + } + } + + /** + * Update Url Key + * + * @param Category $category + * @param string $urlKey + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function updateUrlKey($category, $urlKey) + { + if (empty($urlKey)) { + throw new \Magento\Framework\Exception\LocalizedException(__('Invalid URL key')); + } + $category->setUrlKey($urlKey) + ->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); + if (!$category->isObjectNew()) { + $category->getResource()->saveAttribute($category, 'url_path'); + if ($category->dataHasChangedFor('url_path')) { + $this->updateUrlPathForChildren($category); } } } /** + * Update URL path for children + * * @param Category $category * @return void */ @@ -94,8 +118,13 @@ protected function updateUrlPathForChildren(Category $category) } } else { foreach ($children as $child) { + /** @var Category $child */ $child->setStoreId($category->getStoreId()); - $this->updateUrlPathForCategory($child); + if ($child->getParentId() === $category->getId()) { + $this->updateUrlPathForCategory($child, $category); + } else { + $this->updateUrlPathForCategory($child); + } } } } @@ -112,13 +141,17 @@ protected function isGlobalScope($storeId) } /** + * Update URL path for category + * * @param Category $category + * @param Category|null $parentCategory * @return void + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - protected function updateUrlPathForCategory(Category $category) + protected function updateUrlPathForCategory(Category $category, Category $parentCategory = null) { $category->unsUrlPath(); - $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); + $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category, $parentCategory)); $category->getResource()->saveAttribute($category, 'url_path'); } } From e794db8b1a9fb3b456b1cdaac5303d1888fc9698 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 1 Nov 2018 12:59:38 +0300 Subject: [PATCH 0954/1415] MAGETWO-91649: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed integration test; --- .../Magento/Catalog/Controller/Adminhtml/CategoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index a6d03fcc200e2..dad4d21362a0a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -403,7 +403,7 @@ public function moveActionDataProvider() { return [ [400, 401, 'first_url_key', 402, 'second_url_key', false], - [400, 401, 'duplicated_url_key', 402, 'duplicated_url_key', true], + [400, 401, 'duplicated_url_key', 402, 'duplicated_url_key', false], [0, 401, 'first_url_key', 402, 'second_url_key', true], [400, 401, 'first_url_key', 0, 'second_url_key', true], ]; From 70f1c939381a9ae123770f80a27b3fcaaf6bfc83 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Thu, 1 Nov 2018 12:02:49 +0200 Subject: [PATCH 0955/1415] MAGETWO-95692: [2.3] Value of Customer Address Attribute is not shown in the Customers grid --- .../Magento/Customer/Model/Indexer/Source.php | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Model/Indexer/Source.php b/app/code/Magento/Customer/Model/Indexer/Source.php index e4bf03e08a9ad..a8878e2084ea0 100644 --- a/app/code/Magento/Customer/Model/Indexer/Source.php +++ b/app/code/Magento/Customer/Model/Indexer/Source.php @@ -5,6 +5,7 @@ */ namespace Magento\Customer\Model\Indexer; +use Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory; use Magento\Customer\Model\ResourceModel\Customer\Indexer\Collection; use Magento\Framework\App\ResourceConnection\SourceProviderInterface; use Traversable; @@ -25,11 +26,11 @@ class Source implements \IteratorAggregate, \Countable, SourceProviderInterface private $batchSize; /** - * @param \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collection + * @param CollectionFactory $collectionFactory * @param int $batchSize */ public function __construct( - \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collectionFactory, + CollectionFactory $collectionFactory, $batchSize = 10000 ) { $this->customerCollection = $collectionFactory->create(); @@ -37,7 +38,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getMainTable() { @@ -45,7 +46,7 @@ public function getMainTable() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIdFieldName() { @@ -53,7 +54,7 @@ public function getIdFieldName() } /** - * {@inheritdoc} + * @inheritdoc */ public function addFieldToSelect($fieldName, $alias = null) { @@ -62,7 +63,7 @@ public function addFieldToSelect($fieldName, $alias = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSelect() { @@ -70,7 +71,7 @@ public function getSelect() } /** - * {@inheritdoc} + * @inheritdoc */ public function addFieldToFilter($attribute, $condition = null) { @@ -79,7 +80,7 @@ public function addFieldToFilter($attribute, $condition = null) } /** - * @return int + * @inheritdoc */ public function count() { @@ -105,4 +106,28 @@ public function getIterator() $pageNumber++; } while ($pageNumber <= $lastPage); } + + /** + * Joins Attribute + * + * @param string $alias alias for the joined attribute + * @param string|\Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute + * @param string $bind attribute of the main entity to link with joined $filter + * @param string|null $filter primary key for the joined entity (entity_id default) + * @param string $joinType inner|left + * @param int|null $storeId + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + * @see Collection::joinAttribute() + */ + public function joinAttribute( + string $alias, + $attribute, + string $bind, + ?string $filter = null, + string $joinType = 'inner', + ?int $storeId = null + ): void { + $this->customerCollection->joinAttribute($alias, $attribute, $bind, $filter, $joinType, $storeId); + } } From 7c86822387cbee24186a1746b373b2bfb381bed8 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 12:17:26 +0200 Subject: [PATCH 0956/1415] magento/magento2#10440: [Forwardport] Missing $debugHintsPath when sending email via command. --- app/code/Magento/Developer/etc/di.xml | 8 ++++++++ app/code/Magento/Developer/etc/frontend/di.xml | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Developer/etc/di.xml b/app/code/Magento/Developer/etc/di.xml index 21ecf10c1b1e7..98adcbb3a8295 100644 --- a/app/code/Magento/Developer/etc/di.xml +++ b/app/code/Magento/Developer/etc/di.xml @@ -240,4 +240,12 @@ </argument> </arguments> </type> + + <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints"> + <arguments> + <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument> + <argument name="debugHintsWithParam" xsi:type="string">dev/debug/template_hints_storefront_show_with_parameter</argument> + <argument name="debugHintsParameter" xsi:type="string">dev/debug/template_hints_parameter_value</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Developer/etc/frontend/di.xml b/app/code/Magento/Developer/etc/frontend/di.xml index 329c158d897a9..aa4b347260209 100644 --- a/app/code/Magento/Developer/etc/frontend/di.xml +++ b/app/code/Magento/Developer/etc/frontend/di.xml @@ -9,11 +9,4 @@ <type name="Magento\Framework\View\TemplateEngineFactory"> <plugin name="debug_hints" type="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints" sortOrder="10"/> </type> - <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints"> - <arguments> - <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument> - <argument name="debugHintsWithParam" xsi:type="string">dev/debug/template_hints_storefront_show_with_parameter</argument> - <argument name="debugHintsParameter" xsi:type="string">dev/debug/template_hints_parameter_value</argument> - </arguments> - </type> </config> From 7f1f133d8e1db7d15b9f12d76085f68cdfe94833 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 14:24:34 +0200 Subject: [PATCH 0957/1415] ENGCOM-1928: Fix file name. --- .../Store/ViewModel/{Switcher.php => SwitcherUrlProvider.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/code/Magento/Store/ViewModel/{Switcher.php => SwitcherUrlProvider.php} (100%) diff --git a/app/code/Magento/Store/ViewModel/Switcher.php b/app/code/Magento/Store/ViewModel/SwitcherUrlProvider.php similarity index 100% rename from app/code/Magento/Store/ViewModel/Switcher.php rename to app/code/Magento/Store/ViewModel/SwitcherUrlProvider.php From 24b7d98215333a1fa391073420391fdd079034b5 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Thu, 1 Nov 2018 15:41:58 +0200 Subject: [PATCH 0958/1415] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- app/code/Magento/Catalog/Helper/Data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Helper/Data.php b/app/code/Magento/Catalog/Helper/Data.php index c83eb70486c43..3e96763632830 100644 --- a/app/code/Magento/Catalog/Helper/Data.php +++ b/app/code/Magento/Catalog/Helper/Data.php @@ -413,7 +413,7 @@ public function getAttributeHiddenFields() /** * Retrieve Catalog Price Scope * - * @return int/null + * @return int|null */ public function getPriceScope(): ?int { From d353304c65bd9e8c9eff7841f3a6e4deec403e65 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 1 Nov 2018 15:50:10 +0200 Subject: [PATCH 0959/1415] MAGETWO-95798: All country state's are shown for USA when shipping form has custom address attributes. --- .../Checkout/Test/Mftf/Section/CheckoutShippingSection.xml | 1 + app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 494a365ffd507..a8e0c5508ae06 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,5 +32,6 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="regionOptions" type="select" selector="select[name=region_id] option"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index d090620145105..2609106b1f19b 100755 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -32,6 +32,7 @@ <data key="vat_id">vatData</data> <data key="default_shipping">true</data> <data key="default_billing">true</data> + <data key="region_qty">66</data> </entity> <entity name="US_Address_TX" type="address"> <data key="firstname">John</data> From 099465aed038cbdf2884326d5915acd84867d6e0 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 16:37:19 +0200 Subject: [PATCH 0960/1415] ENGCOM-3201: Updated integration test. --- .../testsuite/Magento/Customer/Controller/Section/LoadTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php index 3e086a89f8140..3563087d3722b 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php @@ -13,7 +13,7 @@ public function testLoadInvalidSection() $expected = [ 'message' => 'The "section<invalid" section source isn't supported.', ]; - $this->dispatch('/customer/section/load/?sections=section<invalid&update_section_id=false&_=147066166394'); + $this->dispatch('/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394'); self::assertEquals(json_encode($expected), $this->getResponse()->getBody()); } } From 0ae58d9b877fffedee4ba7eeb40331c63dfcc7a3 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 17:10:46 +0200 Subject: [PATCH 0961/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../Catalog/Test/Mftf/Section/AdminProductFormSection.xml | 2 +- ...PricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 9ec0dbf9f262c..249610568aec7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -28,7 +28,7 @@ <element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/> <element name="categoriesDropdown" type="multiselect" selector="div[data-index='category_ids']"/> <element name="productQuantity" type="input" selector=".admin__field[data-index=qty] input"/> - <element name="advancedInventoryLink" type="input" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> + <element name="advancedInventoryLink" type="button" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> <element name="productStockStatus" type="select" selector="select[name='product[quantity_and_stock_status][is_in_stock]']"/> <element name="productWeight" type="input" selector=".admin__field[data-index=weight] input"/> <element name="productWeightSelect" type="select" selector="select[name='product[product_has_weight]']"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index e9158e91432fa..9dbd2eb0c1fae 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -45,6 +45,7 @@ <!--Step3. Open *Advanced Pricing* pop-up (Click on *Advanced Pricing* link). Click on *Add* button. Fill *0.5* in *Quantity*--> <scrollTo selector="{{AdminProductFormSection.productName}}" stepKey="scrollToProductName"/> <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink1"/> + <waitForElement selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="waitForAddButton"/> <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="clickOnCustomerGroupPriceAddButton"/> <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="0.5" stepKey="fillProductTierPriceQty"/> <!--Step4. Close *Advanced Pricing* (Click on button *Done*). Save *prod1* (Click on button *Save*)--> From 9c53b7ca5cf096a21bb33c0ec496e74bba7a7fd0 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 1 Nov 2018 17:22:32 +0200 Subject: [PATCH 0962/1415] magento-engcom/magento2ce#2299: Code style fixes --- .../Controller/Adminhtml/Bulk/Details.php | 2 +- .../Backend/App/Request/BackendValidator.php | 4 + .../Block/Widget/Grid/Column/Filter/Theme.php | 4 + .../Magento/Backend/Block/Widget/Tabs.php | 32 ++++++- .../Console/Command/AbstractCacheCommand.php | 4 +- .../Product/Initialization/Helper.php | 7 ++ .../Product/Initialization/HelperTest.php | 16 ++++ .../Model/Address/AbstractAddress.php | 20 ++++- .../Customer/Model/Metadata/Form/Text.php | 3 + .../Magento/Eav/Model/Attribute/Data/Text.php | 1 + .../Magento/Quote/Model/Quote/Address.php | 83 ++++++++++--------- .../Console/Command/ConfigSetCommand.php | 7 +- 12 files changed, 135 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php index 5571c20f526cc..a450187dd094b 100644 --- a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php +++ b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php @@ -8,7 +8,7 @@ /** * Class View Operation Details Controller */ -class Details extends \Magento\Backend\App\Action +class Details extends \Magento\Backend\App\Action implements \Magento\Framework\App\Action\HttpGetActionInterface { /** * @var \Magento\Framework\View\Result\PageFactory diff --git a/app/code/Magento/Backend/App/Request/BackendValidator.php b/app/code/Magento/Backend/App/Request/BackendValidator.php index eed4fbb643d3e..4d04d2fed8eb2 100644 --- a/app/code/Magento/Backend/App/Request/BackendValidator.php +++ b/app/code/Magento/Backend/App/Request/BackendValidator.php @@ -77,6 +77,8 @@ public function __construct( } /** + * Validate request + * * @param RequestInterface $request * @param ActionInterface $action * @@ -115,6 +117,8 @@ private function validateRequest( } /** + * Create exception + * * @param RequestInterface $request * @param ActionInterface $action * diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php index 5db5dc59b4e5b..a0907726ccc46 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php @@ -9,6 +9,9 @@ */ namespace Magento\Backend\Block\Widget\Grid\Column\Filter; +/** + * Theme grid filter + */ class Theme extends \Magento\Backend\Block\Widget\Grid\Column\Filter\AbstractFilter { /** @@ -55,6 +58,7 @@ public function getHtml() /** * Retrieve options set in column. + * * Or load if options was not set. * * @return array diff --git a/app/code/Magento/Backend/Block/Widget/Tabs.php b/app/code/Magento/Backend/Block/Widget/Tabs.php index b390e2fa7d150..c7c1f93e8ca73 100644 --- a/app/code/Magento/Backend/Block/Widget/Tabs.php +++ b/app/code/Magento/Backend/Block/Widget/Tabs.php @@ -8,6 +8,8 @@ use Magento\Backend\Block\Widget\Tab\TabInterface; /** + * Tabs widget + * * @api * @SuppressWarnings(PHPMD.NumberOfChildren) * @since 100.0.2 @@ -178,6 +180,8 @@ protected function _addTabByName($tab, $tabId) } /** + * Get active tab id + * * @return string */ public function getActiveTabId() @@ -187,6 +191,7 @@ public function getActiveTabId() /** * Set Active Tab + * * Tab has to be not hidden and can show * * @param string $tabId @@ -231,7 +236,7 @@ protected function _setActiveTab($tabId) } /** - * {@inheritdoc} + * @inheritdoc */ protected function _beforeToHtml() { @@ -282,6 +287,8 @@ private function reorderTabs() } /** + * Apply tabs order + * * @param array $orderByPosition * @param array $orderByIdentity * @@ -294,7 +301,7 @@ private function applyTabsCorrectOrder(array $orderByPosition, array $orderByIde /** * Rearrange the positions by using the after tag for each tab. * - * @var integer $position + * @var int $position * @var TabInterface $tab */ foreach ($orderByPosition as $position => $tab) { @@ -338,6 +345,8 @@ private function finalTabsSortOrder(array $orderByPosition) } /** + * Get js object name + * * @return string */ public function getJsObjectName() @@ -346,6 +355,8 @@ public function getJsObjectName() } /** + * Get tabs ids + * * @return string[] */ public function getTabsIds() @@ -358,6 +369,8 @@ public function getTabsIds() } /** + * Get tab id + * * @param \Magento\Framework\DataObject|TabInterface $tab * @param bool $withPrefix * @return string @@ -371,6 +384,8 @@ public function getTabId($tab, $withPrefix = true) } /** + * CVan show tab + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return bool */ @@ -383,6 +398,8 @@ public function canShowTab($tab) } /** + * Get tab is hidden + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) @@ -396,6 +413,8 @@ public function getTabIsHidden($tab) } /** + * Get tab url + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -414,6 +433,8 @@ public function getTabUrl($tab) } /** + * Get tab title + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -426,6 +447,8 @@ public function getTabTitle($tab) } /** + * Get tab class + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -441,6 +464,8 @@ public function getTabClass($tab) } /** + * Get tab label + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -453,6 +478,8 @@ public function getTabLabel($tab) } /** + * Get tab content + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -469,6 +496,7 @@ public function getTabContent($tab) /** * Mark tabs as dependent of each other + * * Arbitrary number of tabs can be specified, but at least two * * @param string $tabOneId diff --git a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php index ecea5716f653d..11da740c46606 100644 --- a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php +++ b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php @@ -11,6 +11,8 @@ use Symfony\Component\Console\Input\InputOption; /** + * Abstract cache command + * * @api * @since 100.0.2 */ @@ -40,7 +42,7 @@ public function __construct(Manager $cacheManager) } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 988d61986e3d2..f11d16755ef0d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -19,6 +19,8 @@ use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeFilter; /** + * Product helper + * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 @@ -365,6 +367,8 @@ private function overwriteValue($optionId, $option, $overwriteOptions) } /** + * Get link resolver instance + * * @return LinkResolver * @deprecated 101.0.0 */ @@ -377,6 +381,8 @@ private function getLinkResolver() } /** + * Get DateTimeFilter instance + * * @return \Magento\Framework\Stdlib\DateTime\Filter\DateTime * @deprecated 101.0.0 */ @@ -391,6 +397,7 @@ private function getDateTimeFilter() /** * Remove ids of non selected websites from $websiteIds array and return filtered data + * * $websiteIds parameter expects array with website ids as keys and 1 (selected) or 0 (non selected) as values * Only one id (default website ID) will be set to $websiteIds array when the single store mode is turned on * diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php index ff44a91a64998..c889c58e3df3a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php @@ -95,6 +95,11 @@ class HelperTest extends \PHPUnit\Framework\TestCase */ protected $attributeFilterMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dateTimeFilterMock; + /** * @inheritdoc */ @@ -170,6 +175,11 @@ protected function setUp() $resolverProperty = $helperReflection->getProperty('linkResolver'); $resolverProperty->setAccessible(true); $resolverProperty->setValue($this->helper, $this->linkResolverMock); + + $this->dateTimeFilterMock = $this->createMock(\Magento\Framework\Stdlib\DateTime\Filter\DateTime::class); + $dateTimeFilterProperty = $helperReflection->getProperty('dateTimeFilter'); + $dateTimeFilterProperty->setAccessible(true); + $dateTimeFilterProperty->setValue($this->helper, $this->dateTimeFilterMock); } /** @@ -211,6 +221,12 @@ public function testInitialize( if (!empty($tierPrice)) { $productData = array_merge($productData, ['tier_price' => $tierPrice]); } + + $this->dateTimeFilterMock->expects($this->once()) + ->method('filter') + ->with($specialFromDate) + ->willReturn($specialFromDate); + $attributeNonDate = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 3ee284a705b16..8848fabb9ea1f 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -271,7 +271,7 @@ public function setStreet($street) * Enforce format of the street field or other multiline custom attributes * * @param array|string $key - * @param null $value + * @param mixed $value * @return \Magento\Framework\DataObject */ public function setData($key, $value = null) @@ -286,6 +286,7 @@ public function setData($key, $value = null) /** * Check that address can have multiline attribute by this code (as street or some custom attribute) + * * @param string $code * @return bool */ @@ -403,6 +404,8 @@ public function getRegionCode() } /** + * Get region id + * * @return int */ public function getRegionId() @@ -425,6 +428,8 @@ public function getRegionId() } /** + * Get country + * * @return string */ public function getCountry() @@ -502,6 +507,8 @@ public function getConfig() } /** + * Before save handler + * * @return $this */ public function beforeSave() @@ -591,6 +598,8 @@ public function validate() } /** + * Create region instance + * * @return \Magento\Directory\Model\Region */ protected function _createRegionInstance() @@ -599,6 +608,8 @@ protected function _createRegionInstance() } /** + * Create country instance + * * @return \Magento\Directory\Model\Country */ protected function _createCountryInstance() @@ -608,6 +619,7 @@ protected function _createCountryInstance() /** * Unset Region from address + * * @return $this * @since 100.2.0 */ @@ -617,6 +629,8 @@ public function unsRegion() } /** + * Is company required + * * @return bool * @since 100.2.0 */ @@ -626,6 +640,8 @@ protected function isCompanyRequired() } /** + * Is telephone required + * * @return bool * @since 100.2.0 */ @@ -635,6 +651,8 @@ protected function isTelephoneRequired() } /** + * Is fax required + * * @return bool * @since 100.2.0 */ diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php index dcd3bc93569a4..c639b607e279f 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php @@ -11,6 +11,9 @@ use Magento\Customer\Api\Data\AttributeMetadataInterface; use Magento\Framework\Api\ArrayObjectSearch; +/** + * Form Text metadata + */ class Text extends AbstractData { /** diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index a919a54cf6289..0a49e012690f6 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -51,6 +51,7 @@ public function extractValue(RequestInterface $request) /** * Validate data + * * Return true or array of errors * * @param array|string $value diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index f34cfbbf5fd26..e311eb924dee4 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -965,6 +965,7 @@ public function collectShippingRates() /** * Request shipping rates for entire address or specified address item + * * Returns true if current selected shipping method code corresponds to one of the found rates * * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item @@ -1348,7 +1349,7 @@ public function getAllBaseTotalAmounts() /******************************* End Total Collector Interface *******************************************/ /** - * {@inheritdoc} + * @inheritdoc */ protected function _getValidationRulesBeforeSave() { @@ -1356,7 +1357,7 @@ protected function _getValidationRulesBeforeSave() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCountryId() { @@ -1364,7 +1365,7 @@ public function getCountryId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($countryId) { @@ -1372,7 +1373,7 @@ public function setCountryId($countryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getStreet() { @@ -1381,7 +1382,7 @@ public function getStreet() } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -1389,7 +1390,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompany() { @@ -1397,7 +1398,7 @@ public function getCompany() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -1405,7 +1406,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function getTelephone() { @@ -1413,7 +1414,7 @@ public function getTelephone() } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -1421,7 +1422,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFax() { @@ -1429,7 +1430,7 @@ public function getFax() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -1437,7 +1438,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPostcode() { @@ -1445,7 +1446,7 @@ public function getPostcode() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -1453,7 +1454,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCity() { @@ -1461,7 +1462,7 @@ public function getCity() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -1469,7 +1470,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFirstname() { @@ -1477,7 +1478,7 @@ public function getFirstname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -1485,7 +1486,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getLastname() { @@ -1493,7 +1494,7 @@ public function getLastname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -1501,7 +1502,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getMiddlename() { @@ -1509,7 +1510,7 @@ public function getMiddlename() } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -1517,7 +1518,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPrefix() { @@ -1525,7 +1526,7 @@ public function getPrefix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -1533,7 +1534,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSuffix() { @@ -1541,7 +1542,7 @@ public function getSuffix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -1549,7 +1550,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getVatId() { @@ -1557,7 +1558,7 @@ public function getVatId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($vatId) { @@ -1565,7 +1566,7 @@ public function setVatId($vatId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerId() { @@ -1573,7 +1574,7 @@ public function getCustomerId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($customerId) { @@ -1581,7 +1582,7 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getEmail() { @@ -1594,7 +1595,7 @@ public function getEmail() } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -1602,7 +1603,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -1610,7 +1611,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($regionId) { @@ -1618,7 +1619,7 @@ public function setRegionId($regionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -1626,7 +1627,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSameAsBilling() { @@ -1634,7 +1635,7 @@ public function getSameAsBilling() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSameAsBilling($sameAsBilling) { @@ -1642,7 +1643,7 @@ public function setSameAsBilling($sameAsBilling) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerAddressId() { @@ -1650,7 +1651,7 @@ public function getCustomerAddressId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($customerAddressId) { @@ -1681,7 +1682,7 @@ public function setSaveInAddressBook($saveInAddressBook) //@codeCoverageIgnoreEnd /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null */ @@ -1691,7 +1692,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes * @return $this @@ -1712,7 +1713,7 @@ public function getShippingMethod() } /** - * {@inheritdoc} + * @inheritdoc */ protected function getCustomAttributesCodes() { diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php index 69c369f1ec9f6..e8ff8f09c345e 100644 --- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php +++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php @@ -14,6 +14,9 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question; +/** + * Config Set Command + */ class ConfigSetCommand extends AbstractSetupCommand { /** @@ -68,7 +71,7 @@ protected function configure() } /** - * {@inheritdoc} + * @inheritdoc */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -132,7 +135,7 @@ function ($value) { } /** - * {@inheritdoc} + * @inheritdoc */ protected function initialize(InputInterface $input, OutputInterface $output) { From 2beca3cec7c782ceff5b10eb9550a41fce4a479d Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 1 Nov 2018 17:40:35 +0200 Subject: [PATCH 0963/1415] ENGCOM-3063: Update colinmollenhour/cache-backend-redis from version 1.10.5 to 1.10.6 #18294 --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index c6d14eb38bc64..d4ac4fc091bbc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49fe82043cd4ae944939b6cceade1d1b", + "content-hash": "78153b5c8150c0d145b3372a534a45eb", "packages": [ { "name": "braintree/braintree_php", @@ -88,16 +88,16 @@ }, { "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.5", + "version": "1.10.6", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b" + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/91d949e28d939e607484a4bbf9307cff5afa689b", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/cc941a5f4cc017e11d3eab9061811ba9583ed6bf", + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2018-05-15T16:02:25+00:00" + "time": "2018-09-24T16:02:07+00:00" }, { "name": "colinmollenhour/credis", From 210c4e15364e3a5303515c94906c0eccf9782871 Mon Sep 17 00:00:00 2001 From: Cezary Zeglen <cezary.zeglen@gmail.com> Date: Fri, 24 Aug 2018 17:18:40 +0200 Subject: [PATCH 0964/1415] Fix translations of category design theme not being applied --- app/code/Magento/Catalog/Model/Design.php | 13 ++++++++++++- .../testsuite/Magento/Catalog/Model/DesignTest.php | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Design.php b/app/code/Magento/Catalog/Model/Design.php index bd7cdabb40856..6c0629feaf6fd 100644 --- a/app/code/Magento/Catalog/Model/Design.php +++ b/app/code/Magento/Catalog/Model/Design.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model; +use \Magento\Framework\TranslateInterface; + /** * Catalog Custom Category design Model * @@ -31,6 +33,11 @@ class Design extends \Magento\Framework\Model\AbstractModel */ protected $_localeDate; + /** + * @var TranslateInterface + */ + private $translator; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -47,10 +54,13 @@ public function __construct( \Magento\Framework\View\DesignInterface $design, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [] + array $data = [], + TranslateInterface $translator = null ) { $this->_localeDate = $localeDate; $this->_design = $design; + $this->translator = $translator ?: + \Magento\Framework\App\ObjectManager::getInstance()->get(TranslateInterface::class); parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -63,6 +73,7 @@ public function __construct( public function applyCustomDesign($design) { $this->_design->setDesignTheme($design); + $this->translator->loadData(null, true); return $this; } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php index 33f26302394f4..38960ab66399a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php @@ -32,8 +32,12 @@ public function testApplyCustomDesign($theme) $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\View\DesignInterface::class ); + $translate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\TranslateInterface::class + ); $this->assertEquals('package', $design->getDesignTheme()->getPackageCode()); $this->assertEquals('theme', $design->getDesignTheme()->getThemeCode()); + $this->assertEquals('themepackage/theme', $translate->getTheme()); } /** From 52381c16a8af9255dc032f13aa80d0dce8d8cd53 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 1 Nov 2018 11:21:58 -0500 Subject: [PATCH 0965/1415] MAGETWO-96034: DB compare of upgrade vs fresh install has some inconsistent table schemas --- app/code/Magento/Customer/etc/db_schema.xml | 2 +- app/code/Magento/Integration/etc/db_schema.xml | 2 +- app/code/Magento/Sales/etc/db_schema.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/etc/db_schema.xml b/app/code/Magento/Customer/etc/db_schema.xml index b3c15799011a2..8178baef71abb 100644 --- a/app/code/Magento/Customer/etc/db_schema.xml +++ b/app/code/Magento/Customer/etc/db_schema.xml @@ -506,7 +506,7 @@ <column xsi:type="int" name="customer_id" padding="11" unsigned="false" nullable="true" identity="false" comment="Customer Id"/> <column xsi:type="varchar" name="session_id" nullable="true" length="64" comment="Session ID"/> - <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" + <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Last Visit Time"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="visitor_id"/> diff --git a/app/code/Magento/Integration/etc/db_schema.xml b/app/code/Magento/Integration/etc/db_schema.xml index c2c2cedc665fb..1f702bfe4bc7a 100644 --- a/app/code/Magento/Integration/etc/db_schema.xml +++ b/app/code/Magento/Integration/etc/db_schema.xml @@ -136,7 +136,7 @@ comment="User type (admin or customer)"/> <column xsi:type="smallint" name="failures_count" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Number of failed authentication attempts in a row"/> - <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" + <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Lock expiration time"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml index 6847b4681de52..ced999bb86019 100644 --- a/app/code/Magento/Sales/etc/db_schema.xml +++ b/app/code/Magento/Sales/etc/db_schema.xml @@ -769,7 +769,7 @@ <column xsi:type="varchar" name="order_increment_id" nullable="false" length="32" comment="Order Increment Id"/> <column xsi:type="int" name="order_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Order Id"/> - <column xsi:type="timestamp" name="order_created_at" on_update="true" nullable="true" + <column xsi:type="timestamp" name="order_created_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Order Increment Id"/> <column xsi:type="varchar" name="customer_name" nullable="false" length="128" comment="Customer Name"/> <column xsi:type="decimal" name="total_qty" scale="4" precision="12" unsigned="false" nullable="true" From a0fddaa2777641013b57a62eac9649efc8d79fe8 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 18:45:27 +0200 Subject: [PATCH 0966/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- ...ingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 9dbd2eb0c1fae..6eb78809b187d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -10,13 +10,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> <annotations> - <features value="Tiered pricing and quantity increments work with decimal inventory"/> + <features value="Catalog"/> <stories value="Tiered pricing and quantity increments work with decimal inventory"/> <title value="Tiered pricing and quantity increments work with decimal inventory"/> <description value="Tiered pricing and quantity increments work with decimal inventory"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-91178"/> - <group value="product"/> + <testCaseId value="MAGETWO-93973"/> + <group value="Catalog"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> From 547c6fe2f67312c7ba70a8a91adb684766dae98b Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Thu, 1 Nov 2018 11:58:34 -0500 Subject: [PATCH 0967/1415] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - use filtered collection for loop --- app/code/Magento/Sales/Model/Order/ItemRepository.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index b1ff747d4f487..cdf5bdf99786e 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -229,7 +229,9 @@ private function addParentItem(OrderItemInterface $orderItem) if ($parentId = $orderItem->getParentItemId()) { $orderItem->setParentItem($this->get($parentId)); } else { - foreach ($orderItem->getOrder()->getAllItems() as $item) { + $orderCollection = $orderItem->getOrder()->getItemsCollection()->filterByParent($orderItem->getItemId()); + + foreach ($orderCollection->getItems() as $item) { if ($item->getParentItemId() === $orderItem->getItemId()) { $item->setParentItem($orderItem); } From a5ac2dc694e4fa6224754e0a68936e252bd4c91c Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 19:30:20 +0200 Subject: [PATCH 0968/1415] MAGETWO-96024: Invalid element declared for AdminProductGridSection section --- .../AdminProductGridActionGroup.xml | 23 +++++++++++++ .../Mftf/Section/AdminProductGridSection.xml | 1 + ...atusProductUsingProductGridActionGroup.xml | 33 ------------------- .../Mftf/Section/AdminProductGridSection.xml | 14 -------- 4 files changed, 24 insertions(+), 47 deletions(-) delete mode 100644 app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml delete mode 100644 app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml index 1bd9bb4a09c86..e17f9933cbcab 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml @@ -206,4 +206,27 @@ <conditionalClick selector="{{AdminProductGridTableHeaderSection.id('descend')}}" dependentSelector="{{AdminProductGridTableHeaderSection.id('ascend')}}" visible="false" stepKey="sortById"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> + + <!--Disabled a product by filtering grid and using change status action--> + <actionGroup name="ChangeStatusProductUsingProductGridActionGroup"> + <arguments> + <argument name="product"/> + <argument name="status" defaultValue="Enable" type="string" /> + </arguments> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad time="60" stepKey="waitForPageLoadInitial"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <click selector="{{AdminProductGridFilterSection.filters}}" stepKey="openProductFilters"/> + <fillField selector="{{AdminProductGridFilterSection.skuFilter}}" userInput="{{product.sku}}" stepKey="fillProductSkuFilter"/> + <click selector="{{AdminProductGridFilterSection.applyFilters}}" stepKey="clickApplyFilters"/> + <see selector="{{AdminProductGridSection.productGridCell('1', 'SKU')}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> + <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> + <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> + + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickChangeStatusAction"/> + <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled" parameterized="true"/> + <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml index a7e20e22f1ddc..304cb621e5d9b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml @@ -29,5 +29,6 @@ <element name="productGridCheckboxOnRow" type="checkbox" selector="//*[@id='container']//tr[{{row}}]/td[1]//input" parameterized="true"/> <element name="productGridNameProduct" type="input" selector="//tbody//tr//td//div[contains(., '{{var1}}')]" parameterized="true" timeout="30"/> <element name="selectRowBasedOnName" type="input" selector="//td/div[text()='{{var1}}']" parameterized="true"/> + <element name="changeStatus" type="button" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml deleted file mode 100644 index dba4a94f3db2a..0000000000000 --- a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <!--Disabled a product by filtering grid and using change status action--> - <actionGroup name="ChangeStatusProductUsingProductGridActionGroup"> - <arguments> - <argument name="product"/> - <argument name="status" defaultValue="Enable" type="string" /> - </arguments> - <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> - <waitForPageLoad time="60" stepKey="waitForPageLoadInitial"/> - <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> - <click selector="{{AdminProductGridFilterSection.filters}}" stepKey="openProductFilters"/> - <fillField selector="{{AdminProductGridFilterSection.skuFilter}}" userInput="{{product.sku}}" stepKey="fillProductSkuFilter"/> - <click selector="{{AdminProductGridFilterSection.applyFilters}}" stepKey="clickApplyFilters"/> - <see selector="{{AdminProductGridSection.productGridCell('1', 'SKU')}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> - <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> - <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> - - <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> - <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickChangeStatusAction"/> - <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled" parameterized="true"/> - <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> - <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml deleted file mode 100644 index 32ac73aca7c03..0000000000000 --- a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="AdminProductGridSection"> - <element name="changeStatus" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" stepKey="clickChangeStatus" parameterized="true"/> - </section> -</sections> From 23ad12aee17c8d5f7c4a48ae76a85b458664b1fa Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Thu, 1 Nov 2018 19:24:16 +0100 Subject: [PATCH 0969/1415] Fixed annotations for setData() setData() should return objects class - that inherits from --- app/code/Magento/Catalog/Model/AbstractModel.php | 2 +- app/code/Magento/Customer/Model/Address/AbstractAddress.php | 2 +- app/code/Magento/Sales/Model/Order/Address.php | 2 +- app/code/Magento/Widget/Block/BlockInterface.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/AbstractModel.php b/app/code/Magento/Catalog/Model/AbstractModel.php index 007635b124331..5faf6ccbcdef9 100644 --- a/app/code/Magento/Catalog/Model/AbstractModel.php +++ b/app/code/Magento/Catalog/Model/AbstractModel.php @@ -179,7 +179,7 @@ public function isLockedAttribute($attributeCode) * * @param string|array $key * @param mixed $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 3ee284a705b16..19f91953a074e 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -272,7 +272,7 @@ public function setStreet($street) * * @param array|string $key * @param null $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index 77d8330a72550..8bc602c75db4d 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -174,7 +174,7 @@ protected function implodeStreetValue($value) * * @param array|string $key * @param null $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Widget/Block/BlockInterface.php b/app/code/Magento/Widget/Block/BlockInterface.php index ddf810f433f3a..db101b5e81adc 100644 --- a/app/code/Magento/Widget/Block/BlockInterface.php +++ b/app/code/Magento/Widget/Block/BlockInterface.php @@ -35,7 +35,7 @@ public function addData(array $arr); * * @param string|array $key * @param mixed $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null); } From 2533e88aea6e5834f632ff631e5a4cce6e1496b0 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Thu, 1 Nov 2018 16:27:20 -0500 Subject: [PATCH 0970/1415] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - Update unit test coverage to include changed functionality --- .../Unit/Model/Order/ItemRepositoryTest.php | 94 ++++++++++++------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index 5e1b49c0013e3..7f3626c25d8df 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -145,7 +145,7 @@ public function testGetEmptyEntity() $model->get($orderItemId); } - public function testGet() + public function testGetAsParentWithChild() { $orderItemId = 1; $productType = 'configurable'; @@ -154,18 +154,27 @@ public function testGet() $this->getProductOptionExtensionMock(); $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); + + $orderItemCollectionMock = $this->createMock(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class); + $orderItemCollectionMock->expects($this->once()) + ->method('filterByParent') + ->with($orderItemId) + ->willReturnSelf(); + $orderItemCollectionMock->expects($this->once()) + ->method('getItems') + ->willReturn([$orderItemMock]); $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); $orderMock->expects($this->once()) - ->method('getAllItems') - ->willReturn([$orderItemMock]); + ->method('getItemsCollection') + ->willReturn($orderItemCollectionMock); $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->exactly(2)) + $orderItemMock->expects($this->exactly(3)) ->method('getItemId') ->willReturn($orderItemId); $orderItemMock->expects($this->once()) @@ -183,6 +192,45 @@ public function testGet() $this->assertSame($orderItemMock, $model->get($orderItemId)); } + public function testGetAsChild() + { + $orderItemId = 1; + $parentItemId = 66; + $productType = 'configurable'; + + $this->productOptionData = ['option1' => 'value1']; + + $this->getProductOptionExtensionMock(); + $productOption = $this->getProductOptionMock(); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); + + $orderItemMock->expects($this->once()) + ->method('load') + ->with($orderItemId) + ->willReturn($orderItemMock); + $orderItemMock->expects($this->once()) + ->method('getItemId') + ->willReturn($orderItemId); + $orderItemMock->expects($this->exactly(3)) + ->method('getParentItemId') + ->willReturn($parentItemId); + + $this->metadata->expects($this->once()) + ->method('getNewInstance') + ->willReturn($orderItemMock); + + $parentItemMock = $this->createMock(\Magento\Sales\Model\Order\Item::class); + + $model = $this->getModel($orderItemMock, $productType); + $reflectedRegistryProperty = new \ReflectionProperty($model, 'registry'); + $reflectedRegistryProperty->setAccessible(true); + $reflectedRegistryProperty->setValue($model, [$parentItemId => $parentItemMock]); + $this->assertSame($orderItemMock, $model->get($orderItemId)); + + // Assert already registered + $this->assertSame($orderItemMock, $model->get($orderItemId)); + } + public function testGetList() { $productType = 'configurable'; @@ -192,7 +240,7 @@ public function testGetList() ->getMock(); $this->getProductOptionExtensionMock(); $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); $searchResultMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class) ->disableOriginalConstructor() @@ -214,35 +262,12 @@ public function testDeleteById() $orderItemId = 1; $productType = 'configurable'; - $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) ->disableOriginalConstructor() ->getMock(); - - $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); - $orderMock->expects($this->once()) - ->method('getAllItems') - ->willReturn([$orderItemMock]); - $orderItemMock->expects($this->once()) - ->method('load') - ->with($orderItemId) - ->willReturn($orderItemMock); - $orderItemMock->expects($this->exactly(2)) - ->method('getItemId') + ->method('getEntityId') ->willReturn($orderItemId); - $orderItemMock->expects($this->once()) - ->method('getProductType') - ->willReturn($productType); - $orderItemMock->expects($this->once()) - ->method('getBuyRequest') - ->willReturn($requestMock); - $orderItemMock->expects($this->once()) - ->method('getOrder') - ->willReturn($orderMock); $orderItemResourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) ->disableOriginalConstructor() @@ -252,15 +277,16 @@ public function testDeleteById() ->with($orderItemMock) ->willReturnSelf(); - $this->metadata->expects($this->once()) - ->method('getNewInstance') - ->willReturn($orderItemMock); $this->metadata->expects($this->exactly(1)) ->method('getMapper') ->willReturn($orderItemResourceMock); $model = $this->getModel($orderItemMock, $productType); + $reflectedRegistryProperty = new \ReflectionProperty($model, 'registry'); + $reflectedRegistryProperty->setAccessible(true); + $reflectedRegistryProperty->setValue($model, [$orderItemId => $orderItemMock]); $this->assertTrue($model->deleteById($orderItemId)); + $this->assertEmpty($reflectedRegistryProperty->getValue($model)); } /** @@ -318,7 +344,7 @@ protected function getModel( * @param \PHPUnit_Framework_MockObject_MockObject $productOption * @return \PHPUnit_Framework_MockObject_MockObject */ - protected function getOrderMock($productType, $productOption) + protected function getOrderItemMock($productType, $productOption) { $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() From cbf828a00a9a2287d7c7bb640f3c1078410b4de4 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Wed, 24 Oct 2018 20:55:30 -0400 Subject: [PATCH 0971/1415] Separate interception config logic Moves the logic responsible for loading, saving, clearing the interception config cache into it's own class --- app/etc/di.xml | 6 + .../Framework/Interception/AbstractPlugin.php | 8 +- .../{ConfigTest.php => CacheManagerTest.php} | 15 +-- .../Interception/Config/CacheManager.php | 113 ++++++++++++++++++ .../Framework/Interception/Config/Config.php | 71 +++-------- .../Test/Unit/Config/ConfigTest.php | 42 ++----- 6 files changed, 157 insertions(+), 98 deletions(-) rename dev/tests/integration/testsuite/Magento/Framework/Interception/Config/{ConfigTest.php => CacheManagerTest.php} (87%) create mode 100644 lib/internal/Magento/Framework/Interception/Config/CacheManager.php diff --git a/app/etc/di.xml b/app/etc/di.xml index b374645240ff7..acdd48a393b5e 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -28,6 +28,7 @@ <preference for="Magento\Framework\App\CacheInterface" type="Magento\Framework\App\Cache\Proxy" /> <preference for="Magento\Framework\App\Cache\StateInterface" type="Magento\Framework\App\Cache\State" /> <preference for="Magento\Framework\App\Cache\TypeListInterface" type="Magento\Framework\App\Cache\TypeList" /> + <preference for="Magento\Framework\App\ObjectManager\ConfigWriterInterface" type="Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem" /> <preference for="Magento\Store\Model\StoreManagerInterface" type="Magento\Store\Model\StoreManager" /> <preference for="Magento\Framework\View\DesignInterface" type="Magento\Theme\Model\View\Design\Proxy" /> <preference for="Magento\Framework\View\Design\ThemeInterface" type="Magento\Theme\Model\Theme" /> @@ -412,6 +413,11 @@ <argument name="cacheId" xsi:type="string">interception</argument> </arguments> </type> + <type name="Magento\Framework\Interception\Config\CacheManager"> + <arguments> + <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Config</argument> + </arguments> + </type> <type name="Magento\Framework\Interception\PluginList\PluginList"> <arguments> <argument name="cache" xsi:type="object">Magento\Framework\App\Cache\Type\Config</argument> diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php index a85e5e7c89482..60eb511dcb6b5 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php @@ -59,7 +59,8 @@ public function setUpInterceptionConfig($pluginConfig) $areaList->expects($this->any())->method('getCodes')->will($this->returnValue([])); $configScope = new \Magento\Framework\Config\Scope($areaList, 'global'); $cache = $this->createMock(\Magento\Framework\Config\CacheInterface::class); - $cache->expects($this->any())->method('load')->will($this->returnValue(false)); + $cacheManager = $this->createMock(\Magento\Framework\Interception\Config\CacheManager::class); + $cacheManager->method('load')->willReturn(null); $definitions = new \Magento\Framework\ObjectManager\Definition\Runtime(); $relations = new \Magento\Framework\ObjectManager\Relations\Runtime(); $interceptionConfig = new Config\Config( @@ -68,7 +69,10 @@ public function setUpInterceptionConfig($pluginConfig) $cache, $relations, $config, - $definitions + $definitions, + 'interception', + null, + $cacheManager ); $interceptionDefinitions = new Definition\Runtime(); $json = new \Magento\Framework\Serialize\Serializer\Json(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php similarity index 87% rename from dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php rename to dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php index 1ece9189169bb..9d5abd1a8a6c6 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php @@ -10,7 +10,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; -class ConfigTest extends \PHPUnit\Framework\TestCase +class CacheManagerTest extends \PHPUnit\Framework\TestCase { const CACHE_ID = 'interceptiontest'; @@ -68,9 +68,7 @@ public function testInstantiateFromCompiled(array $testConfig) $this->configWriter->write(self::CACHE_ID, $testConfig); $config = $this->getConfig(); - foreach ($testConfig as $className => $hasPlugins) { - $this->assertEquals($hasPlugins, $config->hasPlugins($className)); - } + $this->assertEquals($testConfig, $config->load(self::CACHE_ID)); } /** @@ -83,9 +81,7 @@ public function testInstantiateFromCache(array $testConfig) $this->cache->save($this->serializer->serialize($testConfig), self::CACHE_ID); $config = $this->getConfig(); - foreach ($testConfig as $className => $hasPlugins) { - $this->assertEquals($hasPlugins, $config->hasPlugins($className)); - } + $this->assertEquals($testConfig, $config->load(self::CACHE_ID)); } public function interceptionCompiledConfigDataProvider() @@ -121,16 +117,15 @@ private function initializeMetadataDirectory() * from altering the interception config that may have been generated during application * installation. Inject a new instance of the compileLoaded to bypass it's caching. * - * @return \Magento\Framework\Interception\Config\Config + * @return \Magento\Framework\Interception\Config\CacheManager */ private function getConfig() { return $this->objectManager->create( - \Magento\Framework\Interception\Config\Config::class, + \Magento\Framework\Interception\Config\CacheManager::class, [ 'cacheId' => self::CACHE_ID, 'compiledLoader' => $this->objectManager->create(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class), - 'serializer' => $this->serializer, ] ); } diff --git a/lib/internal/Magento/Framework/Interception/Config/CacheManager.php b/lib/internal/Magento/Framework/Interception/Config/CacheManager.php new file mode 100644 index 0000000000000..cd16e2277d87a --- /dev/null +++ b/lib/internal/Magento/Framework/Interception/Config/CacheManager.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\Interception\Config; + +/** + * Interception cache manager responsible for handling interaction with compiled and + * uncompiled interception data + */ +class CacheManager +{ + /** + * @var \Magento\Framework\Cache\FrontendInterface + */ + private $cache; + + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigWriterInterface + */ + private $configWriter; + + /** + * @var \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled + */ + private $compiledLoader; + + /** + * @param \Magento\Framework\Cache\FrontendInterface $cache + * @param \Magento\Framework\Serialize\SerializerInterface $serializer + * @param \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter + * @param \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader + */ + public function __construct( + \Magento\Framework\Cache\FrontendInterface $cache, + \Magento\Framework\Serialize\SerializerInterface $serializer, + \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter, + \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader + ) { + $this->cache = $cache; + $this->serializer = $serializer; + $this->configWriter = $configWriter; + $this->compiledLoader = $compiledLoader; + } + + /** + * Load the interception config from cache + * + * @param string $key + * @return array|null + */ + public function load(string $key): ?array + { + if ($this->isCompiled($key)) { + return $this->compiledLoader->load($key); + } + + $intercepted = $this->cache->load($key); + return $intercepted ? $this->serializer->unserialize($intercepted) : null; + } + + /** + * Save config to cache backend + * + * @param string $key + * @param array $data + */ + public function save(string $key, array $data) + { + $this->cache->save($this->serializer->serialize($data), $key); + } + + /** + * Save config to filesystem + * + * @param string $key + * @param array $data + */ + public function saveCompiled(string $key, array $data) + { + $this->configWriter->write($key, $data); + } + + /** + * Purge interception cache + * + * @param string $key + */ + public function clean(string $key) + { + $this->cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$key]); + } + + /** + * Check for the compiled config with the generated metadata + * + * @param string $key + * @return bool + */ + private function isCompiled(string $key): bool + { + return file_exists(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::getFilePath($key)); + } +} diff --git a/lib/internal/Magento/Framework/Interception/Config/Config.php b/lib/internal/Magento/Framework/Interception/Config/Config.php index 9a7845e96006b..4eeed4788a05e 100644 --- a/lib/internal/Magento/Framework/Interception/Config/Config.php +++ b/lib/internal/Magento/Framework/Interception/Config/Config.php @@ -8,7 +8,6 @@ namespace Magento\Framework\Interception\Config; use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Serialize; class Config implements \Magento\Framework\Interception\ConfigInterface { @@ -35,7 +34,7 @@ class Config implements \Magento\Framework\Interception\ConfigInterface /** * Cache - * + * @deprecated * @var \Magento\Framework\Cache\FrontendInterface */ protected $_cache; @@ -74,33 +73,24 @@ class Config implements \Magento\Framework\Interception\ConfigInterface protected $_scopeList; /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @var \Magento\Framework\App\ObjectManager\ConfigWriterInterface - */ - private $configWriter; - - /** - * @var \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled + * @var CacheManager */ - private $compiledLoader; + private $cacheManager; /** * Config constructor * * @param \Magento\Framework\Config\ReaderInterface $reader * @param \Magento\Framework\Config\ScopeListInterface $scopeList - * @param \Magento\Framework\Cache\FrontendInterface $cache + * @param \Magento\Framework\Cache\FrontendInterface $cache @deprecated * @param \Magento\Framework\ObjectManager\RelationsInterface $relations * @param \Magento\Framework\Interception\ObjectManager\ConfigInterface $omConfig * @param \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions * @param string $cacheId - * @param SerializerInterface|null $serializer - * @param \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter - * @param \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader + * @param SerializerInterface|null $serializer @deprecated + * @param CacheManager $cacheManager + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Framework\Config\ReaderInterface $reader, @@ -111,8 +101,7 @@ public function __construct( \Magento\Framework\ObjectManager\DefinitionInterface $classDefinitions, $cacheId = 'interception', SerializerInterface $serializer = null, - \Magento\Framework\App\ObjectManager\ConfigWriterInterface $configWriter = null, - \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled $compiledLoader = null + CacheManager $cacheManager = null ) { $this->_omConfig = $omConfig; $this->_relations = $relations; @@ -121,14 +110,9 @@ public function __construct( $this->_cacheId = $cacheId; $this->_reader = $reader; $this->_scopeList = $scopeList; - $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(Serialize::class); - $this->configWriter = $configWriter ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); - $this->compiledLoader = $compiledLoader ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class); - $intercepted = $this->loadIntercepted(); - if ($intercepted !== false) { + $this->cacheManager = $cacheManager ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CacheManager::class); + $intercepted = $this->cacheManager->load($cacheId); + if ($intercepted !== null) { $this->_intercepted = $intercepted; } else { $this->initializeUncompiled($this->_classDefinitions->getClasses()); @@ -145,7 +129,7 @@ public function initialize($classDefinitions = []) { $this->generateIntercepted($classDefinitions); - $this->configWriter->write($this->_cacheId, $this->_intercepted); + $this->cacheManager->saveCompiled($this->_cacheId, $this->_intercepted); } /** @@ -199,11 +183,11 @@ public function hasPlugins($type) */ private function initializeUncompiled($classDefinitions = []) { - $this->_cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_TAG, [$this->_cacheId]); + $this->cacheManager->clean($this->_cacheId); $this->generateIntercepted($classDefinitions); - $this->_cache->save($this->serializer->serialize($this->_intercepted), $this->_cacheId); + $this->cacheManager->save($this->_cacheId, $this->_intercepted); } /** @@ -230,29 +214,4 @@ private function generateIntercepted($classDefinitions) $this->hasPlugins($class); } } - - /** - * Load the interception config from cache - * - * @return array|false - */ - private function loadIntercepted() - { - if ($this->isCompiled()) { - return $this->compiledLoader->load($this->_cacheId); - } - - $intercepted = $this->_cache->load($this->_cacheId); - return $intercepted ? $this->serializer->unserialize($intercepted) : false; - } - - /** - * Check for the compiled config with the generated metadata - * - * @return bool - */ - private function isCompiled() - { - return file_exists(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::getFilePath($this->_cacheId)); - } } diff --git a/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php b/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php index fe8d29bd0d51d..61eb2e62091ea 100644 --- a/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php +++ b/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php @@ -31,11 +31,6 @@ class ConfigTest extends \PHPUnit\Framework\TestCase */ private $readerMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $cacheMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -51,8 +46,10 @@ class ConfigTest extends \PHPUnit\Framework\TestCase */ private $relationsMock; - /** @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $serializerMock; + /** + * @var \Magento\Framework\Interception\Config\CacheManager|\PHPUnit_Framework_MockObject_MockObject + */ + private $cacheManagerMock; /** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ private $objectManagerHelper; @@ -61,7 +58,6 @@ protected function setUp() { $this->readerMock = $this->createMock(\Magento\Framework\ObjectManager\Config\Reader\Dom::class); $this->configScopeMock = $this->createMock(\Magento\Framework\Config\ScopeListInterface::class); - $this->cacheMock = $this->createMock(\Magento\Framework\Cache\FrontendInterface::class); $this->omConfigMock = $this->getMockForAbstractClass( \Magento\Framework\Interception\ObjectManager\ConfigInterface::class ); @@ -69,7 +65,7 @@ protected function setUp() $this->relationsMock = $this->getMockForAbstractClass( \Magento\Framework\ObjectManager\RelationsInterface::class ); - $this->serializerMock = $this->createMock(SerializerInterface::class); + $this->cacheManagerMock = $this->createMock(\Magento\Framework\Interception\Config\CacheManager::class); $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); } @@ -88,9 +84,9 @@ public function testHasPluginsWhenDataIsNotCached($expectedResult, $type, $entit ->method('getAllScopes') ->will($this->returnValue(['global', 'backend', 'frontend'])); // turn cache off - $this->cacheMock->expects($this->any()) + $this->cacheManagerMock->expects($this->any()) ->method('load') - ->will($this->returnValue(false)); + ->will($this->returnValue(null)); $this->omConfigMock->expects($this->any()) ->method('getOriginalInstanceType') ->will($this->returnValueMap( @@ -138,21 +134,15 @@ public function testHasPluginsWhenDataIsNotCached($expectedResult, $type, $entit $this->relationsMock->expects($this->any())->method('has')->will($this->returnValue($expectedResult)); $this->relationsMock->expects($this->any())->method('getParents')->will($this->returnValue($entityParents)); - $this->serializerMock->expects($this->once()) - ->method('serialize'); - - $this->serializerMock->expects($this->never())->method('unserialize'); - $model = $this->objectManagerHelper->getObject( \Magento\Framework\Interception\Config\Config::class, [ 'reader' => $this->readerMock, 'scopeList' => $this->configScopeMock, - 'cache' => $this->cacheMock, + 'cacheManager' => $this->cacheManagerMock, 'relations' => $this->relationsMock, 'omConfig' => $this->omConfigMock, 'classDefinitions' => $this->definitionMock, - 'serializer' => $this->serializerMock ] ); @@ -177,32 +167,24 @@ public function testHasPluginsWhenDataIsCached($expectedResult, $type) 'virtual_custom_item' => true ]; $this->readerMock->expects($this->never())->method('read'); - $this->cacheMock->expects($this->never())->method('save'); - $serializedValue = 'serializedData'; - $this->cacheMock->expects($this->any()) + $this->cacheManagerMock->expects($this->never())->method('save'); + $this->cacheManagerMock->expects($this->any()) ->method('load') ->with($cacheId) - ->will($this->returnValue($serializedValue)); - - $this->serializerMock->expects($this->never())->method('serialize'); - $this->serializerMock->expects($this->once()) - ->method('unserialize') - ->with($serializedValue) - ->willReturn($interceptionData); + ->will($this->returnValue($interceptionData)); $model = $this->objectManagerHelper->getObject( \Magento\Framework\Interception\Config\Config::class, [ 'reader' => $this->readerMock, 'scopeList' => $this->configScopeMock, - 'cache' => $this->cacheMock, + 'cacheManager' => $this->cacheManagerMock, 'relations' => $this->objectManagerHelper->getObject( \Magento\Framework\ObjectManager\Relations\Runtime::class ), 'omConfig' => $this->omConfigMock, 'classDefinitions' => $this->definitionMock, 'cacheId' => $cacheId, - 'serializer' => $this->serializerMock ] ); From ea661055fc94c1f5a3c7399463915491acc8c0a5 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 11:41:20 +0300 Subject: [PATCH 0972/1415] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Fix comments --- .../Catalog/Model/Indexer/Category/Product/AbstractAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index a1358c02ce9fc..178f4172ce6fa 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -605,7 +605,7 @@ protected function getTemporaryTreeIndexTableName() if (empty($this->tempTreeIndexTableName)) { $this->tempTreeIndexTableName = $this->connection->getTableName('temp_catalog_category_tree_index') . '_' - . substr(md5(time() . random_int(0, 999999999)), 0, 8); + . substr(sha1(time() . random_int(0, 999999999)), 0, 8); } return $this->tempTreeIndexTableName; From 480aa38783f28951ed10f16177aaf3f295818f9e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 11:53:15 +0300 Subject: [PATCH 0973/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix comments --- .../Magento/Catalog/Block/Product/ProductList/Toolbar.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index c7a9fcce7bf7a..a2cbc5087cd12 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -161,10 +161,10 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, ProductList $productListHelper, \Magento\Framework\Data\Helper\PostHelper $postDataHelper, + array $data = [], ToolbarMemorizer $toolbarMemorizer = null, \Magento\Framework\App\Http\Context $httpContext = null, - \Magento\Framework\Data\Form\FormKey $formKey = null, - array $data = [] + \Magento\Framework\Data\Form\FormKey $formKey = null ) { $this->_catalogSession = $catalogSession; $this->_catalogConfig = $catalogConfig; From 71e6f40b1c00b55fd59694ad040749ea26ebbb97 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Fri, 2 Nov 2018 11:31:20 +0200 Subject: [PATCH 0974/1415] Removed method annotation without argument from PHPDoc --- app/code/Magento/Backend/Block/Widget/Grid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Widget/Grid.php b/app/code/Magento/Backend/Block/Widget/Grid.php index 72ab5a265d808..e9394be9e60bd 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid.php +++ b/app/code/Magento/Backend/Block/Widget/Grid.php @@ -12,7 +12,7 @@ * @api * @deprecated 100.2.0 in favour of UI component implementation * @method string getRowClickCallback() getRowClickCallback() - * @method \Magento\Backend\Block\Widget\Grid setRowClickCallback() setRowClickCallback(string $value) + * @method \Magento\Backend\Block\Widget\Grid setRowClickCallback(string $value) * @SuppressWarnings(PHPMD.TooManyFields) * @since 100.0.2 */ From 0cf59de0e706b213e836949700a713fdfa9cf4f4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 11:33:02 +0200 Subject: [PATCH 0975/1415] Added user permission check --- .../Model/Resolver/CartAddress.php | 30 +++++++++++++++---- .../SetShippingMethodsOnCart.php | 8 +++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php index f83a112ba5ba8..d2b502688adbc 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -10,11 +10,13 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteId; +use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; /** @@ -27,6 +29,11 @@ class CartAddress implements ResolverInterface */ private $addressDataProvider; + /** + * @var IsCartMutationAllowedForCurrentUser + */ + private $isCartMutationAllowedForCurrentUser; + /** * @var CartRepositoryInterface */ @@ -43,15 +50,18 @@ class CartAddress implements ResolverInterface * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider + * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, CartRepositoryInterface $cartRepository, - AddressDataProvider $addressDataProvider + AddressDataProvider $addressDataProvider, + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; + $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -59,20 +69,30 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { + /* The cart_id is used instead of the model because some parent resolvers do not work + with cart model */ if (!isset($value['cart_id'])) { - // TODO: consider the possibility to pass quote model instead od quote ID throw new LocalizedException(__('"cart_id" value should be specified')); } + $maskedCartId = $value['cart_id']; + try { - $quoteId = $this->maskedQuoteIdToQuoteId->execute($value['cart_id']); + $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $value['cart_id']]) + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) ); } - // TODO: should we check customer permissions here as well? + if (false === $this->isCartMutationAllowedForCurrentUser->execute($quoteId)) { + throw new GraphQlAuthorizationException( + __( + 'The current user cannot perform operations on cart "%masked_cart_id"', + ['masked_cart_id' => $maskedCartId] + ) + ); + } try { $quote = $this->cartRepository->get($quoteId); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 1f35f37d9cf23..7e35f97d9f711 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -72,13 +72,17 @@ class SetShippingMethodsOnCart implements ResolverInterface * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + * @param ShippingInformationManagementInterface $shippingInformationManagement + * @param QuoteAddressFactory $quoteAddressFactory + * @param QuoteAddressResource $quoteAddressResource + * @param ShippingInformationFactory $shippingInformationFactory */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, ShippingInformationManagementInterface $shippingInformationManagement, - QuoteAddressFactory $quoteAddressFacrory, + QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { @@ -88,7 +92,7 @@ public function __construct( $this->shippingInformationManagement = $shippingInformationManagement; $this->quoteAddressResource = $quoteAddressResource; - $this->quoteAddressFactory = $quoteAddressFacrory; + $this->quoteAddressFactory = $quoteAddressFactory; $this->shippingInformationFactory = $shippingInformationFactory; } From 5c0bcfd2160d549c082d7f51df0562ab674a9fe6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 11:58:47 +0200 Subject: [PATCH 0976/1415] Refactored flow for new authorization check logic --- .../Model/Resolver/CartAddress.php | 49 ++--------------- .../SetShippingMethodsOnCart.php | 52 +++++-------------- 2 files changed, 19 insertions(+), 82 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php index d2b502688adbc..54bd8fa2a5717 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -8,15 +8,11 @@ namespace Magento\QuoteGraphQl\Model\Resolver; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteId; -use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; /** @@ -29,11 +25,6 @@ class CartAddress implements ResolverInterface */ private $addressDataProvider; - /** - * @var IsCartMutationAllowedForCurrentUser - */ - private $isCartMutationAllowedForCurrentUser; - /** * @var CartRepositoryInterface */ @@ -50,18 +41,15 @@ class CartAddress implements ResolverInterface * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider - * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, CartRepositoryInterface $cartRepository, - AddressDataProvider $addressDataProvider, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + AddressDataProvider $addressDataProvider ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; - $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -69,39 +57,12 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - /* The cart_id is used instead of the model because some parent resolvers do not work - with cart model */ - if (!isset($value['cart_id'])) { - throw new LocalizedException(__('"cart_id" value should be specified')); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); } - $maskedCartId = $value['cart_id']; - - try { - $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) - ); - } - - if (false === $this->isCartMutationAllowedForCurrentUser->execute($quoteId)) { - throw new GraphQlAuthorizationException( - __( - 'The current user cannot perform operations on cart "%masked_cart_id"', - ['masked_cart_id' => $maskedCartId] - ) - ); - } - - try { - $quote = $this->cartRepository->get($quoteId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%quote_id"', ['quote_id' => $quoteId]) - ); - } + $cart = $value['model']; - return $this->addressDataProvider->getCartAddresses($quote); + return $this->addressDataProvider->getCartAddresses($cart); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 7e35f97d9f711..97a7bcea8aa48 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -12,18 +12,16 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Checkout\Model\ShippingInformationFactory; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; /** * Class SetShippingMethodsOnCart @@ -47,20 +45,15 @@ class SetShippingMethodsOnCart implements ResolverInterface */ private $quoteAddressResource; - /** - * @var MaskedQuoteIdToQuoteIdInterface - */ - private $maskedQuoteIdToQuoteId; - /** * @var ArrayManager */ private $arrayManager; /** - * @var IsCartMutationAllowedForCurrentUser + * @var GetCartForUser */ - private $isCartMutationAllowedForCurrentUser; + private $getCartForUser; /** * @var ShippingInformationManagementInterface @@ -70,8 +63,7 @@ class SetShippingMethodsOnCart implements ResolverInterface /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager - * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + * @param GetCartForUser $getCartForUser * @param ShippingInformationManagementInterface $shippingInformationManagement * @param QuoteAddressFactory $quoteAddressFactory * @param QuoteAddressResource $quoteAddressResource @@ -79,18 +71,15 @@ class SetShippingMethodsOnCart implements ResolverInterface */ public function __construct( ArrayManager $arrayManager, - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, + GetCartForUser $getCartForUser, ShippingInformationManagementInterface $shippingInformationManagement, QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { $this->arrayManager = $arrayManager; - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; + $this->getCartForUser = $getCartForUser; $this->shippingInformationManagement = $shippingInformationManagement; - $this->quoteAddressResource = $quoteAddressResource; $this->quoteAddressFactory = $quoteAddressFactory; $this->shippingInformationFactory = $shippingInformationFactory; @@ -111,34 +100,20 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } - $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping + $shippingMethod = reset($shippingMethods); if (!$shippingMethod['cart_address_id']) { throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); } - if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here + if (!$shippingMethod['shipping_carrier_code']) { throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here + if (!$shippingMethod['shipping_method_code']) { throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); } - try { - $cartId = $this->maskedQuoteIdToQuoteId->execute((string) $maskedCartId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) - ); - } - - if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { - throw new GraphQlAuthorizationException( - __( - 'The current user cannot perform operations on cart "%masked_cart_id"', - ['masked_cart_id' => $maskedCartId] - ) - ); - } + $userId = $context->getUserId(); + $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); $quoteAddress = $this->quoteAddressFactory->create(); $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); @@ -153,7 +128,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); try { - $this->shippingInformationManagement->saveAddressInformation($cartId, $shippingInformation); + $this->shippingInformationManagement->saveAddressInformation($cart->getId(), $shippingInformation); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException(__($exception->getMessage())); } catch (StateException $exception) { @@ -164,7 +139,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'cart' => [ - 'cart_id' => $maskedCartId + 'cart_id' => $maskedCartId, + 'model' => $cart ] ]; } From effd4cd58724717aa561f8745a13b32c1d5125f2 Mon Sep 17 00:00:00 2001 From: Bernard van der Esch <b.vanderesch@gmail.com> Date: Fri, 2 Nov 2018 11:29:18 +0100 Subject: [PATCH 0977/1415] missing use statement in layout generator --- lib/internal/Magento/Framework/View/Layout/Generator/Block.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php index bc250c54e7946..c69421cda339a 100755 --- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php @@ -6,6 +6,7 @@ namespace Magento\Framework\View\Layout\Generator; use Magento\Framework\App\State; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\ObjectManager\Config\Reader\Dom; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Layout; From c98c3d5142d73789e8233deb4aa90f172d716c21 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 12:29:44 +0200 Subject: [PATCH 0978/1415] Logic for setting shipping method is moved to a separate class --- .../SetShippingMethodOnCart.php} | 84 ++++------------ .../Resolver/SetShippingMethodsOnCart.php | 99 +++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 119 insertions(+), 66 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver/ShippingMethod/SetShippingMethodsOnCart.php => Cart/SetShippingMethodOnCart.php} (54%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php similarity index 54% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php index 97a7bcea8aa48..7f945dca2fd76 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php @@ -5,30 +5,26 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; +namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Checkout\Api\ShippingInformationManagementInterface; -use Magento\Checkout\Model\ShippingInformation; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Checkout\Model\ShippingInformationFactory; -use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\Checkout\Api\ShippingInformationManagementInterface; +use Magento\Checkout\Model\ShippingInformation; /** * Class SetShippingMethodsOnCart * - * Mutation resolver for setting shipping methods for shopping cart + * Set shipping method for a specified shopping cart address */ -class SetShippingMethodsOnCart implements ResolverInterface +class SetShippingMethodOnCart { /** * @var ShippingInformationFactory @@ -45,40 +41,23 @@ class SetShippingMethodsOnCart implements ResolverInterface */ private $quoteAddressResource; - /** - * @var ArrayManager - */ - private $arrayManager; - - /** - * @var GetCartForUser - */ - private $getCartForUser; - /** * @var ShippingInformationManagementInterface */ private $shippingInformationManagement; /** - * SetShippingMethodsOnCart constructor. - * @param ArrayManager $arrayManager - * @param GetCartForUser $getCartForUser * @param ShippingInformationManagementInterface $shippingInformationManagement * @param QuoteAddressFactory $quoteAddressFactory * @param QuoteAddressResource $quoteAddressResource * @param ShippingInformationFactory $shippingInformationFactory */ public function __construct( - ArrayManager $arrayManager, - GetCartForUser $getCartForUser, ShippingInformationManagementInterface $shippingInformationManagement, QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { - $this->arrayManager = $arrayManager; - $this->getCartForUser = $getCartForUser; $this->shippingInformationManagement = $shippingInformationManagement; $this->quoteAddressResource = $quoteAddressResource; $this->quoteAddressFactory = $quoteAddressFactory; @@ -86,37 +65,19 @@ public function __construct( } /** - * @inheritdoc + * Sets shipping method for a specified shopping cart address + * + * @param Quote $cart + * @param int $cartAddressId + * @param string $carrierCode + * @param string $methodCode + * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + public function execute(Quote $cart, int $cartAddressId, string $carrierCode, string $methodCode): void { - $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); - $maskedCartId = $this->arrayManager->get('input/cart_id', $args); - - if (!$maskedCartId) { - throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); - } - if (!$shippingMethods) { - throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); - } - - $shippingMethod = reset($shippingMethods); - - if (!$shippingMethod['cart_address_id']) { - throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); - } - if (!$shippingMethod['shipping_carrier_code']) { - throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); - } - if (!$shippingMethod['shipping_method_code']) { - throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); - } - - $userId = $context->getUserId(); - $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); - $quoteAddress = $this->quoteAddressFactory->create(); - $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); + $this->quoteAddressResource->load($quoteAddress, $cartAddressId); /** @var ShippingInformation $shippingInformation */ $shippingInformation = $this->shippingInformationFactory->create(); @@ -124,8 +85,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /* If the address is not a shipping address (but billing) the system will find the proper shipping address for the selected cart and set the information there (actual for single shipping address) */ $shippingInformation->setShippingAddress($quoteAddress); - $shippingInformation->setShippingCarrierCode($shippingMethod['shipping_carrier_code']); - $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); + $shippingInformation->setShippingCarrierCode($carrierCode); + $shippingInformation->setShippingMethodCode($methodCode); try { $this->shippingInformationManagement->saveAddressInformation($cart->getId(), $shippingInformation); @@ -136,12 +97,5 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } catch (InputException $exception) { throw new GraphQlInputException(__($exception->getMessage())); } - - return [ - 'cart' => [ - 'cart_id' => $maskedCartId, - 'model' => $cart - ] - ]; } -} +} \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php new file mode 100644 index 0000000000000..920829f5d67b1 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\QuoteGraphQl\Model\Cart\SetShippingMethodOnCart; + +/** + * Class SetShippingMethodsOnCart + * + * Mutation resolver for setting shipping methods for shopping cart + */ +class SetShippingMethodsOnCart implements ResolverInterface +{ + /** + * @var SetShippingMethodOnCart + */ + private $setShippingMethodOnCart; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * @var GetCartForUser + */ + private $getCartForUser; + + /** + * @param ArrayManager $arrayManager + * @param GetCartForUser $getCartForUser + * @param SetShippingMethodOnCart $setShippingMethodOnCart + */ + public function __construct( + ArrayManager $arrayManager, + GetCartForUser $getCartForUser, + SetShippingMethodOnCart $setShippingMethodOnCart + ) { + $this->arrayManager = $arrayManager; + $this->getCartForUser = $getCartForUser; + $this->setShippingMethodOnCart = $setShippingMethodOnCart; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + if (!$shippingMethods) { + throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); + } + + $shippingMethod = reset($shippingMethods); // This point can be extended for multishipping + + if (!$shippingMethod['cart_address_id']) { + throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); + } + if (!$shippingMethod['shipping_carrier_code']) { + throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); + } + if (!$shippingMethod['shipping_method_code']) { + throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); + } + + $userId = $context->getUserId(); + $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); + + $this->setShippingMethodOnCart->execute( + $cart, + $shippingMethod['cart_address_id'], + $shippingMethod['shipping_carrier_code'], + $shippingMethod['shipping_method_code'] + ); + + return [ + 'cart' => [ + 'cart_id' => $maskedCartId, + 'model' => $cart + ] + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index cbc56bfaea66f..ce982952f1aee 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -11,7 +11,7 @@ type Mutation { removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput - setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart") addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart") } From c8dbdf4a1b94c5d3f6b9f3211f270c0168d74396 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Fri, 2 Nov 2018 12:37:27 +0200 Subject: [PATCH 0979/1415] graphQl: fixed multi shipping model --- .../MultiShipping/ShippingItemsMapper.php | 2 +- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/QuoteGraphQl/etc/graphql/di.xml diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php index c9cefc421a544..ad5207814db7c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php @@ -14,7 +14,7 @@ class ShippingItemsMapper { /** - * Converts shipping address input array into shipping items information array + * Converts shipping address input array into shipping items information array * Array structure: * array( * $cartItemId => array( diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..43941c9740048 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> + <arguments> + <argument name="specifications" xsi:type="array"> + <item name="enabled" xsi:type="string">Magento\Multishipping\Model\Payment\Method\Specification\Enabled</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Multishipping\Block\Checkout\Billing"> + <arguments> + <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> + </arguments> + </type> + <type name="Magento\Multishipping\Model\Checkout\Type\Multishipping"> + <arguments> + <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> + </arguments> + </type> +</config> From 166259009ae6e741ca90c98472c763d488a6839d Mon Sep 17 00:00:00 2001 From: Bernard van der Esch <b.vanderesch@gmail.com> Date: Fri, 2 Nov 2018 11:43:29 +0100 Subject: [PATCH 0980/1415] import class to the use statement --- lib/internal/Magento/Framework/View/Layout/Generator/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php index c69421cda339a..f0e62fce2a7ce 100755 --- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php @@ -273,7 +273,7 @@ protected function getBlockInstance($block, array $arguments = []) } } if (!$block instanceof \Magento\Framework\View\Element\AbstractBlock) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( new \Magento\Framework\Phrase( 'Invalid block type: %1', [is_object($block) ? get_class($block) : (string) $block] From ed26e551c5f54ead331d0187316269eddc3dff74 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Nov 2018 13:05:17 +0200 Subject: [PATCH 0981/1415] #18562 - Internet Explorer 11: Edit customer in backend leads sometimes to a "loading circle" and error object does not support method "includes" --- app/code/Magento/Ui/view/base/web/js/form/element/country.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/country.js b/app/code/Magento/Ui/view/base/web/js/form/element/country.js index f64a80bf535ec..c75301018e190 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/country.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/country.js @@ -49,7 +49,7 @@ define([ if (!this.value()) { defaultCountry = _.filter(result, function (item) { - return item['is_default'] && item['is_default'].includes(value); + return item['is_default'] && _.contains(item['is_default'], value); }); if (defaultCountry.length) { From 5224958b90b3013b5c213e1b76e2522a3ca2e45e Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin <a.gorbulin@ism-ukraine.com> Date: Fri, 2 Nov 2018 13:20:59 +0200 Subject: [PATCH 0982/1415] Add-validation-new-from-date-less-than-new-to-date-in-SCV-product-import add validation for fields new_from_date and new_to_date to make sure field new_from_date < new_to_date to prevent future errors during saving updated product --- .../Model/Import/Product.php | 29 +++++++++++++++++-- .../Import/Product/RowValidatorInterface.php | 2 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 6f8b2248d8d89..0595617fcf382 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -132,6 +132,16 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ const COL_NAME = 'name'; + /** + * Column new_from_date. + */ + const COL_NEW_FROM_DATE = 'new_from_date'; + + /** + * Column new_to_date. + */ + const COL_NEW_TO_DATE = 'new_to_date'; + /** * Column product website. */ @@ -298,6 +308,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid', ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => "Value for multiselect attribute %s contains duplicated values", + ValidatorInterface::ERROR_NEW_TO_DATE => 'Make sure new_to_date is later than or the same as new_from_date', ]; //@codingStandardsIgnoreEnd @@ -319,8 +330,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity Product::COL_TYPE => 'product_type', Product::COL_PRODUCT_WEBSITES => 'product_websites', 'status' => 'product_online', - 'news_from_date' => 'new_from_date', - 'news_to_date' => 'new_to_date', + 'news_from_date' => self::COL_NEW_FROM_DATE, + 'news_to_date' => self::COL_NEW_TO_DATE, 'options_container' => 'display_product_options_in', 'minimal_price' => 'map_price', 'msrp' => 'msrp_price', @@ -2546,6 +2557,20 @@ public function validateRow(array $rowData, $rowNum) } } } + + if (!empty($rowData[self::COL_NEW_FROM_DATE]) && !empty($rowData[self::COL_NEW_TO_DATE]) + ) { + $newFromTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_FROM_DATE], false)); + $newToTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_TO_DATE], false)); + if ($newFromTimestamp > $newToTimestamp) { + $this->addRowError( + ValidatorInterface::ERROR_NEW_TO_DATE, + $rowNum, + $rowData[self::COL_NEW_TO_DATE] + ); + } + } + return !$this->getErrorAggregator()->isRowInvalid($rowNum); } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php index f41596ad185a6..cbdc5f5beaaf9 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php @@ -87,6 +87,8 @@ interface RowValidatorInterface extends \Magento\Framework\Validator\ValidatorIn const ERROR_DUPLICATE_MULTISELECT_VALUES = 'duplicatedMultiselectValues'; + const ERROR_NEW_TO_DATE = 'invalidNewToDateValue'; + /** * Value that means all entities (e.g. websites, groups etc.) */ From 388fb45eb6ff24b3fe9fc1452bf75db5507ae87c Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 13:42:44 +0200 Subject: [PATCH 0983/1415] magento/magento2#17833: Child theme does not inherit translations from parent theme --- lib/internal/Magento/Framework/Translate.php | 76 ++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ffa8e25031064..3d5213cb2a40e 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework; @@ -339,16 +340,21 @@ protected function _addData($data) } /** - * Load current theme translation + * Load current theme translation according to fallback * * @return $this */ protected function _loadThemeTranslation() { - $file = $this->_getThemeTranslationFile($this->getLocale()); - if ($file) { - $this->_addData($this->_getFileData($file)); + $themeFiles = $this->getThemeTranslationFilesList($this->getLocale()); + + /** @var string $file */ + foreach ($themeFiles as $file) { + if ($file) { + $this->_addData($this->_getFileData($file)); + } } + return $this; } @@ -389,11 +395,73 @@ protected function _getModuleTranslationFile($moduleName, $locale) return $file; } + /** + * Get theme translation locale file name + * + * @param string $locale + * @param array $config + * @return string + */ + private function getThemeTranslationFileName(string $locale, array $config): string + { + return $this->_viewFileSystem->getLocaleFileName( + 'i18n' . '/' . $locale . '.csv', + $config + ); + } + + /** + * Get parent themes for the current theme in fallback order + * + * @return array + */ + private function getParentThemesList(): array + { + $themes = []; + + $parentTheme = $this->_viewDesign->getDesignTheme()->getParentTheme(); + while($parentTheme) { + $themes[] = $parentTheme; + $parentTheme = $parentTheme->getParentTheme(); + } + $themes = array_reverse($themes); + + return $themes; + } + + /** + * Retrieve translation files for themes according to fallback + * + * @param string $locale + * + * @return array + */ + private function getThemeTranslationFilesList($locale): array + { + $translationFiles = []; + + /** @var \Magento\Framework\View\Design\ThemeInterface $theme */ + foreach ($this->getParentThemesList() as $theme) { + $config = $this->_config; + $config['theme'] = $theme->getCode(); + $translationFiles[] = $this->getThemeTranslationFileName($locale, $config); + } + + $translationFiles[] = $this->getThemeTranslationFileName($locale, $this->_config); + + return $translationFiles; + } + + /** * Retrieve translation file for theme * * @param string $locale * @return string + * + * @deprecated + * + * @see \Magento\Framework\Translate::getThemeTranslationFilesList */ protected function _getThemeTranslationFile($locale) { From 6a35e24869be3384e9f7d86bf6faed132d5b2bf6 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 14:16:30 +0200 Subject: [PATCH 0984/1415] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20fix=20code=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/internal/Magento/Framework/Translate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 3d5213cb2a40e..7994c22c14806 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -420,7 +420,7 @@ private function getParentThemesList(): array $themes = []; $parentTheme = $this->_viewDesign->getDesignTheme()->getParentTheme(); - while($parentTheme) { + while ($parentTheme) { $themes[] = $parentTheme; $parentTheme = $parentTheme->getParentTheme(); } From 51e240203aad14b5a0dcce42caf9041c92fc138d Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 2 Nov 2018 15:29:33 +0300 Subject: [PATCH 0985/1415] MAGETWO-91684: Issue with Newsletter subscriptions - Ensure that customer id is presented. --- .../Model/ResourceModel/Subscriber.php | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index 5bd89c2798ce3..f9e9d57bf4b40 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -132,28 +132,34 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface { $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); - $select = $this->connection - ->select() - ->from($this->getMainTable()) - ->where('customer_id = ?', $customer->getId()) - ->where('store_id IN (?)', $storeIds); - - $result = $this->connection->fetchRow($select); - - if ($result) { - return $result; + if ($customer->getId()) { + $select = $this->connection + ->select() + ->from($this->getMainTable()) + ->where('customer_id = ?', $customer->getId()) + ->where('store_id IN (?)', $storeIds) + ->limit(1); + + $result = $this->connection->fetchRow($select); + + if ($result) { + return $result; + } } - $select = $this->connection - ->select() - ->from($this->getMainTable()) - ->where('subscriber_email = ?', $customer->getEmail()) - ->where('store_id IN (?)', $storeIds); + if ($customer->getEmail()) { + $select = $this->connection + ->select() + ->from($this->getMainTable()) + ->where('subscriber_email = ?', $customer->getEmail()) + ->where('store_id IN (?)', $storeIds) + ->limit(1); - $result = $this->connection->fetchRow($select); + $result = $this->connection->fetchRow($select); - if ($result) { - return $result; + if ($result) { + return $result; + } } return []; From 16731a0812d9a74fb55d4acc8e68af3716e1c728 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Fri, 2 Nov 2018 15:00:55 +0200 Subject: [PATCH 0986/1415] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepositoryTest.php | 161 +++++++++++++----- 1 file changed, 114 insertions(+), 47 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php index 1af093bea06cc..15afc87405ffd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php @@ -8,8 +8,24 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Customer\Api\Data\RegionInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\CustomerRegistry; use Magento\Framework\Api\SortOrder; +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Customer\Model\Customer; /** * Checks Customer insert, update, search with repository @@ -24,60 +40,65 @@ class CustomerRepositoryTest extends \PHPUnit\Framework\TestCase /** @var CustomerRepositoryInterface */ private $customerRepository; - /** @var \Magento\Framework\ObjectManagerInterface */ + /** @var ObjectManagerInterface */ private $objectManager; - /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory */ + /** @var CustomerInterfaceFactory */ private $customerFactory; - /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */ + /** @var AddressInterfaceFactory */ private $addressFactory; - /** @var \Magento\Customer\Api\Data\RegionInterfaceFactory */ + /** @var RegionInterfaceFactory */ private $regionFactory; - /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter */ + /** @var ExtensibleDataObjectConverter */ private $converter; - /** @var \Magento\Framework\Api\DataObjectHelper */ + /** @var DataObjectHelper */ protected $dataObjectHelper; - /** @var \Magento\Framework\Encryption\EncryptorInterface */ + /** @var EncryptorInterface */ protected $encryptor; - /** @var \Magento\Customer\Model\CustomerRegistry */ + /** @var CustomerRegistry */ protected $customerRegistry; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->customerRepository = - $this->objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $this->customerFactory = - $this->objectManager->create(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); - $this->addressFactory = $this->objectManager->create(\Magento\Customer\Api\Data\AddressInterfaceFactory::class); - $this->regionFactory = $this->objectManager->create(\Magento\Customer\Api\Data\RegionInterfaceFactory::class); - $this->accountManagement = - $this->objectManager->create(\Magento\Customer\Api\AccountManagementInterface::class); - $this->converter = $this->objectManager->create(\Magento\Framework\Api\ExtensibleDataObjectConverter::class); - $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class); - $this->encryptor = $this->objectManager->create(\Magento\Framework\Encryption\EncryptorInterface::class); - $this->customerRegistry = $this->objectManager->create(\Magento\Customer\Model\CustomerRegistry::class); - - /** @var \Magento\Framework\Config\CacheInterface $cache */ - $cache = $this->objectManager->create(\Magento\Framework\Config\CacheInterface::class); + $this->customerRepository = $this->objectManager->create(CustomerRepositoryInterface::class); + $this->customerFactory = $this->objectManager->create(CustomerInterfaceFactory::class); + $this->addressFactory = $this->objectManager->create(AddressInterfaceFactory::class); + $this->regionFactory = $this->objectManager->create(RegionInterfaceFactory::class); + $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); + $this->converter = $this->objectManager->create(ExtensibleDataObjectConverter::class); + $this->dataObjectHelper = $this->objectManager->create(DataObjectHelper::class); + $this->encryptor = $this->objectManager->create(EncryptorInterface::class); + $this->customerRegistry = $this->objectManager->create(CustomerRegistry::class); + + /** @var CacheInterface $cache */ + $cache = $this->objectManager->create(CacheInterface::class); $cache->remove('extension_attributes_config'); } + /** + * @inheritdoc + */ protected function tearDown() { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */ - $customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class); + $customerRegistry = $objectManager->get(CustomerRegistry::class); $customerRegistry->remove(1); } /** + * Check if first name update was successful + * * @magentoDbIsolation enabled */ public function testCreateCustomerNewThenUpdateFirstName() @@ -99,7 +120,7 @@ public function testCreateCustomerNewThenUpdateFirstName() $newCustomerFirstname = 'New First Name'; $updatedCustomer = $this->customerFactory->create(); $this->dataObjectHelper->mergeDataObjects( - \Magento\Customer\Api\Data\CustomerInterface::class, + CustomerInterface::class, $updatedCustomer, $customer ); @@ -112,6 +133,8 @@ public function testCreateCustomerNewThenUpdateFirstName() } /** + * Test create new customer + * * @magentoDbIsolation enabled */ public function testCreateNewCustomer() @@ -139,6 +162,8 @@ public function testCreateNewCustomer() } /** + * Test update customer + * * @dataProvider updateCustomerDataProvider * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php @@ -168,7 +193,7 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $this->dataObjectHelper->populateWithArray( $customerDetails, $customerData, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $this->customerRepository->save($customerDetails, $newPasswordHash); $customerAfter = $this->customerRepository->getById($existingCustomerId); @@ -187,12 +212,12 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $attributesBefore = $this->converter->toFlatArray( $customerBefore, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $attributesAfter = $this->converter->toFlatArray( $customerAfter, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); // ignore 'updated_at' unset($attributesBefore['updated_at']); @@ -215,6 +240,8 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) } /** + * Test update customer address + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -233,14 +260,14 @@ public function testUpdateCustomerAddress() $this->dataObjectHelper->populateWithArray( $newAddressDataObject, $newAddress, - \Magento\Customer\Api\Data\AddressInterface::class + AddressInterface::class ); $newAddressDataObject->setRegion($addresses[0]->getRegion()); $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customerId) ->setAddresses([$newAddressDataObject, $addresses[1]]); @@ -256,6 +283,8 @@ public function testUpdateCustomerAddress() } /** + * Test preserve all addresses after customer update + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -265,22 +294,37 @@ public function testUpdateCustomerPreserveAllAddresses() $customerId = 1; $customer = $this->customerRepository->getById($customerId); $customerDetails = $customer->__toArray(); + $defaultBilling = $customerDetails['default_billing']; + $defaultShipping = $customerDetails['default_shipping']; $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses(null); $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); + $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are still present $this->assertEquals(2, count($newCustomerDetails->getAddresses())); + $this->assertEquals( + $defaultBilling, + $newCustomerArray['default_billing'], + "Default billing invalid value" + ); + $this->assertEquals( + $defaultShipping, + $newCustomerArray['default_shipping'], + "Default shipping invalid value" + ); } /** + * Test update delete all addresses with empty arrays + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -294,18 +338,31 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses([]); $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); + $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are removed $this->assertEquals(0, count($newCustomerDetails->getAddresses())); + $this->assertEquals( + $newCustomerArray['default_billing'], + null, + "Default billing invalid value" + ); + $this->assertEquals( + $newCustomerArray['default_shipping'], + null, + "Default shipping invalid value" + ); } /** + * Test search customers + * * @param \Magento\Framework\Api\Filter[] $filters * @param \Magento\Framework\Api\Filter[] $filterGroup * @param array $expectedResult array of expected results indexed by ID @@ -317,9 +374,8 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() */ public function testSearchCustomers($filters, $filterGroup, $expectedResult) { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ - $searchBuilder = Bootstrap::getObjectManager() - ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + /** @var SearchCriteriaBuilder $searchBuilder */ + $searchBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); foreach ($filters as $filter) { $searchBuilder->addFilters([$filter]); } @@ -346,19 +402,19 @@ public function testSearchCustomers($filters, $filterGroup, $expectedResult) */ public function testSearchCustomersOrder() { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ + /** @var SearchCriteriaBuilder $searchBuilder */ $objectManager = Bootstrap::getObjectManager(); - $searchBuilder = $objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + $searchBuilder = $objectManager->create(SearchCriteriaBuilder::class); // Filter for 'firstname' like 'First' - $filterBuilder = $objectManager->create(\Magento\Framework\Api\FilterBuilder::class); + $filterBuilder = $objectManager->create(FilterBuilder::class); $firstnameFilter = $filterBuilder->setField('firstname') ->setConditionType('like') ->setValue('First%') ->create(); $searchBuilder->addFilters([$firstnameFilter]); // Search ascending order - $sortOrderBuilder = $objectManager->create(\Magento\Framework\Api\SortOrderBuilder::class); + $sortOrderBuilder = $objectManager->create(SortOrderBuilder::class); $sortOrder = $sortOrderBuilder ->setField('lastname') ->setDirection(SortOrder::SORT_ASC) @@ -383,6 +439,8 @@ public function testSearchCustomersOrder() } /** + * Test delete + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -393,12 +451,14 @@ public function testDelete() $customer = $this->customerRepository->get($fixtureCustomerEmail); $this->customerRepository->delete($customer); /** Ensure that customer was deleted */ - $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class); + $this->expectException(NoSuchEntityException::class); $this->expectExceptionMessage('No such entity with email = customer@example.com, websiteId = 1'); $this->customerRepository->get($fixtureCustomerEmail); } /** + * Test delete by id + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -409,7 +469,7 @@ public function testDeleteById() $fixtureCustomerId = 1; $this->customerRepository->deleteById($fixtureCustomerId); /** Ensure that customer was deleted */ - $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class); + $this->expectException(NoSuchEntityException::class); $this->expectExceptionMessage('No such entity with email = customer@example.com, websiteId = 1'); $this->customerRepository->get($fixtureCustomerEmail); } @@ -433,9 +493,14 @@ public function updateCustomerDataProvider() ]; } + /** + * Search customer data provider + * + * @return array + */ public function searchCustomersDataProvider() { - $builder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class); + $builder = Bootstrap::getObjectManager()->create(FilterBuilder::class); return [ 'Customer with specific email' => [ [$builder->setField('email')->setValue('customer@search.example.com')->create()], @@ -485,9 +550,9 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( $defaultShipping ) { /** - * @var \Magento\Customer\Model\Customer $customer + * @var Customer $customer */ - $customer = $this->objectManager->create(\Magento\Customer\Model\Customer::class); + $customer = $this->objectManager->create(Customer::class); /** @var \Magento\Customer\Model\Customer $customer */ $customer->load($customerId); $this->assertEquals( @@ -503,6 +568,8 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( } /** + * Test update default shipping and default billing address + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDbIsolation enabled */ @@ -530,13 +597,13 @@ public function testUpdateDefaultShippingAndDefaultBillingTest() $this->assertEquals( $savedCustomer->getDefaultBilling(), $oldDefaultBilling, - 'Default billing shoud not be overridden' + 'Default billing should not be overridden' ); $this->assertEquals( $savedCustomer->getDefaultShipping(), $oldDefaultShipping, - 'Default shipping shoud not be overridden' + 'Default shipping should not be overridden' ); } } From bc8d3d5d0ead9779cb22d19201cd731719a79b0c Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 2 Nov 2018 15:01:25 +0200 Subject: [PATCH 0987/1415] magento/magento2#18256: Reset password throws error since 2.2.6. --- app/code/Magento/Customer/Model/AccountManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 9173307a7d270..8beecffd1c865 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -681,8 +681,8 @@ public function resetPassword($email, $resetToken, $newPassword) $customerSecure->setRpToken(null); $customerSecure->setRpTokenCreatedAt(null); $customerSecure->setPasswordHash($this->createPasswordHash($newPassword)); - $this->sessionManager->destroy(); $this->destroyCustomerSessions($customer->getId()); + $this->sessionManager->destroy(); $this->customerRepository->save($customer); return true; From c720d972108e6991f127f6f71e63485290dabe61 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 2 Nov 2018 15:05:08 +0200 Subject: [PATCH 0988/1415] magento/magento2:#18979 - API: Bundle Product Option Repository Delete method removes incorrect option --- app/code/Magento/Bundle/Model/OptionRepository.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index 59e658b08df28..a4d579a44174a 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -160,10 +160,9 @@ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) */ public function deleteById($sku, $optionId) { - $product = $this->getProduct($sku); - $optionCollection = $this->type->getOptionsCollection($product); - $optionCollection->setIdFilter($optionId); - $hasBeenDeleted = $this->delete($optionCollection->getFirstItem()); + /** @var \Magento\Bundle\Api\Data\OptionInterface $option */ + $option = $this->get($sku, $optionId); + $hasBeenDeleted = $this->delete($option); return $hasBeenDeleted; } From 21f52259c1f435a0fcb31ceb6f8a664fc2b7bf6c Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 15:14:28 +0200 Subject: [PATCH 0989/1415] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/internal/Magento/Framework/Translate.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 7994c22c14806..98ba6c0d718c3 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -400,14 +400,16 @@ protected function _getModuleTranslationFile($moduleName, $locale) * * @param string $locale * @param array $config - * @return string + * @return string|null */ - private function getThemeTranslationFileName(string $locale, array $config): string + private function getThemeTranslationFileName(string $locale, array $config): ?string { - return $this->_viewFileSystem->getLocaleFileName( + $fileName = $this->_viewFileSystem->getLocaleFileName( 'i18n' . '/' . $locale . '.csv', $config ); + + return $fileName ? $fileName : null; } /** From 936a22328f429b7e0dd631b6b20831ea91695cb6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 15:23:16 +0200 Subject: [PATCH 0990/1415] Added setting shipping method on cart test coverage concept --- .../Quote/SetShippingMethodOnCartTest.php | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php new file mode 100644 index 0000000000000..64c7cbf9fd42e --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Quote; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; +use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test for setting shipping methods on cart + */ +class SetShippingMethodOnCartTest extends GraphQlAbstract +{ + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * @var QuoteResource + */ + private $quoteResource; + + /** + * @var Quote + */ + private $quote; + + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedId; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->quoteResource = $objectManager->create(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $query = <<<QUERY +mutation { + setShippingMethodsOnCart(input: + { + cart_id: "$maskedQuoteId", + shipping_methods: [ + { + shipping_method_code: "flatrate" + shipping_carrier_code: "flatrate" + cart_address_id: $shippingAddressId + } + ]}) { + + cart { + cart_id, + addresses { + firstname + lastname + company + address_type + city + street + region { + code + label + } + postcode + country { + code + label + } + + selected_shipping_method { + code + label + } + } + } + } +} + +QUERY; + + $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('setShippingMethodsOnCart', $response); + self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); + self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); + + // TODO: check shipping method code and description + } + + // TODO: cover all other cases +} From 76d478fa2c70c5c6ac07c7ef781ce46aeadffd06 Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin <a.gorbulin@ism-ukraine.com> Date: Fri, 2 Nov 2018 15:27:42 +0200 Subject: [PATCH 0991/1415] 18901-Forgot-password-form-should-not-available-while-customer-is-logged-in magento/magento2#18901: Forgot password form should not available while customer is logged in --- .../Customer/Controller/Account/ForgotPassword.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php index 8b5d0612050c3..b94f1993053d4 100644 --- a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php +++ b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php @@ -41,10 +41,17 @@ public function __construct( /** * Forgot customer password page * - * @return \Magento\Framework\View\Result\Page + * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page */ public function execute() { + if ($this->session->isLoggedIn()) { + /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('*/*/'); + return $resultRedirect; + } + /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->getLayout()->getBlock('forgotPassword')->setEmailValue($this->session->getForgottenEmail()); From a30654fb794e4517cdfec07ac431824e2243dec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szyma=C5=84ski?= <bartlomiej.szymanski@bold.net.pl> Date: Fri, 2 Nov 2018 14:29:17 +0100 Subject: [PATCH 0992/1415] Replace GraphQlInputException on \LogicException --- .../Model/LayerFilterItemTypeResolverComposite.php | 4 +--- .../Model/ProductLinkTypeResolverComposite.php | 4 +--- app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php | 7 +------ 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php index 20e5590117556..e04b5d1bf67ff 100644 --- a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php @@ -43,9 +43,7 @@ public function resolveType(array $data) : string } } if (empty($resolvedType)) { - throw new GraphQlInputException( - __('Concrete type for %1 not implemented', ['ProductLinksInterface']) - ); + throw new \LogicException('Cannot resolve layered filter type'); } } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index 937e3921758dc..5f6d1a65519f8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -50,9 +50,7 @@ public function resolveType(array $data) : string } if (!$resolvedType) { - throw new GraphQlInputException( - __('Concrete type for %1 not implemented', ['ProductLinksInterface']) - ); + throw new \LogicException('Cannot resolve type'); } } } diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index cbea3a86bbddd..b1d7aae5df101 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -71,12 +71,7 @@ public function getType(string $attributeCode, string $entityType) : string try { $type = $this->typeProcessor->translateTypeName($type); } catch (\InvalidArgumentException $exception) { - throw new GraphQlInputException( - __('Type %1 has no internal representation declared.', [$type]), - null, - 0, - false - ); + throw new \LogicException('Cannot resolve EAV type'); } } else { $type = $type === 'double' ? 'float' : $type; From 12e0c534e70632deff7e177fa716b79dfbbf83ba Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 16:55:05 +0300 Subject: [PATCH 0993/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix static test --- app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index a2cbc5087cd12..c530ba4785ad9 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -146,10 +146,10 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param ProductList $productListHelper * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper + * @param array $data * @param ToolbarMemorizer|null $toolbarMemorizer * @param \Magento\Framework\App\Http\Context|null $httpContext * @param \Magento\Framework\Data\Form\FormKey|null $formKey - * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ From 144ea18392229aef98c5a21165fba106bd97840d Mon Sep 17 00:00:00 2001 From: Lars Roettig <l.roettig@techdivision.com> Date: Fri, 2 Nov 2018 15:34:08 +0100 Subject: [PATCH 0994/1415] CodeReviewChange --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 3142955ac5988..9d1a7a38ede68 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,7 +177,10 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - $group->setRootCategoryId(0); + if (!isset($groupData['root_categry_id'])) { + $groupData['root_categry_id'] = 0; + } + $group->setData($groupData); $group->getResource()->save($group); From 9498e05885b865a6c4589221ebf20491360d41a7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Fri, 2 Nov 2018 09:44:30 -0500 Subject: [PATCH 0995/1415] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest --- .../Test/Constraint/AssertCartIsEmpty.php | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php index c2839651b582f..22a6136737089 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php @@ -6,7 +6,6 @@ namespace Magento\Checkout\Test\Constraint; -use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\Constraint\AbstractConstraint; @@ -42,10 +41,12 @@ public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $brow ); $cartEmptyBlock->clickLinkToMainPage(); - \PHPUnit\Framework\Assert::assertEquals( + $this->assertUrlEqual( $_ENV['app_frontend_url'], $browser->getUrl(), - 'Wrong link to main page on empty cart page.' + true, + 'Wrong link to main page on empty cart page: expected - ' . $_ENV['app_frontend_url'] + . ', actural - ' . $browser->getUrl() ); } @@ -58,4 +59,27 @@ public function toString() { return 'Shopping Cart is empty.'; } + + /** + * Asserts that two urls are equal + * + * @param string $url1 + * @param string $url2 + * @param bool $ignoreScheme + * @param string $message + * @return void + */ + private function assertUrlEqual($expectedUrl, $actualUrl, $ignoreScheme = false, $message = '') + { + $urlArray1 = parse_url($expectedUrl); + $urlArray2 = parse_url($actualUrl); + if ($ignoreScheme) { + unset($urlArray1['scheme']); + unset($urlArray2['scheme']); + } + \PHPUnit\Framework\Assert::assertTrue( + $urlArray1 === $urlArray2, + $message + ); + } } From c333367742e668ea824c09675eb059fb246181a2 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Nov 2018 17:09:46 +0200 Subject: [PATCH 0996/1415] #13157 - Last Ordered Items block - bad js code --- .../view/frontend/templates/reorder/sidebar.phtml | 14 +++++++++----- .../frontend/web/js/view/last-ordered-items.js | 12 ++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 5ecf1ebe893bc..370e034ead64a 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -26,14 +26,18 @@ <ol id="cart-sidebar-reorder" class="product-items product-items-names" data-bind="foreach: lastOrderedItems().items"> <li class="product-item"> - <div class="field item choice no-display" data-bind="css: {'no-display': !is_saleable}"> + <div class="field item choice"> <label class="label" data-bind="attr: {'for': 'reorder-item-' + id}"> <span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span> </label> <div class="control"> <input type="checkbox" name="order_items[]" - data-bind="attr: {id: 'reorder-item-' + id, value: id}" - title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>" + data-bind="attr: { + id: 'reorder-item-' + id, + value: id, + title: is_saleable ? '<?= /* @escapeNotVerified */ __('Add to Cart') ?>' : '<?= /* @escapeNotVerified */ __('Product is not salable.') ?>' + }, + disable: !is_saleable" class="checkbox" data-validate='{"validate-one-checkbox-required-by-name": true}'/> </div> </div> @@ -46,8 +50,8 @@ </ol> <div id="cart-sidebar-reorder-advice-container"></div> <div class="actions-toolbar"> - <div class="primary no-display" - data-bind="css: {'no-display': !lastOrderedItems().isShowAddToCart}"> + <div class="primary" + data-bind="visible: lastOrderedItems.isShowAddToCart"> <button type="submit" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>" class="action tocart primary"> <span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span> </button> diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index f393cc3fcd3bc..9897666653df9 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -12,18 +12,14 @@ define([ return Component.extend({ /** @inheritdoc */ initialize: function () { - var isShowAddToCart = false, - item; + var isShowAddToCart; this._super(); this.lastOrderedItems = customerData.get('last-ordered-items'); - for (item in this.lastOrderedItems.items) { - if (item['is_saleable']) { - isShowAddToCart = true; - break; - } - } + isShowAddToCart = _.some(this.lastOrderedItems().items, { + 'is_saleable': true + }); this.lastOrderedItems.isShowAddToCart = isShowAddToCart; } From 0a6c0b5a792dbba00295bea9b9b902c7b9598205 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Fri, 2 Nov 2018 17:15:09 +0200 Subject: [PATCH 0997/1415] graphQl: removed multishipping implementation, fixed namespaces --- .../SetShippingAddressOnCart.php} | 19 ++- .../Resolver/SetShippingAddressesOnCart.php | 101 +++++++++++++ .../MultiShipping.php | 76 ---------- .../MultiShipping/ShippingItemsMapper.php | 43 ------ .../SetShippingAddressesOnCart.php | 133 ------------------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 3 +- 6 files changed, 117 insertions(+), 258 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php => Cart/SetShippingAddressOnCart.php} (85%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php similarity index 85% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index feeb333683f76..43e58bb807672 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -16,7 +16,12 @@ use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; -class SingleShipping +/** + * Class SetShippingAddressOnCart + * + * Set shipping address for a specified shopping cart + */ +class SetShippingAddressOnCart { /** * @var ShippingAddressManagementInterface @@ -51,11 +56,17 @@ public function __construct( /** * @param ContextInterface $context * @param int $cartId - * @param array $shippingAddress + * @param array $shippingAddresses * @return void */ - public function setAddress(ContextInterface $context, int $cartId, array $shippingAddress): void + public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void { + if (count($shippingAddresses) > 1) { + throw new GraphQlInputException( + __('Multiple address does not allowed here!') + ); + } + $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; $addressInput = $shippingAddress['address'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..fcb4255a75eb7 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart; + +/** + * Class SetShippingAddressesOnCart + * + * Mutation resolver for setting shipping addresses for shopping cart + */ +class SetShippingAddressesOnCart implements ResolverInterface +{ + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @var SetShippingAddressOnCart + */ + private $setShippingAddressOnCart; + + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var GetCartForUser + */ + private $getCartForUser; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param SetShippingAddressOnCart $setShippingAddressOnCart + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param GetCartForUser $getCartForUser + * @param ArrayManager $arrayManager + */ + public function __construct( + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + SetShippingAddressOnCart $setShippingAddressOnCart, + ShippingAddressManagementInterface $shippingAddressManagement, + GetCartForUser $getCartForUser, + ArrayManager $arrayManager + ) { + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->setShippingAddressOnCart = $setShippingAddressOnCart; + $this->shippingAddressManagement = $shippingAddressManagement; + $this->getCartForUser = $getCartForUser; + $this->arrayManager = $arrayManager; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingAddresses = $this->arrayManager->get('input/shipping_addresses', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + if (!$shippingAddresses) { + throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); + } + + $maskedCartId = $args['input']['cart_id']; + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); + $cartId = (int)$cart->getEntityId(); + + $this->setShippingAddressOnCart->setAddresses($context, $cartId, $shippingAddresses); + + return [ + 'cart' => [ + 'cart_id' => $maskedCartId, + 'model' => $cart + ] + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php deleted file mode 100644 index 318fd9361af5a..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; - -use Magento\Authorization\Model\UserContextInterface; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Multishipping\Model\Checkout\Type\Multishipping as MultishippingModel; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping\ShippingItemsMapper; - -class MultiShipping -{ - /** - * @var MultishippingModel - */ - private $multishippingModel; - - /** - * @var ShippingItemsMapper - */ - private $shippingItemsInformationMapper; - - /** - * @param MultishippingModel $multishippingModel - * @param ShippingItemsMapper $shippingItemsInformationMapper - */ - public function __construct( - MultishippingModel $multishippingModel, - ShippingItemsMapper $shippingItemsInformationMapper - ) { - $this->multishippingModel = $multishippingModel; - $this->shippingItemsInformationMapper = $shippingItemsInformationMapper; - } - - /** - * @param ContextInterface $context - * @param int $cartId - * @param array $shippingAddresses - */ - public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void - { - if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { - throw new GraphQlAuthorizationException( - __( - 'Multishipping allowed only for authorized customers' - ) - ); - } - - $shippingItemsInformation = []; - foreach ($shippingAddresses as $shippingAddress) { - $customerAddressId = $shippingAddress['customer_address_id'] ?? null; - $cartItems = $shippingAddress['cart_items'] ?? null; - if (!$customerAddressId) { - throw new GraphQlInputException(__('Parameter "customer_address_id" is required for multishipping')); - } - if (!$cartItems) { - throw new GraphQlInputException(__('Parameter "cart_items" is required for multishipping')); - } - - $shippingItemsInformation = array_merge( - $shippingItemsInformation, - $this->shippingItemsInformationMapper->map($shippingAddress) - ); - } - - //TODO: multishipping model works with session. Do we need to avoid it? - $this->multishippingModel->setShippingItemsInformation($shippingItemsInformation); - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php deleted file mode 100644 index ad5207814db7c..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; - -/** - * Shipping address to shipping items mapper - */ -class ShippingItemsMapper -{ - - /** - * Converts shipping address input array into shipping items information array - * Array structure: - * array( - * $cartItemId => array( - * 'qty' => $qty, - * 'address' => $customerAddressId - * ) - * ) - * - * @param array $shippingAddress - * @return array - */ - public function map(array $shippingAddress): array - { - $shippingItemsInformation = []; - foreach ($shippingAddress['cart_items'] as $cartItem) { - $shippingItemsInformation[] = [ - $cartItem['cart_item_id'] => [ - 'qty' => $cartItem['quantity'], - 'address' => $shippingAddress['customer_address_id'] - ] - ]; - } - - return $shippingItemsInformation; - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php deleted file mode 100644 index 7ffa6c4950b3d..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\ShippingAddressManagementInterface; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\SingleShipping; - -/** - * @inheritdoc - */ -class SetShippingAddressesOnCart implements ResolverInterface -{ - /** - * @var MaskedQuoteIdToQuoteIdInterface - */ - private $maskedQuoteIdToQuoteId; - - /** - * @var MultiShipping - */ - private $multiShipping; - - /** - * @var SingleShipping - */ - private $singleShipping; - - /** - * @var ShippingAddressManagementInterface - */ - private $shippingAddressManagement; - - /** - * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param MultiShipping $multiShipping - * @param SingleShipping $singleShipping - * @param ShippingAddressManagementInterface $shippingAddressManagement - */ - public function __construct( - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - MultiShipping $multiShipping, - SingleShipping $singleShipping, - ShippingAddressManagementInterface $shippingAddressManagement - ) { - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->multiShipping = $multiShipping; - $this->singleShipping = $singleShipping; - $this->shippingAddressManagement = $shippingAddressManagement; - } - - /** - * @inheritdoc - */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) - { - if (!isset($args['input']['cart_id'])) { - throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); - } - if (!isset($args['input']['shipping_addresses'])) { - throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); - } - - $shippingAddressesInput = $args['input']['shipping_addresses']; - $maskedCartId = $args['input']['cart_id']; - $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - - if (count($shippingAddressesInput) === 1) { - $this->singleShipping->setAddress($context, $cartId, current($shippingAddressesInput)); - } else { - $this->multiShipping->setAddresses($context, $cartId, $shippingAddressesInput); - } - - //TODO: implement Cart object in the separate resolver - $shippingAddress = $this->shippingAddressManagement->get($cartId); - return [ - 'cart' => [ - 'applied_coupon' => [ - 'code' => '' - ], - 'addresses' => [[ - 'firstname' => $shippingAddress->getFirstname(), - 'lastname' => $shippingAddress->getLastname(), - 'company' => $shippingAddress->getCompany(), - 'street' => $shippingAddress->getStreet(), - 'city' => $shippingAddress->getCity(), - 'region' => [ - 'code' => $shippingAddress->getRegionCode(), - 'label' => $shippingAddress->getRegion() - ], - 'country' => [ - 'code' => $shippingAddress->getCountryId(), - 'label' => '' - ], - 'postcode' => $shippingAddress->getPostcode(), - 'telephone' => $shippingAddress->getTelephone(), - 'address_type' => 'SHIPPING', - 'selected_shipping_method' => [ - 'code' => 'test', - 'label' => 'test', - 'free_shipping' => 'test', - 'error_message' => 'test' - ], - 'available_shipping_methods' => [[ - 'code' => 'test', - 'label' => 'test', - 'free_shipping' => 'test', - 'error_message' => 'test' - ]], - 'items_weight' => [0], - 'customer_notes' => $shippingAddress->getLastname(), - 'cart_items' => [[ - 'cart_item_id' => '', - 'quantity' => 0 - ]], - 'applied_coupon' => [ - 'code' => '' - ] - ]] - ] - ]; - } -} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 7312c15e06580..017b1f8119829 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -9,11 +9,10 @@ type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddress\\SetShippingAddressesOnCart") + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart") addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart") From e18df69004ef25f53ed927e953cc5fce0191bf84 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 17:26:27 +0200 Subject: [PATCH 0998/1415] magento/magento2#14007: "Use in Layered Navigation: Filterable (no results)" not working for `Price` attribute. - adjust comment for "Use in Layered Navigation: Filterable (no results)" property to make it more understandable --- .../Tab/Front/ProductAttributeFormBuildFrontTabObserver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php index 1bb601e3a4ebd..ce618f97883b0 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -60,7 +60,11 @@ public function execute(\Magento\Framework\Event\Observer $observer) 'name' => 'is_filterable', 'label' => __("Use in Layered Navigation"), 'title' => __('Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price'), - 'note' => __('Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price.'), + 'note' => __( + 'Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price. + <br>Price is not compatible with <b>\'Filterable (no results)\'</b> option - + it will make no affect on Price filter.' + ), 'values' => [ ['value' => '0', 'label' => __('No')], ['value' => '1', 'label' => __('Filterable (with results)')], From e19d70e3fd43184eeeb009129bf0a564fae002ea Mon Sep 17 00:00:00 2001 From: "al.kravchuk" <al.kravchuk@ism-ukraine.com> Date: Fri, 2 Nov 2018 16:42:45 +0200 Subject: [PATCH 0999/1415] magento/magento2#18323: Order confirmation email for guest checkout does not include download links. - move save downloadable items from 'save_commit_after' to 'save_after' event. --- app/code/Magento/Downloadable/etc/events.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/etc/events.xml b/app/code/Magento/Downloadable/etc/events.xml index e4f03ff238d4a..5a985fc33802e 100644 --- a/app/code/Magento/Downloadable/etc/events.xml +++ b/app/code/Magento/Downloadable/etc/events.xml @@ -6,10 +6,10 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> - <event name="sales_order_item_save_commit_after"> + <event name="sales_order_item_save_after"> <observer name="downloadable_observer" instance="Magento\Downloadable\Observer\SaveDownloadableOrderItemObserver" /> </event> - <event name="sales_order_save_commit_after"> + <event name="sales_order_save_after"> <observer name="downloadable_observer" instance="Magento\Downloadable\Observer\SetLinkStatusObserver" /> </event> <event name="sales_model_service_quote_submit_success"> From c8941f1d13a82e0c3d1c65dbf262a5e295933f3f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 2 Nov 2018 18:47:41 +0300 Subject: [PATCH 1000/1415] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix statics. --- app/code/Magento/Catalog/Controller/Category/View.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php index 43f25c58a70dd..2088bb5ea77cd 100644 --- a/app/code/Magento/Catalog/Controller/Category/View.php +++ b/app/code/Magento/Catalog/Controller/Category/View.php @@ -208,7 +208,7 @@ public function execute() if ($layoutUpdates && is_array($layoutUpdates)) { foreach ($layoutUpdates as $layoutUpdate) { $page->addUpdate($layoutUpdate); - $page->addPageLayoutHandles(['layout_update' => md5($layoutUpdate)], null, false); + $page->addPageLayoutHandles(['layout_update' => sha1($layoutUpdate)], null, false); } } From 70743fa4f5e5a6c6ba416d33cfb9d36faaaa47c2 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Nov 2018 18:14:21 +0200 Subject: [PATCH 1001/1415] #10048 - WYSIWYG unable to set default value in ui component --- app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 6507da5e1a933..29a0cc0f0c295 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -20,7 +20,6 @@ define([ return Abstract.extend({ defaults: { elementSelector: 'textarea', - value: '', $wysiwygEditorButton: '', links: { value: '${ $.provider }:${ $.dataScope }' From 4ec4c0e1f390c987b6db7efd799cb0da74df1770 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Fri, 2 Nov 2018 11:54:18 -0500 Subject: [PATCH 1002/1415] MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest --- .../Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 5c05d4a840009..0edd8f4183f30 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest" summary="OnePageCheckout within Offline Payment Methods" ticketId="MAGETWO-27485"> - <variation name="OnePageCheckoutUsingSingInLink" summary="Login during checkout using 'Sign In' link" ticketId="MAGETWO-42547"> + <variation name="OnePageCheckoutUsingSignInLink" summary="Login during checkout using 'Sign In' link" ticketId="MAGETWO-42547"> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_UK_US_addresses</data> @@ -49,10 +49,6 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> - <!-- MAGETWO-94169 --> - <data name="tag" xsi:type="string">stable:no</data> - <data name="issue" xsi:type="string">MAGETWO-94169: [MTF] - OnePageCheckoutUsingNonDefaultAddress_0 fails on 2.3-develop</data> - <!-- MAGETWO-94169 --> </variation> <variation name="OnePageCheckoutUsingNewAddress" summary="Checkout as Customer using New address" ticketId="MAGETWO-42601"> <data name="tag" xsi:type="string">severity:S1</data> From 90cf2e0da44ba17b8d21307e062be80391d402e5 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Fri, 2 Nov 2018 17:09:40 +0000 Subject: [PATCH 1003/1415] Removed unnecessary empty line --- lib/internal/Magento/Framework/Translate.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 98ba6c0d718c3..ff1bf99162a8a 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -454,7 +454,6 @@ private function getThemeTranslationFilesList($locale): array return $translationFiles; } - /** * Retrieve translation file for theme * From d1e749aa37878c3c3be3a15f216745978d95a804 Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoudhgz@gmail.com> Date: Fri, 2 Nov 2018 22:34:49 +0100 Subject: [PATCH 1004/1415] Add/update newsletter messages in translation file --- app/code/Magento/Newsletter/i18n/en_US.csv | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/i18n/en_US.csv b/app/code/Magento/Newsletter/i18n/en_US.csv index c49fdc80da810..388b583f990b1 100644 --- a/app/code/Magento/Newsletter/i18n/en_US.csv +++ b/app/code/Magento/Newsletter/i18n/en_US.csv @@ -67,8 +67,8 @@ Subscribers,Subscribers "Something went wrong while saving this template.","Something went wrong while saving this template." "Newsletter Subscription","Newsletter Subscription" "Something went wrong while saving your subscription.","Something went wrong while saving your subscription." -"We saved the subscription.","We saved the subscription." -"We removed the subscription.","We removed the subscription." +"We have saved your subscription.","We have saved your subscription." +"We have removed your newsletter subscription.","We have removed your newsletter subscription." "Your subscription has been confirmed.","Your subscription has been confirmed." "This is an invalid subscription confirmation code.","This is an invalid subscription confirmation code." "This is an invalid subscription ID.","This is an invalid subscription ID." @@ -76,7 +76,7 @@ Subscribers,Subscribers "Sorry, but the administrator denied subscription for guests. Please <a href=""%1"">register</a>.","Sorry, but the administrator denied subscription for guests. Please <a href=""%1"">register</a>." "Please enter a valid email address.","Please enter a valid email address." "This email address is already subscribed.","This email address is already subscribed." -"The confirmation request has been sent.","The confirmation request has been sent." +"A confirmation request has been sent.","A confirmation request has been sent." "Thank you for your subscription.","Thank you for your subscription." "There was a problem with the subscription: %1","There was a problem with the subscription: %1" "Something went wrong with the subscription.","Something went wrong with the subscription." @@ -151,3 +151,4 @@ Unconfirmed,Unconfirmed Store,Store "Store View","Store View" "Newsletter Subscriptions","Newsletter Subscriptions" +"We have updated your subscription.","We have updated your subscription." From 4a945f2807c391d6a5aca92ffb7cd4a09f9aa2f0 Mon Sep 17 00:00:00 2001 From: Abrar pathan <abrarkhan@krishtechnolabs.com> Date: Sat, 3 Nov 2018 11:58:43 +0530 Subject: [PATCH 1005/1415] fixed-18887-notifications-counter --- .../css/source/module/header/actions-group/_notifications.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index c9c97930297cb..93fc0d3eb4948 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -103,6 +103,7 @@ padding: .3em .5em; position: absolute; top: 50%; + width: 18px; } } From 7682fa08ca31f36400ec29778f014389131e707a Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel@daniel-ruf.de> Date: Sat, 3 Nov 2018 10:56:00 +0100 Subject: [PATCH 1006/1415] chore: move count variable to loop variables --- app/code/Magento/Paypal/Model/Report/Settlement.php | 3 +-- .../Test/TestCase/Product/AddCompareProductsTest.php | 3 +-- .../Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php | 3 +-- .../Test/TestStep/FillShippingInformationStep.php | 3 +-- .../Test/Constraint/AssertProductsQtyAfterOrderCancel.php | 3 +-- .../Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php | 3 +-- .../Magento/Sniffs/Translation/ConstantUsageSniffTest.php | 3 +-- .../testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php | 5 ++--- .../Framework/App/Test/Unit/Language/DictionaryTest.php | 3 +-- lib/internal/Magento/Framework/Archive.php | 7 +++---- lib/internal/Magento/Framework/Cache/Backend/Memcached.php | 3 +-- lib/internal/Magento/Framework/Filter/Template.php | 3 +-- lib/internal/Magento/Framework/System/Ftp.php | 3 +-- .../src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php | 6 ++---- setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php | 6 ++---- 15 files changed, 20 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index b2ab1627b24d4..5dc51518f0b11 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -409,8 +409,7 @@ public function parseCsv($localCsv, $format = 'new') private function getBodyItems(array $line, array $sectionColumns, array $rowMap) { $bodyItem = []; - $lineCount = count($line); - for ($i = 1, $count = $lineCount; $i < $count; $i++) { + for ($i = 1, $count = count($line); $i < $count; $i++) { if (isset($rowMap[$sectionColumns[$i]])) { if (in_array($rowMap[$sectionColumns[$i]], $this->dateTimeColumns)) { $line[$i] = $this->formatDateTimeColumns($line[$i]); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php index da0aa49d9697b..c40387aba4603 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php @@ -76,8 +76,7 @@ public function tearDown() { $this->cmsIndex->open(); $this->cmsIndex->getLinksBlock()->openLink("Compare Products"); - $productsCount = count($this->products); - for ($i = 1; $i <= $productsCount; $i++) { + for ($i = 1, $count = count($this->products); $i <= $count; $i++) { $this->catalogProductCompare->getCompareProductsBlock()->removeProduct(); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php index 381c18d3ee686..7365195d0cd44 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php @@ -95,8 +95,7 @@ public function test( $customers = []; $cartFixtures = []; - $checkoutDataCount = count($checkoutData); - for ($i = 0; $i < $checkoutDataCount; $i++) { + for ($i = 0, $count = count($checkoutData); $i < $count; $i++) { $customers[$i] = $this->fixtureFactory->createByCode('customer', ['dataset' => $customerDataset]); $customers[$i]->persist(); diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 248dfc8e16dc9..73b2f762057b0 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,8 +58,7 @@ public function __construct( public function run() { $shippingMethods = []; - $addressCount = $this->customer->getAddress(); - for ($i = 0; $i < $addressCount; $i++) { + for ($i = 0, $count = $this->customer->getAddress(); $i < $count; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php index 7d229bc358995..24027cacd9e4a 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php @@ -52,8 +52,7 @@ public function processAssert( AssertProductForm $assertProductForm, AssertConfigurableProductForm $assertConfigurableProductForm ) { - $productsCount = count($order->getEntityId()['products']); - for ($i = 0; $i < $productsCount; $i++) { + for ($i = 0, $count = count($order->getEntityId()['products']); $i < $count; $i++) { $product = $order->getEntityId()['products'][$i]; $productData = $product->getData(); if ($product instanceof BundleProduct) { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php index 87ba4d7c2808c..e3a948d6c63de 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php @@ -112,8 +112,7 @@ public function testPricesSegmentation($categoryId, array $entityIds, array $int $items = $model->calculateSeparators($interval); $this->assertEquals(array_keys($intervalItems), array_keys($items)); - $intervalItemsCount = count($intervalItems); - for ($i = 0; $i < $intervalItemsCount; ++$i) { + for ($i = 0, $count = count($intervalItems); $i < $count; ++$i) { $this->assertInternalType('array', $items[$i]); $this->assertEquals($intervalItems[$i]['from'], $items[$i]['from']); $this->assertEquals($intervalItems[$i]['to'], $items[$i]['to']); diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php index 06a8a0accc732..65512653ce3fa 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php @@ -67,8 +67,7 @@ private function tokenizeString($fileContent) $lineNumber = 1; $tokens = token_get_all($fileContent); $snifferTokens = []; - $tokensCount = count($tokens); - for ($i = 0; $i < $tokensCount; $i++) { + for ($i = 0, $count = count($tokens); $i < $count; $i++) { $content = is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]; $snifferTokens[$i]['line'] = $lineNumber; $snifferTokens[$i]['content'] = $content; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php index 0560158a82668..fe15c06bdea4a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php @@ -501,9 +501,8 @@ private function _checkConstantWithClasspath($constant, $class, $replacement, $c { $classPathParts = explode('\\', $class); $classPartialPath = ''; - $classPathPartsCount = count($classPathParts); - for ($i = $classPathPartsCount - 1; $i >= 0; $i--) { - if ($i === ($classPathPartsCount - 1)) { + for ($count = count($classPathParts), $i = $count - 1; $i >= 0; $i--) { + if ($i === ($count - 1)) { $classPartialPath = $classPathParts[$i] . $classPartialPath; } else { $classPartialPath = $classPathParts[$i] . '\\' . $classPartialPath; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php index 67518a6c7d142..748337443d7a8 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php @@ -52,8 +52,7 @@ public function testDictionaryGetter() } $file = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\File\ReadInterface::class); - $dataCount = count($data); - for ($i = 0; $i < $dataCount; $i++) { + for ($i = 0, $count = count($data); $i < $count; $i++) { $file->expects($this->at($i))->method('readCsv')->will($this->returnValue($data[$i])); } $file->expects($this->at($i))->method('readCsv')->will($this->returnValue(false)); diff --git a/lib/internal/Magento/Framework/Archive.php b/lib/internal/Magento/Framework/Archive.php index 7c4b6984b3fc4..3b706f8e97d07 100644 --- a/lib/internal/Magento/Framework/Archive.php +++ b/lib/internal/Magento/Framework/Archive.php @@ -96,15 +96,14 @@ public function pack($source, $destination = 'packed.tgz', $skipRoot = false) { $archivers = $this->_getArchivers($destination); $interimSource = ''; - $archiversCount = count($archivers); - for ($i = 0; $i < $archiversCount; $i++) { - if ($i == $archiversCount - 1) { + for ($i = 0, $count = count($archivers); $i < $count; $i++) { + if ($i == $count - 1) { $packed = $destination; } else { $packed = dirname($destination) . '/~tmp-' . microtime(true) . $archivers[$i] . '.' . $archivers[$i]; } $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot); - if ($interimSource && $i < $archiversCount) { + if ($interimSource && $i < $count) { unlink($interimSource); } $interimSource = $source; diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index c793714f69153..ff9413aa90fea 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -84,8 +84,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false) if (is_string($data) && strlen($data) > $this->_options['slab_size']) { $dataChunks = str_split($data, $this->_options['slab_size']); - $dataChunksCount = count($dataChunks); - for ($i = 0, $cnt = $dataChunksCount; $i < $cnt; $i++) { + for ($i = 0, $count = count($dataChunks); $i < $count; $i++) { $chunkId = $this->_getChunkId($id, $i); if (!parent::save($dataChunks[$i], $chunkId, $tags, $specificLifetime)) { diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 27797d0867924..e0cbab450f6be 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -374,8 +374,7 @@ protected function getVariable($value, $default = '{no_value_defined}') $stackVars = $tokenizer->tokenize(); $result = $default; $last = 0; - $stackVarsCount = count($stackVars); - for ($i = 0; $i < $stackVarsCount; $i++) { + for ($i = 0, $count = count($stackVars); $i < $count; $i++) { if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; diff --git a/lib/internal/Magento/Framework/System/Ftp.php b/lib/internal/Magento/Framework/System/Ftp.php index c915d50741dd2..14f55f32add82 100644 --- a/lib/internal/Magento/Framework/System/Ftp.php +++ b/lib/internal/Magento/Framework/System/Ftp.php @@ -56,8 +56,7 @@ public function mkdirRecursive($path, $mode = 0777) $dir = explode("/", $path); $path = ""; $ret = true; - $dirCount = count($dir); - for ($i = 0; $i < $dirCount; $i++) { + for ($i = 0, $count = count($dir); $i < $count; $i++) { $path .= "/" . $dir[$i]; if (!@ftp_chdir($this->_conn, $path)) { @ftp_chdir($this->_conn, "/"); diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index 9112192f6eb27..6867944d95f8f 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -31,8 +31,7 @@ protected function _parse() $results = []; preg_match_all(Filter::CONSTRUCTION_PATTERN, $data, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if ($results[$i][1] === Filter::TRANS_DIRECTIVE_NAME) { $directive = []; if (preg_match(Filter::TRANS_DIRECTIVE_REGEX, $results[$i][2], $directive) !== 1) { @@ -44,8 +43,7 @@ protected function _parse() } preg_match_all(self::HTML_FILTER, $data, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (!empty($results[$i]['value'])) { $this->_addPhrase($results[$i]['value']); } diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 0f6a402e2609c..6b53a1a4c15b7 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -22,8 +22,7 @@ protected function _parse() $fileRow = fgets($fileHandle, 4096); $results = []; preg_match_all('/mage\.__\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); @@ -31,8 +30,7 @@ protected function _parse() } preg_match_all('/\\$t\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); From 73ff7cbc55cb1bbde88a96421daa5410f1fdd8c9 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 4 Nov 2018 20:33:10 +0530 Subject: [PATCH 1007/1415] Fixed Product Tax total on PDF for 2.3, Reference of PL #18649 --- app/code/Magento/Weee/Model/Sales/Pdf/Weee.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php index fa71e81281763..65480047f2f05 100644 --- a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php +++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php @@ -70,4 +70,17 @@ public function getTotalsForDisplay() return $totals; } + + /** + * Check if we can display Weee total information in PDF + * + * @return bool + */ + public function canDisplay() + { + $items = $this->getSource()->getAllItems(); + $store = $this->getSource()->getStore(); + $amount = $this->_weeeData->getTotalAmounts($items, $store); + return $this->getDisplayZero() === 'true' || $amount != 0; + } } From 5fa66213fa852793694b4aee831bb93969bff5d0 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Sun, 4 Nov 2018 17:20:03 +0200 Subject: [PATCH 1008/1415] magento/magento2:#18979 - API: Bundle Product Option Repository Delete method removes incorrect option - Fixed failed unit tests --- .../Magento/Bundle/Model/OptionRepository.php | 11 +-- .../Test/Unit/Model/OptionRepositoryTest.php | 74 +++++++++++++++++-- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index a4d579a44174a..46c44c83b5bb5 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -106,17 +106,18 @@ public function get($sku, $optionId) $productLinks = $this->linkManagement->getChildren($product->getSku(), $optionId); - /** @var \Magento\Bundle\Api\Data\OptionInterface $option */ + /** @var \Magento\Bundle\Api\Data\OptionInterface $optionDataObject */ $optionDataObject = $this->optionFactory->create(); $this->dataObjectHelper->populateWithArray( $optionDataObject, $option->getData(), \Magento\Bundle\Api\Data\OptionInterface::class ); - $optionDataObject->setOptionId($option->getId()) - ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) - ->setSku($product->getSku()) - ->setProductLinks($productLinks); + + $optionDataObject->setOptionId($option->getId()); + $optionDataObject->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()); + $optionDataObject->setSku($product->getSku()); + $optionDataObject->setProductLinks($productLinks); return $optionDataObject; } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php index b4a466b413af0..c579d8289d1b6 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php @@ -8,6 +8,7 @@ namespace Magento\Bundle\Test\Unit\Model; use Magento\Bundle\Model\OptionRepository; +use Magento\Framework\Exception\NoSuchEntityException; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -84,7 +85,7 @@ protected function setUp() ->getMock(); $this->optionResourceMock = $this->createPartialMock( \Magento\Bundle\Model\ResourceModel\Option::class, - ['delete', '__wakeup', 'save', 'removeOptionSelections'] + ['get', 'delete', '__wakeup', 'save', 'removeOptionSelections'] ); $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); $this->linkManagementMock = $this->createMock(\Magento\Bundle\Api\ProductLinkManagementInterface::class); @@ -227,32 +228,91 @@ public function testDeleteThrowsExceptionIfCannotDelete() $this->model->delete($optionMock); } + /** + * Test successful delete action for given $optionId + */ public function testDeleteById() { $productSku = 'sku'; $optionId = 100; - $productMock = $this->createMock(\Magento\Catalog\Api\Data\ProductInterface::class); + + $optionMock = $this->createMock(\Magento\Bundle\Model\Option::class); + $optionMock->expects($this->exactly(2)) + ->method('getId') + ->willReturn($optionId); + + $optionMock->expects($this->once()) + ->method('getData') + ->willReturn([ + 'title' => 'Option title', + 'option_id' => $optionId + ]); + + $this->optionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($optionMock); + + $productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + ['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku'] + ); $productMock->expects($this->once()) ->method('getTypeId') ->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE); - $this->productRepositoryMock->expects($this->once()) + $productMock->expects($this->exactly(2))->method('getSku')->willReturn($productSku); + + $this->productRepositoryMock + ->expects($this->once()) ->method('get') ->with($productSku) ->willReturn($productMock); + $optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class); + $optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock); + $this->typeMock->expects($this->once()) + ->method('getOptionsCollection') + ->with($productMock) + ->willReturn($optCollectionMock); + + $this->assertTrue($this->model->deleteById($productSku, $optionId)); + } + + /** + * Tests if NoSuchEntityException thrown when provided $optionId not found + */ + public function testDeleteByIdException() { + $productSku = 'sku'; + $optionId = null; + $optionMock = $this->createMock(\Magento\Bundle\Model\Option::class); + $optionMock->expects($this->exactly(1)) + ->method('getId') + ->willReturn($optionId); + + $productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + ['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku'] + ); + $productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE); + + $this->productRepositoryMock + ->expects($this->once()) + ->method('get') + ->with($productSku) + ->willReturn($productMock); $optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class); + $optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock); $this->typeMock->expects($this->once()) ->method('getOptionsCollection') ->with($productMock) ->willReturn($optCollectionMock); - $optCollectionMock->expects($this->once())->method('setIdFilter')->with($optionId)->willReturnSelf(); - $optCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($optionMock); + $this->expectException(NoSuchEntityException::class); - $this->optionResourceMock->expects($this->once())->method('delete')->with($optionMock)->willReturnSelf(); - $this->assertTrue($this->model->deleteById($productSku, $optionId)); + $this->model->deleteById($productSku, $optionId); } /** From f06056a040a22d49a580fba331cad11799267272 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Mon, 5 Nov 2018 00:32:38 +0200 Subject: [PATCH 1009/1415] Sort schema field for test cases --- .../Framework/GraphQl/Config/GraphQlReaderTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 8583dcf3e4cd2..3d3372429123a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -191,6 +191,16 @@ enumValues(includeDeprecated: true) { $mergedSchemaResponseFields = array_merge($schemaResponseFieldsFirstHalf, $schemaResponseFieldsSecondHalf); foreach ($expectedOutput as $searchTerm) { + $sortFields = ['inputFields', 'fields']; + foreach ($sortFields as $sortField) { + isset($searchTerm[$sortField]) && is_array($searchTerm[$sortField]) + ? usort($searchTerm[$sortField], function($a, $b) { + $cmpField = 'name'; + return isset($a[$cmpField]) && isset($b[$cmpField]) + ? strcmp($a[$cmpField], $b[$cmpField]) : 0; + }) : null; + } + $this->assertTrue( (in_array($searchTerm, $mergedSchemaResponseFields)), 'Missing type in the response' From a30501f0d59d42c661a11b009a6eb532dd48de4d Mon Sep 17 00:00:00 2001 From: Vlad Veselov <orlangur@users.noreply.github.com> Date: Mon, 5 Nov 2018 00:45:12 +0200 Subject: [PATCH 1010/1415] Add `count` call back --- .../Multishipping/Test/TestStep/FillShippingInformationStep.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 73b2f762057b0..2c41ce3d8b4e2 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,7 +58,7 @@ public function __construct( public function run() { $shippingMethods = []; - for ($i = 0, $count = $this->customer->getAddress(); $i < $count; $i++) { + for ($i = 0, $count = count($this->customer->getAddress()); $i < $count; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); From 0f575bce67a6dbc4fd9226d7b0ef19eaaebe0fed Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Mon, 5 Nov 2018 00:19:04 +0100 Subject: [PATCH 1011/1415] #18956 Fix for phpunit-test case --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 4 ++-- .../Test/Unit/Model/Config/Importer/Processor/CreateTest.php | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 9d1a7a38ede68..71ffa5303293d 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,8 +177,8 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - if (!isset($groupData['root_categry_id'])) { - $groupData['root_categry_id'] = 0; + if (!isset($groupData['root_category_id'])) { + $groupData['root_category_id'] = 0; } $group->setData($groupData); diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php index 2c2b0b00aec43..0901464224399 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php @@ -291,9 +291,6 @@ public function testRunGroup() $this->groupMock->expects($this->exactly(3)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) - ->method('setRootCategoryId') - ->with(0); $this->groupMock->expects($this->once()) ->method('getDefaultStoreId') ->willReturn($defaultStoreId); From a38250ec547c80e6558e571317f595673efeebb2 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Mon, 5 Nov 2018 10:51:53 +0200 Subject: [PATCH 1012/1415] magento-engcom/magento2ce#2299: Code style fixes --- .../Magento/Catalog/Model/AbstractModel.php | 13 ++--- .../Magento/Sales/Model/Order/Address.php | 56 +++++++++---------- .../Magento/Widget/Block/BlockInterface.php | 1 + 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/Catalog/Model/AbstractModel.php b/app/code/Magento/Catalog/Model/AbstractModel.php index 5faf6ccbcdef9..78a49cd1e8b14 100644 --- a/app/code/Magento/Catalog/Model/AbstractModel.php +++ b/app/code/Magento/Catalog/Model/AbstractModel.php @@ -282,9 +282,9 @@ public function getWebsiteStoreIds() * * Default value existing is flag for using store value in data * - * @param string $attributeCode - * @param mixed $value - * @return $this + * @param string $attributeCode + * @param mixed $value + * @return $this * * @deprecated 101.0.0 */ @@ -332,11 +332,10 @@ public function getAttributeDefaultValue($attributeCode) } /** - * Set attribute code flag if attribute has value in current store and does not use - * value of default store as value + * Set attribute code flag if attribute has value in current store and does not use value of default store as value * - * @param string $attributeCode - * @return $this + * @param string $attributeCode + * @return $this * * @deprecated 101.0.0 */ diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index 8bc602c75db4d..083ec0089a5c0 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -173,7 +173,7 @@ protected function implodeStreetValue($value) * Enforce format of the street field * * @param array|string $key - * @param null $value + * @param array|string $value * @return $this */ public function setData($key, $value = null) @@ -508,7 +508,7 @@ public function getVatRequestSuccess() } /** - * {@inheritdoc} + * @inheritdoc */ public function setParentId($id) { @@ -516,7 +516,7 @@ public function setParentId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($id) { @@ -524,7 +524,7 @@ public function setCustomerAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($id) { @@ -532,7 +532,7 @@ public function setRegionId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -540,7 +540,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($id) { @@ -548,7 +548,7 @@ public function setCustomerId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -556,7 +556,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -564,7 +564,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -572,7 +572,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -580,7 +580,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -588,7 +588,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -596,7 +596,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -604,7 +604,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($id) { @@ -612,7 +612,7 @@ public function setCountryId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -620,7 +620,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAddressType($addressType) { @@ -628,7 +628,7 @@ public function setAddressType($addressType) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -636,7 +636,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -644,7 +644,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -652,7 +652,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -660,7 +660,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($id) { @@ -668,7 +668,7 @@ public function setVatId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatIsValid($vatIsValid) { @@ -676,7 +676,7 @@ public function setVatIsValid($vatIsValid) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestId($id) { @@ -684,7 +684,7 @@ public function setVatRequestId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -692,7 +692,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestDate($vatRequestDate) { @@ -700,7 +700,7 @@ public function setVatRequestDate($vatRequestDate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestSuccess($vatRequestSuccess) { @@ -708,7 +708,7 @@ public function setVatRequestSuccess($vatRequestSuccess) } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Sales\Api\Data\OrderAddressExtensionInterface|null */ @@ -718,7 +718,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes * @return $this diff --git a/app/code/Magento/Widget/Block/BlockInterface.php b/app/code/Magento/Widget/Block/BlockInterface.php index db101b5e81adc..4f795d949b8cd 100644 --- a/app/code/Magento/Widget/Block/BlockInterface.php +++ b/app/code/Magento/Widget/Block/BlockInterface.php @@ -19,6 +19,7 @@ interface BlockInterface { /** * Add data to the widget. + * * Retains previous data in the widget. * * @param array $arr From f9b4595a60d7b81775cdd43f996991acb0d50ff2 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 12:08:27 +0300 Subject: [PATCH 1013/1415] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Fix perfomance --- .../Model/Indexer/Fulltext/Action/DataProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 421746e7761c1..6cd4e227b85c8 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -653,7 +653,8 @@ private function getAttributeOptionValue($attributeId, $valueIds, $storeId) } } foreach ($attributeValueIds as $attrValueId) { - $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + if (isset($this->attributeOptions[$optionKey][$attrValueId])) + $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; } return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } From da66589239c95d7739b2c01e27628d178ed9c139 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 5 Nov 2018 12:32:18 +0300 Subject: [PATCH 1014/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix functional test --- .../Mftf/Section/AdminProductFormGroupedProductsSection.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index 0739c4e601b62..f5549f26bfd56 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,8 +11,8 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> - <element name="nextActionButton" type="button" selector="//button[@class='action-next']"/> - <element name="previousActionButton" type="button" selector="//button[@class='action-previous']"/> + <element name="nextActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-next"/> + <element name="previousActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-previous"/> <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> From 1a703c7054e3efc51cf9eded93602c6d4b93f726 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 5 Nov 2018 13:11:11 +0300 Subject: [PATCH 1015/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../adminhtml/web/js/grouped-product-grid.js | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index f257cb2df729e..c8e5a58c99e78 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -23,6 +23,7 @@ define([ if (position || position === 0) { this.checkMaxPosition(position); this.sort(position, elem); + if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) { this.shiftNextPagesPositions(position); } @@ -37,17 +38,17 @@ define([ * @param position */ shiftNextPagesPositions: function (position) { - var recordData = this.recordData(); + + var recordData = this.recordData(), + startIndex = ~~this.currentPage() * this.pageSize, + offset = position - startIndex + 1; if (~~this.currentPage() === this.pages()) { return false; - } else { - var startIndex = ~~this.currentPage() * this.pageSize, - offset = position - startIndex + 1; - for (var index = startIndex; index < recordData.length; index++) { - recordData[index].position = index + offset; - } - this.recordData(recordData); } + for (var index = startIndex; index < recordData.length; index++) { + recordData[index].position = index + offset; + } + this.recordData(recordData); }, @@ -58,14 +59,14 @@ define([ * @param event */ updateGridPosition: function (data, event) { - var inputValue = parseInt(event.target.value), + var inputValue = parseInt(event.target.value, 10), recordData = this.recordData(), record, previousValue, updatedRecord; record = this.elems().find(function (obj) { - return obj.dataScope === data.parentScope + return obj.dataScope === data.parentScope; }); previousValue = this.getCalculatedPosition(record); @@ -105,7 +106,7 @@ define([ */ getUpdatedRecordIndex: function (recordData, recordId) { return recordData.map(function (o) { - return ~~o.id + return ~~o.id; }).indexOf(~~recordId); }, @@ -163,7 +164,7 @@ define([ this.elems([]); updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); recordData.forEach(function (value, index) { - recordData[index].position = (index === updatedRecord) ? 0 : value.position + 1; + recordData[index].position = index === updatedRecord ? 0 : value.position + 1; }); this.reloadGridData(recordData); } @@ -198,7 +199,7 @@ define([ * @return {number} */ getDefaultPageBoundary: function () { - return (~~this.currentPage() * this.pageSize) - 1; + return ~~this.currentPage() * this.pageSize - 1; }, /** @@ -208,7 +209,7 @@ define([ */ getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { - return ~~r.position + return ~~r.position; })); } }); From 322d82bc8af1c8fefc3cde25536a82556f59aadc Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 5 Nov 2018 10:51:26 +0000 Subject: [PATCH 1016/1415] magento-engcom/import-export-improvements#122: Update History file for phpstyle check --- app/code/Magento/ImportExport/Model/History.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/History.php b/app/code/Magento/ImportExport/Model/History.php index 617ca11e18f22..19d62259c02a2 100644 --- a/app/code/Magento/ImportExport/Model/History.php +++ b/app/code/Magento/ImportExport/Model/History.php @@ -298,6 +298,8 @@ public function setSummary($summary) } /** + * Load the last inserted item + * * @return $this */ public function loadLastInsertItem() From a089fa137b790ef5be815eee7672baabc00b8755 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 5 Nov 2018 13:29:39 +0200 Subject: [PATCH 1017/1415] ENGCOM-3283: Feature/import success page improvement #138 Fix functional tests. --- .../ImportExport/Test/Constraint/AssertImportSuccessMessage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php index ca75e3b203f63..a5408426514f2 100644 --- a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php +++ b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php @@ -28,7 +28,7 @@ class AssertImportSuccessMessage extends AbstractConstraint public function processAssert(AdminImportIndex $adminImportIndex) { $validationMessage = $adminImportIndex->getMessagesBlock()->getImportResultMessage(); - \PHPUnit\Framework\Assert::assertEquals( + \PHPUnit\Framework\Assert::assertStringEndsWith( self::SUCCESS_MESSAGE, $validationMessage, 'Wrong validation result is displayed.' From 2f995d13c332dd4a2e560373d231c0f06cf25f98 Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Mon, 5 Nov 2018 12:33:25 +0100 Subject: [PATCH 1018/1415] GraphQL-202: [Mutations] adds description and category_id as parameter --- app/code/Magento/SendFriendGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 87bf90fd10072..4123387650838 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Mutation { - sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"Recommends Product by Sending Single/Multiple Email") } input SendEmailToFriendSenderInput { @@ -16,9 +16,9 @@ type Sender { email: String! message: String! } -#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed type Params { product_id: Int! + category_id: Int! } type Recipient { From 1fb624d381e67581a06e66809883e51a4a4b0d75 Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Mon, 5 Nov 2018 12:34:46 +0100 Subject: [PATCH 1019/1415] GraphQL-202: [Mutations] moves validation logic to separate module --- .../Model/Validation/Validation.php | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php new file mode 100644 index 0000000000000..49f7feeaba489 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SendFriendGraphQl\Model\Validation; + +use Magento\Framework\DataObjectFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\SendFriend\Model\SendFriend; + +class Validation +{ + /** + * @var SendFriend + */ + private $sendFriend; + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + public function __construct( + DataObjectFactory $dataObjectFactory, + SendFriend $sendFriend + ) { + $this->sendFriend = $sendFriend; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @param $args + * @param array $recipientsArray + * @throws GraphQlInputException + */ + public function validate($args, array $recipientsArray): void + { + $this->prepareDataForSendFriendValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + } + + private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + +} \ No newline at end of file From ed6649194f0844f8faae0ba63a5df52b3fe8d5c4 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Mon, 5 Nov 2018 14:34:03 +0200 Subject: [PATCH 1020/1415] Add additional check if password hash is empty in auth process --- app/code/Magento/Customer/Model/Authentication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Authentication.php b/app/code/Magento/Customer/Model/Authentication.php index 0967f1a0189e3..b0729647d7eec 100644 --- a/app/code/Magento/Customer/Model/Authentication.php +++ b/app/code/Magento/Customer/Model/Authentication.php @@ -167,7 +167,7 @@ public function authenticate($customerId, $password) { $customerSecure = $this->customerRegistry->retrieveSecureData($customerId); $hash = $customerSecure->getPasswordHash(); - if (!$this->encryptor->validateHash($password, $hash)) { + if (!$hash || !$this->encryptor->validateHash($password, $hash)) { $this->processAuthenticationFailure($customerId); if ($this->isLocked($customerId)) { throw new UserLockedException(__('The account is locked.')); From 2a021c075f52e39b03dc8c30ba418afc57851041 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 17:12:32 +0300 Subject: [PATCH 1021/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c8e5a58c99e78..3fb7e9ecc8b4b 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -35,17 +35,19 @@ define([ /** * Shift positions for next page elements * - * @param position + * @param {Number} position */ shiftNextPagesPositions: function (position) { var recordData = this.recordData(), startIndex = ~~this.currentPage() * this.pageSize, - offset = position - startIndex + 1; + offset = position - startIndex + 1, + index = startIndex; + if (~~this.currentPage() === this.pages()) { return false; } - for (var index = startIndex; index < recordData.length; index++) { + for (index; index < recordData.length; index++) { recordData[index].position = index + offset; } this.recordData(recordData); From e18bcb5f846df4ae8fd84f2b66890984982aee04 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 17:15:28 +0300 Subject: [PATCH 1022/1415] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Fix static testd --- .../Model/Indexer/Fulltext/Action/DataProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 6cd4e227b85c8..39cb95747c2cf 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -653,8 +653,9 @@ private function getAttributeOptionValue($attributeId, $valueIds, $storeId) } } foreach ($attributeValueIds as $attrValueId) { - if (isset($this->attributeOptions[$optionKey][$attrValueId])) + if (isset($this->attributeOptions[$optionKey][$attrValueId])) { $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + } } return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } From 518b4d4a181ffd60d57909b12b07fd39f149d9c7 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 5 Nov 2018 14:41:29 +0000 Subject: [PATCH 1023/1415] magento-engcom/import-export-improvements#126: update the download controller to implement the HttpGetActionInterface --- .../ImportExport/Controller/Adminhtml/History/Download.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php index 4dda5ebc4a310..d46fda9a1c0ef 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php @@ -6,9 +6,10 @@ */ namespace Magento\ImportExport\Controller\Adminhtml\History; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; -class Download extends \Magento\ImportExport\Controller\Adminhtml\History +class Download extends \Magento\ImportExport\Controller\Adminhtml\History implements HttpGetActionInterface { /** * @var \Magento\Framework\Controller\Result\RawFactory From 0f4c7946bc003d05dfa4330ffb4a09cc08206435 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 5 Nov 2018 09:44:42 -0600 Subject: [PATCH 1024/1415] MAGETWO-95212: block call to getCurrentUrl method is returning ajax request value - Removed unintended change --- app/code/Magento/Catalog/Block/Product/AbstractProduct.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php index fb45246ea3464..c8da0f70f73b6 100644 --- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php @@ -266,7 +266,6 @@ public function getProductUrl($product, $additional = []) if (!isset($additional['_escape'])) { $additional['_escape'] = true; } - $additional['useUencPlaceholder'] = true; return $product->getUrlModel()->getUrl($product, $additional); } From ca90fef1a09a8dc0e03299df89ba7c0e24ea05dc Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Mon, 5 Nov 2018 18:40:22 +0200 Subject: [PATCH 1025/1415] MAGETWO-96024: Invalid element declared for AdminProductGridSection section. Delete empty files --- .../ChangeStatusProductUsingProductGridActionGroup.xml | 0 .../Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml delete mode 100644 app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml deleted file mode 100644 index e69de29bb2d1d..0000000000000 From a40eb487b7d3f57d6241620ff2f49d9b4196f383 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 5 Nov 2018 10:42:57 -0600 Subject: [PATCH 1026/1415] ENGCOM-3355: [Forwardport] Fix Authenticating a customer via REST API does not update the last logged in data #18973 - Fixed docblocks --- app/code/Magento/Integration/Model/CustomerTokenService.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/Model/CustomerTokenService.php b/app/code/Magento/Integration/Model/CustomerTokenService.php index 35d0424d3b4fa..7c2c444a734eb 100644 --- a/app/code/Magento/Integration/Model/CustomerTokenService.php +++ b/app/code/Magento/Integration/Model/CustomerTokenService.php @@ -16,6 +16,9 @@ use Magento\Framework\Exception\AuthenticationException; use Magento\Framework\Event\ManagerInterface; +/** + * @inheritdoc + */ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServiceInterface { /** @@ -79,7 +82,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function createCustomerAccessToken($username, $password) { From 90831f56053bc2af291468e01bead189441eb25c Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 19:16:24 +0200 Subject: [PATCH 1027/1415] graphQl: removed not needed exception, added test coverage --- .../Model/Cart/SetShippingAddressOnCart.php | 9 +- .../Quote/SetShippingAddressOnCartTest.php | 424 ++++++++++++++++++ 2 files changed, 425 insertions(+), 8 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 43e58bb807672..a2d93ac1753c5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -84,19 +84,12 @@ public function setAddresses(ContextInterface $context, int $cartId, array $ship if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { throw new GraphQlAuthorizationException( __( - 'Address management allowed only for authorized customers' + 'Address management allowed only for authorized customers.' ) ); } /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); - if ($context->getUserId() !== (int)$customerAddress->getCustomerId()) { - throw new GraphQlInputException( - __( - 'Address is not applicable for current customer' - ) - ); - } $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } else { $shippingAddress = $this->addressModel->addData($addressInput); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php new file mode 100644 index 0000000000000..9771dbbf84c48 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -0,0 +1,424 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Quote; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; +use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\TestFramework\ObjectManager; + +/** + * Test for set shipping addresses on cart mutation + */ +class SetShippingAddressOnCartTest extends GraphQlAbstract +{ + /** + * @var QuoteResource + */ + private $quoteResource; + + /** + * @var Quote + */ + private $quote; + + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedId; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->quoteResource = $objectManager->create(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetNewGuestShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetSavedShippingAddressOnCartByGuest() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage('Address management allowed only for authorized customers.'); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetSavedAndNewShippingAddressOnCartAtTheSameTime() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1, + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage( + 'Shipping address can\'t contain "customer_address_id" and "address" input at the same time.' + ); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetShippingAddressOnCartWithNoAddresses() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + {} + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage( + 'Shipping address should contain either "customer_address_id" or "address" input.' + ); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + */ + public function testSetNewRegisteredCustomerShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $this->quote->setCustomerId(1); + $this->quoteResource->save($this->quote); + + $headerMap = $this->getHeaderMap(); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testSetSavedRegisteredCustomerShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $this->quote->setCustomerId(1); + $this->quoteResource->save($this->quote); + + $headerMap = $this->getHeaderMap(); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertSavedShippingAddressFields($shippingAddressResponse); + } + + /** + * Verify the all the whitelisted fields for a New Address Object + * + * @param array $shippingAddressResponse + */ + private function assertNewShippingAddressFields(array $shippingAddressResponse): void + { + $assertionMap = [ + ['response_field' => 'firstname', 'expected_value' => 'test firstname'], + ['response_field' => 'lastname', 'expected_value' => 'test lastname'], + ['response_field' => 'company', 'expected_value' => 'test company'], + ['response_field' => 'street', 'expected_value' => [0 => 'test street 1', 1 => 'test street 2']], + ['response_field' => 'city', 'expected_value' => 'test city'], + ['response_field' => 'postcode', 'expected_value' => '887766'], + ['response_field' => 'telephone', 'expected_value' => '88776655'] + ]; + + $this->assertResponseFields($shippingAddressResponse, $assertionMap); + } + + /** + * Verify the all the whitelisted fields for a Address Object + * + * @param array $shippingAddressResponse + */ + private function assertSavedShippingAddressFields(array $shippingAddressResponse): void + { + $assertionMap = [ + ['response_field' => 'firstname', 'expected_value' => 'John'], + ['response_field' => 'lastname', 'expected_value' => 'Smith'], + ['response_field' => 'company', 'expected_value' => 'CompanyName'], + ['response_field' => 'street', 'expected_value' => [0 => 'Green str, 67']], + ['response_field' => 'city', 'expected_value' => 'CityM'], + ['response_field' => 'postcode', 'expected_value' => '75477'], + ['response_field' => 'telephone', 'expected_value' => '3468676'] + ]; + + $this->assertResponseFields($shippingAddressResponse, $assertionMap); + } + + /** + * @param string $username + * @return array + */ + private function getHeaderMap(string $username = 'customer@example.com'): array + { + $password = 'password'; + /** @var CustomerTokenServiceInterface $customerTokenService */ + $customerTokenService = ObjectManager::getInstance() + ->get(CustomerTokenServiceInterface::class); + $customerToken = $customerTokenService->createCustomerAccessToken($username, $password); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + return $headerMap; + } +} From 5d2b1c8d80f23a8061c63702d370728d05234cd5 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 19:17:53 +0200 Subject: [PATCH 1028/1415] graphQl: fixed dependency issue --- app/code/Magento/QuoteGraphQl/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index c9900dd5f3150..485c958718bf3 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -7,7 +7,8 @@ "magento/framework": "*", "magento/module-quote": "*", "magento/module-catalog": "*", - "magento/module-store": "*" + "magento/module-store": "*", + "magento/module-checkout": "*" }, "suggest": { "magento/module-graph-ql": "*" From 743d3ebd5584b61b3c3d1ff804767871caff470c Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 5 Nov 2018 11:46:52 -0600 Subject: [PATCH 1029/1415] MAGETWO-95248: Show Packages button in Shipping and Tracking information section of Shipments doesn't work --- .../view/adminhtml/web/js/packages.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 app/code/Magento/Shipping/view/adminhtml/web/js/packages.js diff --git a/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js b/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js new file mode 100644 index 0000000000000..f46ad4192d170 --- /dev/null +++ b/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js @@ -0,0 +1,39 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'Magento_Ui/js/modal/modal', + 'mage/translate' +], function ($, modal, $t) { + 'use strict'; + + return function (config, element) { + config.buttons = [ + { + text: $t('Print'), + 'class': 'action action-primary', + + /** + * Click handler + */ + click: function () { + window.location.href = this.options.url; + } + }, { + text: $t('Cancel'), + 'class': 'action action-secondary', + + /** + * Click handler + */ + click: function () { + this.closeModal(); + } + } + ]; + modal(config, element); + }; +}); From 3343ad61aa8ac0d596f5b6783b25852d8589f966 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Mon, 5 Nov 2018 20:41:11 +0200 Subject: [PATCH 1030/1415] MAGETWO-96026: Create MFTF test for MAGETWO-93973. Add more stability --- ...PricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 6eb78809b187d..a8b2df1fcfa67 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -63,7 +63,9 @@ <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsUseConfigSettings}}" stepKey="clickOnEnableQtyIncrementsUseConfigSettingsCheckbox"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="clickOnEnableQtyIncrements"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsOptions(('1'))}}" stepKey="chooseYesOnEnableQtyIncrements"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="scrollToQtyIncrementsUseConfigSettings"/> <click selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="clickOnQtyIncrementsUseConfigSettings"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" stepKey="scrollToQtyIncrements"/> <fillField selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" userInput=".5" stepKey="fillQtyIncrements"/> <!--Step6. Close *Advanced Inventory* (Click on button *Done*). Save *prod1* (Click on button *Save*) --> <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton3"/> From e1f09fb984df705e35dde07092d04957c7c0e5c1 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 21:15:25 +0200 Subject: [PATCH 1031/1415] graphQl: added extension point for multishipping --- .../Model/Cart/SetShippingAddressesOnCart.php | 48 +++++++++++++++++++ .../SingleShippingAddressProcessor.php} | 20 +++----- .../SetShippingAddressesOnCartInterface.php | 31 ++++++++++++ .../Resolver/SetShippingAddressesOnCart.php | 22 ++++----- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 9 ++++ 5 files changed, 106 insertions(+), 24 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php rename app/code/Magento/QuoteGraphQl/Model/Cart/{SetShippingAddressOnCart.php => SetShippingAddressesOnCart/SingleShippingAddressProcessor.php} (85%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..ad3615b94f8ef --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart; + +use InvalidArgumentException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; + +/** + * Set shipping addresses for shopping cart processors chain + */ +class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface +{ + /** + * @var SetShippingAddressesOnCartInterface[] + */ + private $shippingAddressProcessors; + + /** + * @param array $shippingAddressProcessors + */ + public function __construct( + array $shippingAddressProcessors + ) { + $this->shippingAddressProcessors = $shippingAddressProcessors; + } + + /** + * @inheritdoc + */ + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + { + foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { + if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { + throw new InvalidArgumentException( + get_class($shippingAddressProcessor) . + ' is not instance of \Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface.' + ); + } + + $shippingAddressProcessor->execute($context, $cartId, $shippingAddresses); + } + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php similarity index 85% rename from app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php index a2d93ac1753c5..6584b9887bed5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Cart; +namespace Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -15,13 +15,12 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** - * Class SetShippingAddressOnCart - * - * Set shipping address for a specified shopping cart + * Set single shipping address for a specified shopping cart */ -class SetShippingAddressOnCart +class SingleShippingAddressProcessor implements SetShippingAddressesOnCartInterface { /** * @var ShippingAddressManagementInterface @@ -54,17 +53,12 @@ public function __construct( } /** - * @param ContextInterface $context - * @param int $cartId - * @param array $shippingAddresses - * @return void + * @inheritdoc */ - public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { - throw new GraphQlInputException( - __('Multiple address does not allowed here!') - ); + return; } $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php new file mode 100644 index 0000000000000..f9623e36c5395 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart; + +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; + +/** + * Extension point for setting shipping addresses for a specified shopping cart + * + * All objects that are responsible for set shipping addresses on cart via GraphQl should implement this interface. + */ +interface SetShippingAddressesOnCartInterface +{ + + /** + * Set shipping addresses for a specified shopping cart + * + * @param ContextInterface $context + * @param int $cartId + * @param array $shippingAddresses + * @return void + * @throws GraphQlInputException + */ + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void; +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index fcb4255a75eb7..ec151214dbc42 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -15,7 +15,7 @@ use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; -use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** * Class SetShippingAddressesOnCart @@ -29,11 +29,6 @@ class SetShippingAddressesOnCart implements ResolverInterface */ private $maskedQuoteIdToQuoteId; - /** - * @var SetShippingAddressOnCart - */ - private $setShippingAddressOnCart; - /** * @var ShippingAddressManagementInterface */ @@ -49,25 +44,30 @@ class SetShippingAddressesOnCart implements ResolverInterface */ private $arrayManager; + /** + * @var SetShippingAddressesOnCartInterface + */ + private $setShippingAddressesOnCart; + /** * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param SetShippingAddressOnCart $setShippingAddressOnCart * @param ShippingAddressManagementInterface $shippingAddressManagement * @param GetCartForUser $getCartForUser * @param ArrayManager $arrayManager + * @param SetShippingAddressesOnCartInterface $setShippingAddressesOnCart */ public function __construct( MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - SetShippingAddressOnCart $setShippingAddressOnCart, ShippingAddressManagementInterface $shippingAddressManagement, GetCartForUser $getCartForUser, - ArrayManager $arrayManager + ArrayManager $arrayManager, + SetShippingAddressesOnCartInterface $setShippingAddressesOnCart ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->setShippingAddressOnCart = $setShippingAddressOnCart; $this->shippingAddressManagement = $shippingAddressManagement; $this->getCartForUser = $getCartForUser; $this->arrayManager = $arrayManager; + $this->setShippingAddressesOnCart = $setShippingAddressesOnCart; } /** @@ -89,7 +89,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); $cartId = (int)$cart->getEntityId(); - $this->setShippingAddressOnCart->setAddresses($context, $cartId, $shippingAddresses); + $this->setShippingAddressesOnCart->execute($context, $cartId, $shippingAddresses); return [ 'cart' => [ diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index 43941c9740048..f28d484fa0f6f 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -6,6 +6,15 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" + type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart" /> + <type name="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface"> + <arguments> + <argument name="shippingAddressProcessors" xsi:type="array"> + <item name="singleShippingAddress" xsi:type="object">Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart\SingleShippingAddressProcessor</item> + </argument> + </arguments> + </type> <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> <arguments> <argument name="specifications" xsi:type="array"> From 55b6f4e46809d162e2258e4da760228ec4062a93 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 22:12:55 +0200 Subject: [PATCH 1032/1415] graphQl: fixed SetShippingAddressesInterface param --- .../QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php | 5 +++-- .../SingleShippingAddressProcessor.php | 5 +++-- .../Model/Cart/SetShippingAddressesOnCartInterface.php | 5 +++-- .../Model/Resolver/SetShippingAddressesOnCart.php | 3 +-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index ad3615b94f8ef..8ebcdef1f549a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -9,6 +9,7 @@ use InvalidArgumentException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; /** * Set shipping addresses for shopping cart processors chain @@ -32,7 +33,7 @@ public function __construct( /** * @inheritdoc */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { @@ -42,7 +43,7 @@ public function execute(ContextInterface $context, int $cartId, array $shippingA ); } - $shippingAddressProcessor->execute($context, $cartId, $shippingAddresses); + $shippingAddressProcessor->execute($context, $cart, $shippingAddresses); } } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php index 6584b9887bed5..41675716c68bf 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php @@ -12,6 +12,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; @@ -55,7 +56,7 @@ public function __construct( /** * @inheritdoc */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { return; @@ -89,6 +90,6 @@ public function execute(ContextInterface $context, int $cartId, array $shippingA $shippingAddress = $this->addressModel->addData($addressInput); } - $this->shippingAddressManagement->assign($cartId, $shippingAddress); + $this->shippingAddressManagement->assign($cart->getId(), $shippingAddress); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index f9623e36c5395..ae337240c3a26 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; /** * Extension point for setting shipping addresses for a specified shopping cart @@ -22,10 +23,10 @@ interface SetShippingAddressesOnCartInterface * Set shipping addresses for a specified shopping cart * * @param ContextInterface $context - * @param int $cartId + * @param CartInterface $cart * @param array $shippingAddresses * @return void * @throws GraphQlInputException */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void; + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void; } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index ec151214dbc42..587ebb2b6db1f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -87,9 +87,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $args['input']['cart_id']; $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); - $cartId = (int)$cart->getEntityId(); - $this->setShippingAddressesOnCart->execute($context, $cartId, $shippingAddresses); + $this->setShippingAddressesOnCart->execute($context, $cart, $shippingAddresses); return [ 'cart' => [ From e496e26af5dfbe6d109a48c7f0071cd257bcf7fc Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 5 Nov 2018 14:32:34 -0600 Subject: [PATCH 1033/1415] MAGETWO-95589: [FT][Temando] Tests fail with enabled Temando extension --- .../Mftf/ActionGroup/StorefrontProductCartActionGroup.xml | 5 ++++- .../Test/Mftf/Section/CheckoutCartSummarySection.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 3 ++- .../CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml | 2 ++ .../Test/Block/Adminhtml/Order/Create/Shipping/Method.php | 1 - 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..8ef9ff9e8df38 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -84,7 +84,10 @@ <argument name="total"/> </arguments> <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> - <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <conditionalClick selector="{{CheckoutCartSummarySection.shippingHeading}}" dependentSelector="{{CheckoutCartSummarySection.shippingMethodForm}}" visible="false" stepKey="openEstimateShippingSection"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="waitForShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectShippingMethod"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> <see userInput="({{shippingMethod}})" selector="{{CheckoutCartSummarySection.shippingMethod}}" stepKey="assertShippingMethod"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index a1a8d2ba3eade..c2e0868848188 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CheckoutCartSummarySection"> <element name="subtotal" type="text" selector="//*[@id='cart-totals']//tr[@class='totals sub']//td//span[@class='price']"/> + <element name="shippingMethodForm" type="text" selector="#co-shipping-method-form"/> <element name="shippingMethod" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//th//span[@class='value']"/> <element name="shipping" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//td//span[@class='price']"/> <element name="total" type="text" selector="//*[@id='cart-totals']//tr[@class='grand totals']//td//span[@class='price']"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index 3eec020e26347..045fdbb33763f 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -72,11 +72,12 @@ <!-- Should not see the discount yet because we have not set country --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid country --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="Brazil" stepKey="fillCountry"/> <waitForPageLoad stepKey="waitForCountry1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index 73b5d2546f439..d8c3ef9c32b0b 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -76,11 +76,12 @@ <!-- Should not see the discount yet because we have not filled in postcode --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid postcode --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="78613" stepKey="fillPostcode"/> <waitForPageLoad stepKey="waitForPostcode1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index 9395e87c20edb..647f4d6e5c800 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -72,11 +72,12 @@ <!-- Should not see the discount yet because we have not filled in postcode --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid postcode --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Indiana" stepKey="fillState"/> <waitForPageLoad stepKey="waitForPostcode1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml index 1fad2f282fa5d..719e9bb95694e 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml @@ -106,6 +106,8 @@ <data name="productPrice/0/special" xsi:type="string">5</data> <data name="productPrice/0/sub_total" xsi:type="string">5</data> <data name="productPrice/0/regular" xsi:type="string">10</data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedCatalogPage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedProductPage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedShoppingCart" /> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php index 2ee6269c39d47..a0520e1c7ef8f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php @@ -67,7 +67,6 @@ function () { */ private function waitFormLoading() { - $this->_rootElement->click(); $this->browser->waitUntil( function () { return $this->browser->find($this->waitElement)->isVisible() ? null : true; From 091a065cddb39c0f8f4d6a324e3aaa7dcad20c8c Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 5 Nov 2018 16:19:47 -0600 Subject: [PATCH 1034/1415] MAGETWO-95212: block call to getCurrentUrl method is returning ajax request value - Static fix --- app/code/Magento/CatalogWidget/Block/Product/ProductsList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 6f1e22593452a..851f9e3fc5e94 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -435,7 +435,7 @@ public function getAddToCartUrl($product, $additional = []) return parent::getAddToCartUrl($product, $additional); } - /* + /** * Get widget block name * * @return string From 8df9f0208f93993a065ace2ee5e32612134898bb Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 6 Nov 2018 09:30:41 +0200 Subject: [PATCH 1035/1415] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepositoryTest.php | 63 ++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php index 15afc87405ffd..75dfcf7e8f2fd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php @@ -294,8 +294,6 @@ public function testUpdateCustomerPreserveAllAddresses() $customerId = 1; $customer = $this->customerRepository->getById($customerId); $customerDetails = $customer->__toArray(); - $defaultBilling = $customerDetails['default_billing']; - $defaultShipping = $customerDetails['default_shipping']; $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, @@ -307,19 +305,8 @@ public function testUpdateCustomerPreserveAllAddresses() $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); - $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are still present $this->assertEquals(2, count($newCustomerDetails->getAddresses())); - $this->assertEquals( - $defaultBilling, - $newCustomerArray['default_billing'], - "Default billing invalid value" - ); - $this->assertEquals( - $defaultShipping, - $newCustomerArray['default_shipping'], - "Default shipping invalid value" - ); } /** @@ -345,19 +332,51 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); - $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are removed $this->assertEquals(0, count($newCustomerDetails->getAddresses())); - $this->assertEquals( - $newCustomerArray['default_billing'], - null, - "Default billing invalid value" + } + + /** + * Test customer update with new address + * + * @magentoAppArea frontend + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testUpdateCustomerWithNewAddress() + { + $customerId = 1; + $customer = $this->customerRepository->getById($customerId); + $customerDetails = $customer->__toArray(); + unset($customerDetails['default_billing']); + unset($customerDetails['default_shipping']); + + $beforeSaveCustomer = $this->customerFactory->create(); + $this->dataObjectHelper->populateWithArray( + $beforeSaveCustomer, + $customerDetails, + CustomerInterface::class ); - $this->assertEquals( - $newCustomerArray['default_shipping'], - null, - "Default shipping invalid value" + + $addresses = $customer->getAddresses(); + $beforeSaveAddress = $addresses[0]->__toArray(); + unset($beforeSaveAddress['id']); + $newAddressDataObject = $this->addressFactory->create(); + $this->dataObjectHelper->populateWithArray( + $newAddressDataObject, + $beforeSaveAddress, + AddressInterface::class ); + + $beforeSaveCustomer->setAddresses([$newAddressDataObject]); + $this->customerRepository->save($beforeSaveCustomer); + + $newCustomer = $this->customerRepository->getById($customerId); + $newCustomerAddresses = $newCustomer->getAddresses(); + $addressId = $newCustomerAddresses[0]->getId(); + + $this->assertEquals($newCustomer->getDefaultBilling(), $addressId, "Default billing invalid value"); + $this->assertEquals($newCustomer->getDefaultShipping(), $addressId, "Default shipping invalid value"); } /** From fef5e974e8bdc75926b41f910d2356883367149b Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 6 Nov 2018 11:31:09 +0200 Subject: [PATCH 1036/1415] magento-engcom/magento2ce#2306: Code style fixes --- .../Model/Import/Uploader.php | 4 ++-- .../Block/Adminhtml/Edit/Tab/Orders.php | 6 +++--- .../Controller/Account/ForgotPassword.php | 4 +++- app/code/Magento/Swatches/Helper/Data.php | 19 +++++++++++++++++++ .../Framework/Cache/Backend/Memcached.php | 9 ++++++--- .../Magento/Framework/Filter/Template.php | 13 +++++++++++-- .../Setup/Module/I18n/Parser/Adapter/Html.php | 2 +- .../Setup/Module/I18n/Parser/Adapter/Js.php | 2 +- 8 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index 8dc551c407277..ae4be4a1e62b3 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -101,7 +101,7 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\Filesystem\File\ReadFactory $readFactory - * @param null $filePath + * @param null|string $filePath * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( @@ -353,7 +353,7 @@ protected function _moveFile($tmpPath, $destPath) } /** - * {@inheritdoc} + * @inheritdoc */ protected function chmod($file) { diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php index 5059d61eb3f7e..f2b8133e352ad 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php @@ -57,7 +57,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function _construct() { @@ -102,7 +102,7 @@ protected function _prepareCollection() } /** - * {@inheritdoc} + * @inheritdoc */ protected function _prepareColumns() { @@ -163,7 +163,7 @@ public function getRowUrl($row) } /** - * {@inheritdoc} + * @inheritdoc */ public function getGridUrl() { diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php index b94f1993053d4..cfa605580777c 100644 --- a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php +++ b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -11,6 +10,9 @@ use Magento\Framework\App\Action\Context; use Magento\Framework\View\Result\PageFactory; +/** + * Forgot Password controller + */ class ForgotPassword extends \Magento\Customer\Controller\AbstractAccount implements HttpGetActionInterface { /** diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index ac19ad5116cc3..d82109ac12603 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -132,6 +132,8 @@ public function __construct( } /** + * Assemble Additional Data for Eav Attribute + * * @param Attribute $attribute * @return $this */ @@ -181,6 +183,8 @@ private function isMediaAvailable(ModelProduct $product, string $attributeCode): } /** + * Load first variation + * * @param string $attributeCode swatch_image|image * @param ModelProduct $configurableProduct * @param array $requiredAttributes @@ -204,6 +208,8 @@ private function loadFirstVariation($attributeCode, ModelProduct $configurablePr } /** + * Load first variation with swatch image + * * @param Product $configurableProduct * @param array $requiredAttributes * @return bool|Product @@ -214,6 +220,8 @@ public function loadFirstVariationWithSwatchImage(Product $configurableProduct, } /** + * Load first variation with image + * * @param Product $configurableProduct * @param array $requiredAttributes * @return bool|Product @@ -269,6 +277,8 @@ public function loadVariationByFallback(Product $parentProduct, array $attribute } /** + * Add filter by attribute + * * @param ProductCollection $productCollection * @param array $attributes * @return void @@ -281,6 +291,8 @@ private function addFilterByAttributes(ProductCollection $productCollection, arr } /** + * Add filter by parent + * * @param ProductCollection $productCollection * @param integer $parentId * @return void @@ -299,6 +311,7 @@ private function addFilterByParent(ProductCollection $productCollection, $parent /** * Method getting full media gallery for current Product + * * Array structure: [ * ['image'] => 'http://url/pub/media/catalog/product/2/0/blabla.jpg', * ['mediaGallery'] => [ @@ -307,7 +320,9 @@ private function addFilterByParent(ProductCollection $productCollection, $parent * ..., * ] * ] + * * @param ModelProduct $product + * * @return array */ public function getProductMediaGallery(ModelProduct $product) @@ -339,6 +354,8 @@ public function getProductMediaGallery(ModelProduct $product) } /** + * Get all size images + * * @param string $imageFile * @return array */ @@ -476,6 +493,8 @@ private function setCachedSwatches(array $optionIds, array $swatches) } /** + * Add fallback options + * * @param array $fallbackValues * @param array $swatches * @return array diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index ff9413aa90fea..0621c63acbd86 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Cache\Backend; +/** + * Memcached cache model + */ class Memcached extends \Zend_Cache_Backend_Memcached implements \Zend_Cache_Backend_ExtendedInterface { /** @@ -46,7 +49,7 @@ public function __construct(array $options = []) * Returns ID of a specific chunk on the basis of data's ID * * @param string $id Main data's ID - * @param int $index Particular chunk number to return ID for + * @param int $index Particular chunk number to return ID for * @return string */ protected function _getChunkId($id, $index) @@ -58,7 +61,7 @@ protected function _getChunkId($id, $index) * Remove saved chunks in case something gone wrong (e.g. some chunk from the chain can not be found) * * @param string $id ID of data's info cell - * @param int $chunks Number of chunks to remove (basically, the number after '{splitted}|') + * @param int $chunks Number of chunks to remove (basically, the number after '{splitted}|') * @return null */ protected function _cleanTheMess($id, $chunks) @@ -103,7 +106,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false) * Load data from memcached, glue from several chunks if it was splitted upon save. * * @param string $id @see \Zend_Cache_Backend_Memcached::load() - * @param bool $doNotTestCacheValidity @see \Zend_Cache_Backend_Memcached::load() + * @param bool $doNotTestCacheValidity @see \Zend_Cache_Backend_Memcached::load() * @return bool|false|string */ public function load($id, $doNotTestCacheValidity = false) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index e0cbab450f6be..3e5f9bcf0bd27 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -10,6 +10,8 @@ namespace Magento\Framework\Filter; /** + * Template filter + * * @api */ class Template implements \Zend_Filter_Interface @@ -228,8 +230,9 @@ protected function afterFilter($value) } /** - * Adds a callback to run after main filtering has happened. Callback must accept a single argument and return - * a string of the processed value. + * Adds a callback to run after main filtering has happened. + * + * Callback must accept a single argument and return a string of the processed value. * * @param callable $afterFilterCallback * @return $this @@ -257,6 +260,8 @@ protected function resetAfterFilterCallbacks() } /** + * Get var directive + * * @param string[] $construction * @return string */ @@ -302,6 +307,8 @@ public function templateDirective($construction) } /** + * Get depend directive + * * @param string[] $construction * @return string */ @@ -320,6 +327,8 @@ public function dependDirective($construction) } /** + * If directive + * * @param string[] $construction * @return string */ diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index 6867944d95f8f..cf38fd70884f3 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -20,7 +20,7 @@ class Html extends AbstractAdapter const HTML_FILTER = "/i18n:\s?'(?<value>[^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/i"; /** - * {@inheritdoc} + * @inheritdoc */ protected function _parse() { diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 6b53a1a4c15b7..4678af60d63f0 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -11,7 +11,7 @@ class Js extends AbstractAdapter { /** - * {@inheritdoc} + * @inheritdoc */ protected function _parse() { From 46e06440229c51f35ff96123b575be4b21fa9f1e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 13:40:36 +0300 Subject: [PATCH 1037/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 3fb7e9ecc8b4b..88758d63d0148 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -47,6 +47,7 @@ define([ if (~~this.currentPage() === this.pages()) { return false; } + for (index; index < recordData.length; index++) { recordData[index].position = index + offset; } From 0a9977fe2b0810e01dd32557dafaa4a31f2a0e5e Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 13:03:24 +0200 Subject: [PATCH 1038/1415] GraphQL-174: Absolute image paths for Products --- .../Resolver/Product/ProductImage/Path.php | 45 ------ .../CatalogGraphQl/etc/schema.graphqls | 1 - .../GraphQl/Catalog/ProductImageTest.php | 139 ++++++++++++++++++ 3 files changed, 139 insertions(+), 46 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php deleted file mode 100644 index 249f1dc40b19a..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; - -use Magento\Catalog\Model\Product; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Returns product's image path - */ -class Path implements ResolverInterface -{ - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['image_type'])) { - throw new LocalizedException(__('"image_type" value should be specified')); - } - - if (!isset($value['model'])) { - throw new LocalizedException(__('"model" value should be specified')); - } - - /** @var Product $product */ - $product = $value['model']; - - $imagePath = $product->getData($value['image_type']); - return $imagePath; - } -} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index fb042c7e59c15..5efe37d8f91f6 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -351,7 +351,6 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { url: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Url") - path: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Path") label: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Label") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php new file mode 100644 index 0000000000000..dc7c4b1c03040 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php @@ -0,0 +1,139 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ProductImageTest extends GraphQlAbstract +{ + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithBaseImage() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + image { + url + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['image']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['image']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductWithoutBaseImage() + { + $this->markTestIncomplete('https://github.com/magento/graphql-ce/issues/239'); + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + image { + url + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + self::assertEquals('Simple Product', $response['products']['items'][0]['image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithSmallImage() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + small_image { + url + path + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['small_image']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['small_image']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['small_image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithThumbnail() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + thumbnail { + url + path + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['thumbnail']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['thumbnail']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['thumbnail']['label']); + } + + /** + * @param string $url + * @return bool + */ + private function checkImageExists(string $url): bool + { + $connection = curl_init($url); + curl_setopt($connection, CURLOPT_HEADER, true); + curl_setopt($connection, CURLOPT_NOBODY, true); + curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1); + curl_exec($connection); + $responseStatus = curl_getinfo($connection, CURLINFO_HTTP_CODE); + + return $responseStatus === 200 ? true : false; + } +} From 4803537b41f6ca2b059c2a64a3c2a03d7c9482e1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 6 Nov 2018 13:03:59 +0200 Subject: [PATCH 1039/1415] #13157 - Last Ordered Items block - bad js code --- .../Sales/view/frontend/web/js/view/last-ordered-items.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index 9897666653df9..74465128f8c72 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -5,8 +5,9 @@ define([ 'uiComponent', - 'Magento_Customer/js/customer-data' -], function (Component, customerData) { + 'Magento_Customer/js/customer-data', + 'underscore' +], function (Component, customerData, _) { 'use strict'; return Component.extend({ From 10fdcfc6edcc5fafe4f622da11cf4593045e2378 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 13:09:01 +0200 Subject: [PATCH 1040/1415] GraphQL-174: Absolute image paths for Products --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index c9f2e5264b951..791696b2fa29e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -299,8 +299,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() description gift_message_available id - image - image_label + image {url, label} meta_description meta_keyword meta_title From 67bc1628a1ee0e5f209fd9876279ece0bbc59fc4 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 6 Nov 2018 13:12:24 +0200 Subject: [PATCH 1041/1415] magento-engcom/magento2ce#2306: Code style fixes --- app/code/Magento/Customer/Model/Authentication.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Model/Authentication.php b/app/code/Magento/Customer/Model/Authentication.php index b0729647d7eec..6d228e30b8aa4 100644 --- a/app/code/Magento/Customer/Model/Authentication.php +++ b/app/code/Magento/Customer/Model/Authentication.php @@ -83,7 +83,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function processAuthenticationFailure($customerId) { @@ -120,7 +120,7 @@ public function processAuthenticationFailure($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function unlock($customerId) { @@ -152,7 +152,7 @@ protected function getMaxFailures() } /** - * {@inheritdoc} + * @inheritdoc */ public function isLocked($customerId) { @@ -161,7 +161,7 @@ public function isLocked($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function authenticate($customerId, $password) { From 3196ebc9ff78c7ec61211ee1e36ffe3865de4561 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 14:19:54 +0200 Subject: [PATCH 1042/1415] GraphQL-174: Absolute image paths for Products -- Update PAT scenario --- setup/performance-toolkit/benchmark.jmx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 8b295c9f5fc46..37e07d1319572 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -40763,7 +40763,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40820,7 +40820,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40896,7 +40896,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40965,7 +40965,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41025,7 +41025,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41085,7 +41085,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41145,7 +41145,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41214,7 +41214,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41301,7 +41301,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41368,7 +41368,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> From bfd8feb724a44beeee3945f06fc5946a1529b86d Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 15:24:28 +0300 Subject: [PATCH 1043/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 88758d63d0148..fbd134cdf29d8 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -54,7 +54,6 @@ define([ this.recordData(recordData); }, - /** * Update position for element after position from another page is entered * From c0c1d76192b57fe524d0b9d2672282221ea8b011 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 6 Nov 2018 14:07:03 +0100 Subject: [PATCH 1044/1415] Added checkout module dependency --- app/code/Magento/QuoteGraphQl/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index c9900dd5f3150..f0d2eea9bcaf6 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -6,6 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-quote": "*", + "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*" }, From 591168ed6ab3e62a374f5c32bc4e5fb8a406740e Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 6 Nov 2018 15:52:45 +0200 Subject: [PATCH 1045/1415] ENGCOM-3358: [Forwardport] Prevent rendering of 'Ship here' button to select a shipping item if it is already selected #18986 Fix function test. --- .../Test/Mftf/Section/CheckoutShippingMethodsSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml index ceb4505c79693..56ed42fbfbbea 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml @@ -14,7 +14,7 @@ <element name="shippingMethodRow" type="text" selector=".form.methods-shipping table tbody tr"/> <element name="checkShippingMethodByName" type="radio" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/..//input" parameterized="true"/> <element name="shippingMethodRowByName" type="text" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/.." parameterized="true"/> - <element name="shipHereButton" type="button" selector="//button[contains(@class, 'action-select-shipping-item')]/parent::div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> + <element name="shipHereButton" type="button" selector="//div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> <element name="shippingMethodLoader" type="button" selector="//div[contains(@class, 'checkout-shipping-method')]/following-sibling::div[contains(@class, 'loading-mask')]"/> </section> </sections> From c3b4a8078771dd6ba76b1d00d9709a37b81c7677 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 6 Nov 2018 15:00:00 +0100 Subject: [PATCH 1046/1415] Covered most cases except authorisation --- .../Quote/SetShippingMethodOnCartTest.php | 160 +++++++++++++++--- 1 file changed, 132 insertions(+), 28 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php index 64c7cbf9fd42e..932c8ac386c27 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -39,6 +39,9 @@ class SetShippingMethodOnCartTest extends GraphQlAbstract */ private $quoteIdToMaskedId; + /** + * @inheritdoc + */ protected function setUp() { $objectManager = Bootstrap::getObjectManager(); @@ -51,26 +54,139 @@ protected function setUp() /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php */ - public function testSetShippingOnCart() + public function testSetShippingMethodOnCart() { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; $this->quoteResource->load( $this->quote, 'test_order_1', 'reserved_order_id' ); + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + $response = $this->sendRequestWithToken($query); + + self::assertArrayHasKey('setShippingMethodsOnCart', $response); + self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); + self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); + $addressesInformation = $response['setShippingMethodsOnCart']['cart']['addresses']; + self::assertCount(2, $addressesInformation); + self::assertEquals( + $addressesInformation[0]['selected_shipping_method']['code'], + $shippingCarrierCode . '_' . $shippingMethodCode + ); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodWithWrongCartId() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $shippingAddressId = '1'; + $maskedQuoteId = 'invalid'; + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage("Could not find a cart with ID \"$maskedQuoteId\""); + $this->sendRequestWithToken($query); + } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetNonExistingShippingMethod() + { + $shippingCarrierCode = 'non'; + $shippingMethodCode = 'existing'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); $shippingAddress = $this->quote->getShippingAddress(); $shippingAddressId = $shippingAddress->getId(); $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $query = <<<QUERY + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage("Carrier with such method not found: $shippingCarrierCode, $shippingMethodCode"); + $this->sendRequestWithToken($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodWithNonExistingAddress() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $shippingAddressId = '-20'; + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage('The shipping address is missing. Set the address and try again.'); + $this->sendRequestWithToken($query); + } + + // TODO: TBD - add check for guest with attempt to set shipping method to the customer's shopping cart + + /** + * Generates query for setting the specified shipping method on cart + * + * @param string $maskedQuoteId + * @param string $shippingMethodCode + * @param string $shippingCarrierCode + * @param string $shippingAddressId + * @return string + */ + private function prepareMutationQuery( + string $maskedQuoteId, + string $shippingMethodCode, + string $shippingCarrierCode, + string $shippingAddressId + ) : string { + return <<<QUERY mutation { setShippingMethodsOnCart(input: { cart_id: "$maskedQuoteId", shipping_methods: [ { - shipping_method_code: "flatrate" - shipping_carrier_code: "flatrate" + shipping_method_code: "$shippingMethodCode" + shipping_carrier_code: "$shippingCarrierCode" cart_address_id: $shippingAddressId } ]}) { @@ -78,22 +194,6 @@ public function testSetShippingOnCart() cart { cart_id, addresses { - firstname - lastname - company - address_type - city - street - region { - code - label - } - postcode - country { - code - label - } - selected_shipping_method { code label @@ -104,17 +204,21 @@ public function testSetShippingOnCart() } QUERY; + } + + /** + * Sends a GraphQL request with using a bearer token + * + * @param string $query + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function sendRequestWithToken(string $query): array + { $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; - $response = $this->graphQlQuery($query, [], '', $headerMap); - - self::assertArrayHasKey('setShippingMethodsOnCart', $response); - self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); - self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); - // TODO: check shipping method code and description + return $this->graphQlQuery($query, [], '', $headerMap); } - - // TODO: cover all other cases } From ddb64a537e44cf54490485fa79c5873d6865551e Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 16:03:34 +0200 Subject: [PATCH 1047/1415] GraphQL-174: Absolute image paths for Products -- Fix static tests --- .../Model/Resolver/Product/ProductImage/Label.php | 2 ++ .../CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php index e9020c2df5333..f971e35742628 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -80,6 +80,8 @@ public function resolve( } /** + * Get attribute value + * * @param int $productId * @param string $attributeCode * @return null|string Null if attribute value is not exists diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php index c6659080ee9e9..3c19ce599a9b3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -60,6 +60,8 @@ public function resolve( } /** + * Get image url + * * @param string $imageType * @param string|null $imagePath Null if image is not set * @return string From 32baeb40f1fdc3842bfa2c8c8b95a7c74ddf8ed5 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 16:26:50 +0200 Subject: [PATCH 1048/1415] GraphQL-174: Absolute image paths for Products -- Fix API-functional tests --- .../testsuite/Magento/GraphQl/Catalog/CategoryTest.php | 7 +++---- .../testsuite/Magento/GraphQl/Catalog/ProductImageTest.php | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index cc91ba7ed399d..a3c6298c70a53 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -141,8 +141,7 @@ public function testCategoryProducts() available_sort_by level } - image { url, path, label } - image_label + image { url, label } meta_description meta_keyword meta_title @@ -225,8 +224,8 @@ public function testCategoryProducts() } short_description sku - small_image { url, path, label } - thumbnail { url, path, label } + small_image { url, label } + thumbnail { url, label } special_from_date special_price special_to_date diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php index dc7c4b1c03040..b55c6c1d91460 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php @@ -81,7 +81,6 @@ public function testProductWithSmallImage() items { small_image { url - path label } } @@ -107,7 +106,6 @@ public function testProductWithThumbnail() items { thumbnail { url - path label } } From 1320b9d45115831588cb8396fba9171304b27fb3 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Thu, 25 Oct 2018 14:26:50 +0300 Subject: [PATCH 1049/1415] MAGETWO-95816: Invoice PDF contain different address when use arabic symbols - Reverse text with Arabic characters --- .../Sales/Model/Order/Pdf/AbstractPdf.php | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php index 85e34f560bb7b..8cdc90972bbb0 100644 --- a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php +++ b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php @@ -363,6 +363,38 @@ protected function _calcAddressHeight($address) return $y; } + /** + * Detect an input string is Arabic + * + * @param string $subject + * @return bool + */ + private function isArabic(string $subject): bool + { + return (preg_match('/\p{Arabic}/u', $subject) > 0); + } + + /** + * Reverse text with Arabic characters + * + * @param string $string + * @return string + */ + private function reverseArabicText($string) + { + $splitText = explode(' ', $string); + for ($i = 0; $i < count($splitText); $i++) { + if ($this->isArabic($splitText[$i])) { + for ($j = $i + 1; $j < count($splitText); $j++) { + $tmp = $this->string->strrev($splitText[$j]); + $splitText[$j] = $this->string->strrev($splitText[$i]); + $splitText[$i] = $tmp; + } + } + } + return implode(' ', $splitText); + } + /** * Insert order to pdf page * @@ -474,7 +506,7 @@ protected function insertOrder(&$page, $obj, $putOrderId = true) if ($value !== '') { $text = []; foreach ($this->string->split($value, 45, true, true) as $_value) { - $text[] = $_value; + $text[] = ($this->isArabic($_value)) ? $this->reverseArabicText($_value) : $_value; } foreach ($text as $part) { $page->drawText(strip_tags(ltrim($part)), 35, $this->y, 'UTF-8'); @@ -491,7 +523,7 @@ protected function insertOrder(&$page, $obj, $putOrderId = true) if ($value !== '') { $text = []; foreach ($this->string->split($value, 45, true, true) as $_value) { - $text[] = $_value; + $text[] = ($this->isArabic($_value)) ? $this->reverseArabicText($_value) : $_value; } foreach ($text as $part) { $page->drawText(strip_tags(ltrim($part)), 285, $this->y, 'UTF-8'); From 5934b231fe89fde967936124f714b929f2a1aada Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 17:38:53 +0300 Subject: [PATCH 1050/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../adminhtml/web/js/grouped-product-grid.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index fbd134cdf29d8..9cb0a00dc9521 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -57,8 +57,8 @@ define([ /** * Update position for element after position from another page is entered * - * @param data - * @param event + * @param {Object} data + * @param {Object} event */ updateGridPosition: function (data, event) { var inputValue = parseInt(event.target.value, 10), @@ -102,8 +102,8 @@ define([ /** * Get updated record index * - * @param recordData - * @param recordId + * @param {Array} recordData + * @param {Number} recordId * @return {number} */ getUpdatedRecordIndex: function (recordData, recordId) { @@ -114,7 +114,7 @@ define([ /** * - * @param recordData to reprocess + * @param {Array} recordData to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { @@ -127,7 +127,7 @@ define([ /** * Event handler for "Send to bottom" button * - * @param positionObj + * @param {Object} positionObj * @return {boolean} */ sendToBottom: function (positionObj) { @@ -151,7 +151,7 @@ define([ /** * Event handler for "Send to top" button * - * @param positionObj + * @param {Object} positionObj * @returns {boolean} */ sendToTop: function (positionObj) { @@ -176,7 +176,7 @@ define([ /** * Get element from grid for update * - * @param object + * @param {Object} object * @return {*} */ getObjectToUpdate: function (object) { @@ -188,7 +188,7 @@ define([ /** * Value function for position input * - * @param data + * @param {Object} data * @return {number} */ getCalculatedPosition: function (data) { From 9badfbde6544b9cc4339316903c073551dac6ac5 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Tue, 6 Nov 2018 17:15:59 +0200 Subject: [PATCH 1051/1415] MAGETWO-95539: [2.3] Moving Category generate duplicate url_rewrite when 4th level category exist and is translated - Fixed url rewrites regeneration after category moving --- .../Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php index 8147818135edc..a2767f76cfecb 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php @@ -85,6 +85,7 @@ public function test(Store $storeView, Category $childCategory, Category $parent $this->catalogCategoryEdit->getFormPageActions()->selectStoreView($storeView->getName()); $this->catalogCategoryEdit->getEditForm()->fill($categoryUpdates); $this->catalogCategoryEdit->getFormPageActions()->save(); + $this->catalogCategoryEdit->getFormPageActions()->selectStoreView('All Store Views'); $this->catalogCategoryIndex->getTreeCategories()->assignCategory( $parentCategory->getName(), $childCategory->getName() From bf5ad21fc451c17b496f5a24280600e5c66c1aba Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 18:36:03 +0300 Subject: [PATCH 1052/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 9cb0a00dc9521..c06f615ae48e6 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -104,7 +104,7 @@ define([ * * @param {Array} recordData * @param {Number} recordId - * @return {number} + * @return {Number} */ getUpdatedRecordIndex: function (recordData, recordId) { return recordData.map(function (o) { From 418d0cabbe129eb0fcc9cf793213de7217292be8 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 11:18:38 -0600 Subject: [PATCH 1053/1415] MAGETWO-95745: Signifyd case not created for WorldPay --- app/code/Magento/Checkout/Controller/Onepage/Success.php | 5 ++++- app/code/Magento/Signifyd/etc/events.xml | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Onepage/Success.php b/app/code/Magento/Checkout/Controller/Onepage/Success.php index 7db5cd8f012c7..e0872b425cc7c 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/Success.php +++ b/app/code/Magento/Checkout/Controller/Onepage/Success.php @@ -26,7 +26,10 @@ public function execute() $resultPage = $this->resultPageFactory->create(); $this->_eventManager->dispatch( 'checkout_onepage_controller_success_action', - ['order_ids' => [$session->getLastOrderId()]] + [ + 'order_ids' => [$session->getLastOrderId()], + 'order' => $session->getLastRealOrder() + ] ); return $resultPage; } diff --git a/app/code/Magento/Signifyd/etc/events.xml b/app/code/Magento/Signifyd/etc/events.xml index d5ba6e5a99227..e6418e2fdb6b4 100644 --- a/app/code/Magento/Signifyd/etc/events.xml +++ b/app/code/Magento/Signifyd/etc/events.xml @@ -15,4 +15,7 @@ <event name="paypal_checkout_success"> <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> + <event name="checkout_onepage_controller_success_action"> + <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> + </event> </config> From 25fd4670c9988c7fe7b365f077f25dfa6d01839a Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 19:19:55 +0200 Subject: [PATCH 1054/1415] GraphQl-45: Product textarea field format --- .../Product/ProductComplexTextAttribute.php | 2 +- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ----- app/code/Magento/GraphQl/etc/schema.graphqls | 2 +- .../Magento/GraphQl/Catalog/CategoryTest.php | 8 +- .../Catalog/ProductTextAttributesTest.php | 142 ++++++++++++++++++ .../GraphQl/Catalog/ProductViewTest.php | 34 ----- .../ProductWithDescriptionDirectivesTest.php | 65 -------- 7 files changed, 150 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index 7cf7225d0f61c..96519d6191eee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -52,6 +52,6 @@ public function resolve( $fieldName = $field->getName(); $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return ['html' => $renderedValue]; + return ['html' => $renderedValue ?? '']; } } diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php deleted file mode 100644 index fffca765faba6..0000000000000 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\GraphQl\Model\Resolver\ComplexTextValue; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * HTML format for complex text value. - * - * Initially, a value from parent resolver should be in HTML format, therefore, there is no any customization. - */ -class HtmlFormat implements ResolverInterface -{ - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): ?string { - if (!isset($value['html'])) { - throw new GraphQlInputException(__('"html" value should be specified')); - } - - return $value['html']; - } -} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index 991c320860622..2281495d059e1 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -38,5 +38,5 @@ enum SortEnum @doc(description: "This enumeration indicates whether to return re } type ComplexTextValue { - html: String! @doc(description: "HTML format") @resolver(class: "\\Magento\\GraphQl\\Model\\Resolver\\ComplexTextValue\\HtmlFormat") + html: String! @doc(description: "HTML format") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index eff2e96f4b112..adc3a58e4f8dc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -132,7 +132,9 @@ public function testCategoryProducts() attribute_set_id country_of_manufacture created_at - description + description { + html + } gift_message_available id categories { @@ -223,7 +225,9 @@ public function testCategoryProducts() position sku } - short_description + short_description { + html + } sku small_image { path diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php new file mode 100644 index 0000000000000..999e1cc7fca3d --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php @@ -0,0 +1,142 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ProductTextAttributesTest extends GraphQlAbstract +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + protected function setUp() + { + $this->productRepository = Bootstrap::getObjectManager()::getInstance()->get(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductTextAttributes() + { + $productSku = 'simple'; + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) + { + items { + sku + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + 'Short description', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + 'Description with <b>html tag</b>', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + */ + public function testProductWithoutFilledTextAttributes() + { + $productSku = 'virtual-product'; + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) + { + items { + sku + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * Test for checking that product fields with directives allowed are rendered correctly + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @magentoApiDataFixture Magento/Cms/_files/block.php + */ + public function testHtmlDirectivesRendering() + { + $productSku = 'simple'; + $cmsBlockId = 'fixture_block'; + $assertionCmsBlockText = 'Fixture Block Title'; + + $product = $this->productRepository->get($productSku, false, null, true); + $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['description']['html']); + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']['html']); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 0ec63374be869..a3d0bb28da14a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,9 +44,6 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description { - html - } gift_message_available id categories { @@ -205,9 +202,6 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description { - html - } sku small_image { path @@ -266,7 +260,6 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -306,7 +299,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } country_of_manufacture created_at - description gift_message_available id image @@ -457,7 +449,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() position sku } - short_description sku small_image { path @@ -947,31 +938,6 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } - /** - * @param ProductInterface $product - * @param array $actualResponse - */ - private function assertComplexTextAttributes($product, $actualResponse) - { - $eavAttributes = [ - 'description', - 'short_description', - ]; - $assertionMap = []; - foreach ($eavAttributes as $attributeCode) { - $expectedAttribute = $product->getCustomAttribute($attributeCode); - - $assertionMap[] = [ - 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), - 'expected_value' => $expectedAttribute ? [ - 'html' => $expectedAttribute->getValue() - ] : null - ]; - } - - $this->assertResponseFields($actualResponse, $assertionMap); - } - /** * @param string $eavAttributeCode * @return string diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php deleted file mode 100644 index 8e9bc4dfa2825..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\GraphQl\Catalog; - -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\TestFramework\ObjectManager; -use Magento\TestFramework\TestCase\GraphQlAbstract; - -/** - * Test for checking that product fields with directives allowed are rendered correctly - */ -class ProductWithDescriptionDirectivesTest extends GraphQlAbstract -{ - /** - * @var \Magento\TestFramework\ObjectManager - */ - private $objectManager; - - protected function setUp() - { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php - * @magentoApiDataFixture Magento/Cms/_files/block.php - */ - public function testHtmlDirectivesRendered() - { - $productSku = 'simple'; - $cmsBlockId = 'fixture_block'; - $assertionCmsBlockText = 'Fixture Block Title'; - - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - /** @var ProductInterface $product */ - $product = $productRepository->get($productSku, false, null, true); - $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $productRepository->save($product); - - $query = <<<QUERY -{ - products(filter: {sku: {eq: "{$productSku}"}}) { - items { - description - short_description - } - } -} -QUERY; - $response = $this->graphQlQuery($query); - - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['description']); - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']); - } -} From 7c21b3b31e5f330e698d6a766cb45e90cf61a3f3 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 6 Nov 2018 20:36:45 +0200 Subject: [PATCH 1055/1415] graphQl: removed set shipping addresses chain, using di preference instead --- ...essor.php => SetShippingAddressOnCart.php} | 9 ++-- .../Model/Cart/SetShippingAddressesOnCart.php | 49 ------------------- app/code/Magento/QuoteGraphQl/composer.json | 4 +- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 9 +--- .../Quote/SetShippingAddressOnCartTest.php | 46 +++++++++++++++++ 5 files changed, 55 insertions(+), 62 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/Cart/{SetShippingAddressesOnCart/SingleShippingAddressProcessor.php => SetShippingAddressOnCart.php} (92%) delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php similarity index 92% rename from app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 41675716c68bf..588d4f65cc565 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart; +namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -16,12 +16,11 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; -use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** * Set single shipping address for a specified shopping cart */ -class SingleShippingAddressProcessor implements SetShippingAddressesOnCartInterface +class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface { /** * @var ShippingAddressManagementInterface @@ -59,7 +58,9 @@ public function __construct( public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { - return; + throw new GraphQlInputException( + __('Multiple addresses do not allowed here!') + ); } $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php deleted file mode 100644 index 8ebcdef1f549a..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Cart; - -use InvalidArgumentException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Quote\Api\Data\CartInterface; - -/** - * Set shipping addresses for shopping cart processors chain - */ -class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface -{ - /** - * @var SetShippingAddressesOnCartInterface[] - */ - private $shippingAddressProcessors; - - /** - * @param array $shippingAddressProcessors - */ - public function __construct( - array $shippingAddressProcessors - ) { - $this->shippingAddressProcessors = $shippingAddressProcessors; - } - - /** - * @inheritdoc - */ - public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void - { - foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { - if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { - throw new InvalidArgumentException( - get_class($shippingAddressProcessor) . - ' is not instance of \Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface.' - ); - } - - $shippingAddressProcessor->execute($context, $cart, $shippingAddresses); - } - } -} diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 485c958718bf3..b3433fdc8fea6 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -8,7 +8,9 @@ "magento/module-quote": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-checkout": "*" + "magento/module-checkout": "*", + "magento/module-customer": "*", + "magento/module-authorization": "*" }, "suggest": { "magento/module-graph-ql": "*" diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index f28d484fa0f6f..e7417d657a0ea 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -7,14 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" - type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart" /> - <type name="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface"> - <arguments> - <argument name="shippingAddressProcessors" xsi:type="array"> - <item name="singleShippingAddress" xsi:type="object">Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart\SingleShippingAddressProcessor</item> - </argument> - </arguments> - </type> + type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart" /> <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> <arguments> <argument name="specifications" xsi:type="array"> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 9771dbbf84c48..48ef8ebb790d1 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -143,6 +143,52 @@ public function testSetSavedShippingAddressOnCartByGuest() $this->graphQlQuery($query); } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoConfigFixture default_store multishipping/options/checkout_multiple 0 + */ + public function testSetMultipleShippingAddressesOnCartByGuest() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + }, + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage('Multiple addresses do not allowed here!'); + $this->graphQlQuery($query); + } + /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php */ From c8578575c498690cd672764c374ddafec18dcc90 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 6 Nov 2018 20:38:08 +0200 Subject: [PATCH 1056/1415] graphQl: fixed composer json --- app/code/Magento/QuoteGraphQl/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 05575ef371600..9d29cda3b872b 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,7 +9,6 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-checkout": "*", "magento/module-customer": "*", "magento/module-authorization": "*" }, From 2095d836b5fc31dac949b37dad31fd6973fea406 Mon Sep 17 00:00:00 2001 From: Dmytro Salamatov <sal.dima27@gmail.com> Date: Tue, 6 Nov 2018 00:11:18 +0200 Subject: [PATCH 1057/1415] magento/magento2#19071: Password strength indicator shows No Password even when a password is entered --- .../view/frontend/web/js/password-strength-indicator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js b/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js index 89d9b320c049d..9742e37f2df57 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js +++ b/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js @@ -83,7 +83,7 @@ define([ } else { isValid = $.validator.validateSingleElement(this.options.cache.input); zxcvbnScore = zxcvbn(password).score; - displayScore = isValid ? zxcvbnScore : 1; + displayScore = isValid && zxcvbnScore > 0 ? zxcvbnScore : 1; } } From 8aafa54f3356a8d361231cf3d84e19f80ef076c0 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 6 Nov 2018 14:41:16 -0600 Subject: [PATCH 1058/1415] ENGCOM-3368: fixed - can't import external http to https redirecting images by default csv import #18900 - Fixed docblock --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index e43f35b072f1d..3668bd17477a4 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -12,7 +12,6 @@ /** * Class Http - * */ class Http extends File { From a58147333b285ed746a9b516d9bc6561c289010d Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 6 Nov 2018 15:15:52 -0600 Subject: [PATCH 1059/1415] MQE-1339: Bump MFTF version in Magento - MFTF version upgrade to 2.3.10 --- composer.json | 2 +- composer.lock | 168 +++++++++++++++++++++++++------------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/composer.json b/composer.json index ca345c1897412..0a2716489d6c9 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.9", + "magento/magento2-functional-testing-framework": "2.3.10", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index c6d14eb38bc64..ab0c8f2bf8973 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49fe82043cd4ae944939b6cceade1d1b", + "content-hash": "52b81b57603c71ff946453178068a064", "packages": [ { "name": "braintree/braintree_php", @@ -257,16 +257,16 @@ }, { "name": "composer/composer", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", + "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", "shasum": "" }, "require": { @@ -333,7 +333,7 @@ "dependency", "package" ], - "time": "2018-08-16T14:57:12+00:00" + "time": "2018-11-01T09:05:06+00:00" }, { "name": "composer/semver", @@ -399,16 +399,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", "shasum": "" }, "require": { @@ -456,7 +456,7 @@ "spdx", "validator" ], - "time": "2018-04-30T10:33:04+00:00" + "time": "2018-11-01T09:45:54+00:00" }, { "name": "composer/xdebug-handler", @@ -919,16 +919,16 @@ }, { "name": "monolog/monolog", - "version": "1.23.0", + "version": "1.24.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", "shasum": "" }, "require": { @@ -993,7 +993,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2018-11-05T09:00:11+00:00" }, { "name": "oyejorge/less.php", @@ -1375,16 +1375,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.11", + "version": "2.0.12", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", "shasum": "" }, "require": { @@ -1463,7 +1463,7 @@ "x.509", "x509" ], - "time": "2018-04-15T16:55:05+00:00" + "time": "2018-11-04T05:45:48+00:00" }, { "name": "psr/container", @@ -1834,16 +1834,16 @@ }, { "name": "symfony/console", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" + "reference": "432122af37d8cd52fba1b294b11976e0d20df595" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", + "reference": "432122af37d8cd52fba1b294b11976e0d20df595", "shasum": "" }, "require": { @@ -1898,20 +1898,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:15:46+00:00" + "time": "2018-10-31T09:30:44+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + "reference": "552541dad078c85d9414b09c041ede488b456cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", + "reference": "552541dad078c85d9414b09c041ede488b456cd5", "shasum": "" }, "require": { @@ -1961,20 +1961,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-07-26T09:10:45+00:00" + "time": "2018-10-10T13:52:42+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", "shasum": "" }, "require": { @@ -2011,11 +2011,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-30T13:18:25+00:00" }, { "name": "symfony/finder", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2064,7 +2064,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2122,16 +2122,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -2177,20 +2177,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/process", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529" + "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529", + "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", + "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", "shasum": "" }, "require": { @@ -2226,7 +2226,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-14T20:48:13+00:00" }, { "name": "tedivm/jshrink", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.9", + "version": "2.3.10", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84" + "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9885925ea741d0b0eede35be09a45b62d9ef7c84", - "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/7cd80dbf1af405473f1a976c3b75097a0f27725d", + "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-10-28T11:19:53+00:00" + "time": "2018-11-06T20:54:16+00:00" }, { "name": "moontoast/math", @@ -8228,7 +8228,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -8285,16 +8285,16 @@ }, { "name": "symfony/config", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96" + "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96", - "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", "shasum": "" }, "require": { @@ -8344,11 +8344,11 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-09-08T13:24:10+00:00" + "time": "2018-10-31T09:09:42+00:00" }, { "name": "symfony/css-selector", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -8401,16 +8401,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30" + "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30", - "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483", + "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483", "shasum": "" }, "require": { @@ -8468,11 +8468,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-31T10:54:16+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -8529,16 +8529,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d528136617ff24f530e70df9605acc1b788b08d4" + "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4", - "reference": "d528136617ff24f530e70df9605acc1b788b08d4", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", "shasum": "" }, "require": { @@ -8579,11 +8579,11 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:48:45+00:00" + "time": "2018-10-31T09:09:42+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -8637,16 +8637,16 @@ }, { "name": "symfony/polyfill-php70", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", "shasum": "" }, "require": { @@ -8692,20 +8692,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T06:26:08+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", "shasum": "" }, "require": { @@ -8747,11 +8747,11 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -8800,7 +8800,7 @@ }, { "name": "symfony/yaml", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", From dda4f8af9ba60997cb7b78fcd7afe61f988b444b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 15:56:34 -0600 Subject: [PATCH 1060/1415] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest - address code review comments --- .../Test/Constraint/AssertCartIsEmpty.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php index 22a6136737089..cf05079b0a079 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Checkout\Test\Constraint; @@ -29,8 +30,10 @@ class AssertCartIsEmpty extends AbstractConstraint * @param BrowserInterface $browser * @return void */ - public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $browser) - { + public function processAssert( + CheckoutCart $checkoutCart, + BrowserInterface $browser + ): void { $checkoutCart->open(); $cartEmptyBlock = $checkoutCart->getCartEmptyBlock(); @@ -46,7 +49,7 @@ public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $brow $browser->getUrl(), true, 'Wrong link to main page on empty cart page: expected - ' . $_ENV['app_frontend_url'] - . ', actural - ' . $browser->getUrl() + . ', actual - ' . $browser->getUrl() ); } @@ -63,14 +66,18 @@ public function toString() /** * Asserts that two urls are equal * - * @param string $url1 - * @param string $url2 + * @param string $expectedUrl + * @param string $actualUrl * @param bool $ignoreScheme * @param string $message * @return void */ - private function assertUrlEqual($expectedUrl, $actualUrl, $ignoreScheme = false, $message = '') - { + private function assertUrlEqual( + string $expectedUrl, + string $actualUrl, + bool $ignoreScheme = false, + string $message = '' + ): void { $urlArray1 = parse_url($expectedUrl); $urlArray2 = parse_url($actualUrl); if ($ignoreScheme) { From cf824bcda59d97d2890b64a56a72cbb2f71e89ce Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Wed, 7 Nov 2018 12:33:59 +0400 Subject: [PATCH 1061/1415] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Moved test from CE to EE. --- .../Test/Mftf/Data/CheckoutConfigData.xml | 25 ------ .../Mftf/Metadata/checkout_config-meta.xml | 86 ------------------- .../CheckoutTotalsSortOrderInCartTest.xml | 52 ----------- 3 files changed, 163 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml deleted file mode 100644 index bf2ae28009011..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="CheckoutShippingTotalsSortOrder" type="checkout_totals_sort_order"> - <requiredEntity type="shipping">ShippingTotalsSortOrder</requiredEntity> - </entity> - - <entity name="ShippingTotalsSortOrder" type="shipping"> - <data key="value">27</data> - </entity> - - <entity name="DefaultCheckoutTotalsSortOrder" type="default_checkout_totals_sort_order"> - <requiredEntity type="checkoutTotalFlagZero">DefaultTotalFlagZero</requiredEntity> - </entity> - <entity name="DefaultTotalFlagZero" type="checkoutTotalFlagZero"> - <data key="value">0</data> - </entity> -</entities> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml deleted file mode 100644 index 55572ee73ac46..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml +++ /dev/null @@ -1,86 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> - <operation name="SetCheckoutTotalsSortOrder" dataType="checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="checkout_totals_sort_order"> - <object key="totals_sort" dataType="checkout_totals_sort_order"> - <object key="fields" dataType="checkout_totals_sort_order"> - <object key="subtotal" dataType="subtotal"> - <field key="value">integer</field> - </object> - <object key="discount" dataType="discount"> - <field key="value">integer</field> - </object> - <object key="shipping" dataType="shipping"> - <field key="value">integer</field> - </object> - <object key="tax" dataType="tax"> - <field key="value">integer</field> - </object> - <object key="weee" dataType="weee"> - <field key="value">integer</field> - </object> - <object key="grand_total" dataType="grand_total"> - <field key="value">integer</field> - </object> - <object key="giftcardaccount" dataType="giftcardaccount"> - <field key="value">integer</field> - </object> - <object key="customerbalance" dataType="customerbalance"> - <field key="value">integer</field> - </object> - </object> - </object> - </object> - </operation> - - <operation name="DefaultCheckoutTotalsSortOrder" dataType="default_checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="default_checkout_totals_sort_order"> - <object key="totals_sort" dataType="default_checkout_totals_sort_order"> - <object key="fields" dataType="default_checkout_totals_sort_order"> - <object key="subtotal" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="discount" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="shipping" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="tax" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="weee" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="grand_total" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="giftcardaccount" dataType="giftcardaccount"> - <field key="value">integer</field> - </object> - <object key="customerbalance" dataType="customerbalance"> - <field key="value">integer</field> - </object> - </object> - </object> - </object> - </operation> -</operations> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml deleted file mode 100644 index 08623da68a8ef..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="CheckoutTotalsSortOrderInCartTest"> - <annotations> - <title value="Checkout Totals Sort Order configuration and displaying in cart"/> - <stories value="MAGETWO-91658: Wrong Checkout Totals Sort Order in cart"/> - <description value="Checkout Totals Sort Order configuration and displaying in cart"/> - <features value="Checkout"/> - <severity value="AVERAGE"/> - <testCaseId value="MAGETWO-94944"/> - <group value="Checkout"/> - </annotations> - - <before> - <createData entity="_defaultCategory" stepKey="defaultCategory"/> - <createData entity="SimpleProduct" stepKey="simpleProduct"> - <requiredEntity createDataKey="defaultCategory"/> - </createData> - - <createData entity="ApiCartRule" stepKey="cartRule"/> - - <createData entity="CheckoutShippingTotalsSortOrder" stepKey="setConfigShippingTotalsSortOrder"/> - </before> - - <actionGroup ref="VerifyDiscountAmount" stepKey="verifyStorefront"> - <argument name="productUrl" value="$$simpleProduct.sku$$.html"/> - <argument name="quantity" value="1"/> - <argument name="expectedDiscount" value="-$61.50"/> - </actionGroup> - - <actionGroup ref="CheckTotalsSortOrderInSummarySection" stepKey="checkTotalsSortOrderInSummarySection"> - <argument name="elementName" value="Shipping (Flat Rate - Fixed)"/> - <argument name="positionNumber" value="3"/> - </actionGroup> - - <after> - <createData entity="DefaultCheckoutTotalsSortOrder" stepKey="setDefaultTotalsSortOrder"/> - - <deleteData createDataKey="cartRule" stepKey="deleteCartRule"/> - <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> - <deleteData createDataKey="defaultCategory" stepKey="deleteCategory"/> - - <magentoCLI command="cache:flush" stepKey="flushCache"/> - </after> - </test> -</tests> \ No newline at end of file From c62229f1342448ad693ae070bf57e3d819921290 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Wed, 7 Nov 2018 12:41:13 +0200 Subject: [PATCH 1062/1415] MAGETWO-94052: CAPTCHA does not appear in "Log in" popup window - Added sleep for MTF test --- .../Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php index d951d84bab78d..d16da19cfe8b8 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php @@ -107,6 +107,7 @@ private function processLogin() if ($this->checkoutMethod === 'login') { if ($this->checkoutOnepage->getAuthenticationPopupBlock()->isVisible()) { $this->checkoutOnepage->getAuthenticationPopupBlock()->loginCustomer($this->customer); + sleep(5); $this->clickProceedToCheckoutStep->run(); } else { $this->checkoutOnepage->getLoginBlock()->loginCustomer($this->customer); From f631c90376dd2d217686e781147cc707bd816c8f Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 7 Nov 2018 14:36:22 +0200 Subject: [PATCH 1063/1415] magento/magento2#12970: [Forwardport] Can't add grouped product, with out of stock sub product, to cart. --- .../Model/Product/Type/Grouped.php | 2 +- .../_files/product_virtual_out_of_stock.php | 20 ++ .../product_virtual_out_of_stock_rollback.php | 26 +++ .../Model/Product/Type/GroupedTest.php | 194 ++++++++++++++++-- .../product_grouped_with_out_of_stock.php | 75 +++++++ ...uct_grouped_with_out_of_stock_rollback.php | 10 + 6 files changed, 311 insertions(+), 16 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index 80824d45cb6e5..56de9ee9552ae 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -347,7 +347,7 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr if ($isStrictProcessMode && !$subProduct->getQty()) { return __('Please specify the quantity of product(s).')->render(); } - $productsInfo[$subProduct->getId()] = (int)$subProduct->getQty(); + $productsInfo[$subProduct->getId()] = $subProduct->isSalable() ? (float)$subProduct->getQty() : 0; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php new file mode 100644 index 0000000000000..cff2e83ed002e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL) + ->setId(31) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Virtual Product Out') + ->setSku('virtual-product-out') + ->setPrice(10) + ->setTaxClassId(0) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['is_in_stock' => 0]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php new file mode 100644 index 0000000000000..8055ca4a25569 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +try { + $product = $productRepository->get('virtual-product-out', false, null, true); + $productRepository->delete($product); +} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) { + //Product already removed +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php index dcf4565873ea5..ed283d196e69c 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php @@ -5,8 +5,19 @@ */ namespace Magento\GroupedProduct\Model\Product\Type; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Model\Configuration; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\App\Config\Value; + class GroupedTest extends \PHPUnit\Framework\TestCase { + /** + * @var ReinitableConfigInterface + */ + private $reinitableConfig; + /** * @var \Magento\Framework\ObjectManagerInterface */ @@ -20,16 +31,21 @@ class GroupedTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->_productType = $this->objectManager->get(\Magento\Catalog\Model\Product\Type::class); + $this->reinitableConfig = $this->objectManager->get(ReinitableConfigInterface::class); + } + + protected function tearDown() + { + $this->dropConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK); } public function testFactory() { $product = new \Magento\Framework\DataObject(); - $product->setTypeId(\Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE); + $product->setTypeId(Grouped::TYPE_CODE); $type = $this->_productType->factory($product); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); } /** @@ -38,12 +54,12 @@ public function testFactory() */ public function testGetAssociatedProducts() { - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product */ + /** @var Product $product */ $product = $productRepository->get('grouped-product'); $type = $product->getTypeInstance(); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); $associatedProducts = $type->getAssociatedProducts($product); $this->assertCount(2, $associatedProducts); @@ -53,7 +69,7 @@ public function testGetAssociatedProducts() } /** - * @param \Magento\Catalog\Model\Product $product + * @param Product $product */ private function assertProductInfo($product) { @@ -92,25 +108,25 @@ public function testPrepareProduct() \Magento\Framework\DataObject::class, ['data' => ['value' => ['qty' => 2]]] ); - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); $product = $productRepository->get('grouped-product'); - /** @var \Magento\GroupedProduct\Model\Product\Type\Grouped $type */ - $type = $this->objectManager->get(\Magento\GroupedProduct\Model\Product\Type\Grouped::class); + /** @var Grouped $type */ + $type = $this->objectManager->get(Grouped::class); $processModes = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL, - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE + Grouped::PROCESS_MODE_FULL, + Grouped::PROCESS_MODE_LITE ]; $expectedData = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL => [ + Grouped::PROCESS_MODE_FULL => [ 1 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', 21 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', ], - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE => [ + Grouped::PROCESS_MODE_LITE => [ $product->getId() => '{"value":{"qty":2}}', ] ]; @@ -127,4 +143,152 @@ public function testPrepareProduct() } } } + + /** + * Test adding grouped product to cart when one of subproducts is out of stock. + * + * @magentoDataFixture Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @dataProvider outOfStockSubProductDataProvider + * @param bool $outOfStockShown + * @param array $data + * @param array $expected + */ + public function testOutOfStockSubProduct(bool $outOfStockShown, array $data, array $expected) + { + $this->changeConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK, $outOfStockShown); + $buyRequest = new \Magento\Framework\DataObject($data); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + /** @var Product $product */ + $product = $productRepository->get('grouped-product'); + /** @var Grouped $groupedProduct */ + $groupedProduct = $this->objectManager->get(Grouped::class); + $actual = $groupedProduct->prepareForCartAdvanced($buyRequest, $product, Grouped::PROCESS_MODE_FULL); + self::assertEquals( + count($expected), + count($actual) + ); + /** @var Product $product */ + foreach ($actual as $product) { + $sku = $product->getSku(); + self::assertEquals( + $expected[$sku], + $product->getCartQty(), + "Failed asserting that Product Cart Quantity matches expected" + ); + } + } + + /** + * Data provider for testOutOfStockSubProduct. + * + * @return array + */ + public function outOfStockSubProductDataProvider() + { + return [ + 'Out of stock product are shown #1' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4 + ], + ], + 'Out of stock product are shown #2' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + 'Out of stock product are hidden #1' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4, + ], + ], + 'Out of stock product are hidden #2' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + ]; + } + + /** + * Write config value to database. + * + * @param string $path + * @param string $value + * @param string $scope + * @param int $scopeId + */ + private function changeConfigValue(string $path, string $value, string $scope = 'default', int $scopeId = 0) + { + $configValue = $this->objectManager->create(Value::class); + $configValue->setPath($path) + ->setValue($value) + ->setScope($scope) + ->setScopeId($scopeId) + ->save(); + $this->reinitConfig(); + } + + /** + * Delete config value from database. + * + * @param string $path + */ + private function dropConfigValue(string $path) + { + $configValue = $this->objectManager->create(Value::class); + try { + $configValue->load($path, 'path'); + $configValue->delete(); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + // do nothing + } + $this->reinitConfig(); + } + + /** + * Reinit config. + */ + private function reinitConfig() + { + $this->reinitableConfig->reinit(); + } } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php new file mode 100644 index 0000000000000..7aa62b149b8c0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php @@ -0,0 +1,75 @@ +\<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_associated.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_in_stock.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_out_of_stock.php'; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId( + \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE +)->setAttributeSetId( + 4 +)->setWebsiteIds( + [1] +)->setName( + 'Grouped Product' +)->setSku( + 'grouped-product' +)->setPrice( + 100 +)->setTaxClassId( + 0 +)->setVisibility( + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH +)->setStatus( + \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED +); + +$newLinks = []; +$productLinkFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory::class); + +/** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ +$productLink = $productLinkFactory->create(); +$linkedProduct = $productRepository->getById(1); +$productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($linkedProduct->getSku()) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->setPosition(1) + ->getExtensionAttributes() + ->setQty(1); +$newLinks[] = $productLink; + +$subProductsSkus = ['virtual-product', 'virtual-product-out']; +foreach ($subProductsSkus as $sku) { + /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ + $productLink = $productLinkFactory->create(); + $linkedProduct = $productRepository->get($sku); + $productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($sku) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->getExtensionAttributes() + ->setQty(2.5); + $newLinks[] = $productLink; +} +$product->setProductLinks($newLinks); +$product->save(); + +/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); + +$categoryLinkManagement->assignProductToCategories( + $product->getSku(), + [2] +); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php new file mode 100644 index 0000000000000..48e7d495f8985 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php @@ -0,0 +1,10 @@ +\<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'product_grouped_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_out_of_stock_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_in_stock_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_associated_rollback.php'; From 2cab212809680085450836442c9346130c1f6440 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 7 Nov 2018 16:02:31 +0200 Subject: [PATCH 1064/1415] Covering the \Magento\Weee\Observer\AddPaymentWeeeItem by Unit Test --- .../Unit/Observer/AddPaymentWeeeItemTest.php | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php new file mode 100644 index 0000000000000..1e707b118dccb --- /dev/null +++ b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php @@ -0,0 +1,154 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Weee\Test\Unit\Observer; + +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Payment\Model\Cart; +use Magento\Payment\Model\Cart\SalesModel\SalesModelInterface; +use Magento\Quote\Model\Quote\Item; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Weee\Helper\Data; +use Magento\Weee\Observer\AddPaymentWeeeItem; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class AddPaymentWeeeItemTest + */ +class AddPaymentWeeeItemTest extends TestCase +{ + /** + * Testable object + * + * @var AddPaymentWeeeItem + */ + private $observer; + + /** + * @var Data|MockObject + */ + private $weeeHelperMock; + + /** + * @var StoreManagerInterface|MockObject + */ + private $storeManagerMock; + + /** + * Set Up + */ + protected function setUp() + { + $this->weeeHelperMock = $this->createMock(Data::class); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + + $this->observer = new AddPaymentWeeeItem( + $this->weeeHelperMock, + $this->storeManagerMock + ); + } + + /** + * Test execute + * + * @dataProvider dataProvider + * @param $isEnabled + * @param $includeInSubtotal + * @return void + */ + public function testExecute($isEnabled, $includeInSubtotal): void + { + /** @var Observer|MockObject $observerMock */ + $observerMock = $this->createMock(Observer::class); + $cartModelMock = $this->createMock(Cart::class); + $salesModelMock = $this->createMock(SalesModelInterface::class); + $itemMock = $this->createPartialMock(Item::class, ['getOriginalItem']); + $originalItemMock = $this->createPartialMock(Item::class, ['getParentItem']); + $parentItemMock = $this->createMock(Item::class); + $eventMock = $this->getMockBuilder(Event::class) + ->disableOriginalConstructor() + ->setMethods(['getCart']) + ->getMock(); + + $asCustomItem = $this->prepareShouldBeAddedAsCustomItem($isEnabled, $includeInSubtotal); + $toBeCalled = 1; + if (!$asCustomItem) { + $toBeCalled = 0; + } + + $eventMock->expects($this->exactly($toBeCalled)) + ->method('getCart') + ->willReturn($cartModelMock); + $observerMock->expects($this->exactly($toBeCalled)) + ->method('getEvent') + ->willReturn($eventMock); + $itemMock->expects($this->exactly($toBeCalled)) + ->method('getOriginalItem') + ->willReturn($originalItemMock); + $originalItemMock->expects($this->exactly($toBeCalled)) + ->method('getParentItem') + ->willReturn($parentItemMock); + $salesModelMock->expects($this->exactly($toBeCalled)) + ->method('getAllItems') + ->willReturn([$itemMock]); + $cartModelMock->expects($this->exactly($toBeCalled)) + ->method('getSalesModel') + ->willReturn($salesModelMock); + + $this->observer->execute($observerMock); + } + + /** + * @return array + */ + public function dataProvider(): array + { + return [ + [true, false], + [true, true], + [false, true], + [false, false], + ]; + } + + /** + * Prepare if FPT should be added to payment cart as custom item or not. + * + * @param $isEnabled + * @param $includeInSubtotal + * @return bool + */ + private function prepareShouldBeAddedAsCustomItem(bool $isEnabled, bool $includeInSubtotal): bool + { + $storeMock = $this->getMockBuilder(StoreInterface::class) + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $storeMock->expects($this->once()) + ->method('getId') + ->willReturn(Store::DEFAULT_STORE_ID); + $this->storeManagerMock->expects($this->once()) + ->method('getStore') + ->willReturn($storeMock); + $this->weeeHelperMock->expects($this->once()) + ->method('isEnabled') + ->with(Store::DEFAULT_STORE_ID) + ->willReturn($isEnabled); + + if ($isEnabled) { + $this->weeeHelperMock->expects($this->once()) + ->method('includeInSubtotal') + ->with(Store::DEFAULT_STORE_ID) + ->willReturn($includeInSubtotal); + } + + return $isEnabled && !$includeInSubtotal; + } +} From bb20a8b757ca43f16b63e98dd97aa5c6f630eaa0 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 7 Nov 2018 16:45:52 +0200 Subject: [PATCH 1065/1415] Small refactoring. Covering the SetWeeeRendererInFormObserver class by Unit Test --- .../Unit/Observer/AddPaymentWeeeItemTest.php | 10 +-- .../SetWeeeRendererInFormObserverTest.php | 88 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php index 1e707b118dccb..dd0547354cfa4 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php @@ -60,11 +60,11 @@ protected function setUp() * Test execute * * @dataProvider dataProvider - * @param $isEnabled - * @param $includeInSubtotal + * @param bool $isEnabled + * @param bool $includeInSubtotal * @return void */ - public function testExecute($isEnabled, $includeInSubtotal): void + public function testExecute(bool $isEnabled, bool $includeInSubtotal): void { /** @var Observer|MockObject $observerMock */ $observerMock = $this->createMock(Observer::class); @@ -122,8 +122,8 @@ public function dataProvider(): array /** * Prepare if FPT should be added to payment cart as custom item or not. * - * @param $isEnabled - * @param $includeInSubtotal + * @param bool $isEnabled + * @param bool $includeInSubtotal * @return bool */ private function prepareShouldBeAddedAsCustomItem(bool $isEnabled, bool $includeInSubtotal): bool diff --git a/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php b/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php new file mode 100644 index 0000000000000..188b42cb37906 --- /dev/null +++ b/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php @@ -0,0 +1,88 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Weee\Test\Unit\Observer; + +use Magento\Framework\Data\Form; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\View\LayoutInterface; +use Magento\Weee\Model\Tax; +use Magento\Weee\Observer\SetWeeeRendererInFormObserver; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class AddPaymentWeeeItemTest + */ +class SetWeeeRendererInFormObserverTest extends TestCase +{ + /** + * Testable object + * + * @var SetWeeeRendererInFormObserver + */ + private $observer; + + /** + * @var LayoutInterface|MockObject + */ + private $layoutMock; + + /** + * @var Tax|MockObject + */ + private $taxModelMock; + + /** + * Set Up + */ + protected function setUp() + { + $this->layoutMock = $this->createMock(LayoutInterface::class); + $this->taxModelMock = $this->createMock(Tax::class); + $this->observer = new SetWeeeRendererInFormObserver( + $this->layoutMock, + $this->taxModelMock + ); + } + + /** + * Test assigning a custom renderer for product create/edit form weee attribute element + * + * @return void + */ + public function testExecute(): void + { + $attributes = new \ArrayIterator(['element_code_1', 'element_code_2']); + /** @var Event|MockObject $eventMock */ + $eventMock = $this->getMockBuilder(Event::class) + ->disableOriginalConstructor() + ->setMethods(['getForm']) + ->getMock(); + + /** @var Observer|MockObject $observerMock */ + $observerMock = $this->createMock(Observer::class); + /** @var Form|MockObject $formMock */ + $formMock = $this->createMock(Form::class); + + $eventMock->expects($this->once()) + ->method('getForm') + ->willReturn($formMock); + $observerMock->expects($this->once()) + ->method('getEvent') + ->willReturn($eventMock); + $this->taxModelMock->expects($this->once()) + ->method('getWeeeAttributeCodes') + ->willReturn($attributes); + $formMock->expects($this->exactly($attributes->count())) + ->method('getElement') + ->willReturnSelf(); + + $this->observer->execute($observerMock); + } +} From 773746968337a08d5f89f5a09113dd763bc0577f Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 7 Nov 2018 17:18:24 +0200 Subject: [PATCH 1066/1415] magento-engcom/magento2ce#2316: Code style fixes --- app/code/Magento/Catalog/Model/Design.php | 5 +++-- lib/internal/Magento/Framework/Translate.php | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Design.php b/app/code/Magento/Catalog/Model/Design.php index 6c0629feaf6fd..853bbeac8eb38 100644 --- a/app/code/Magento/Catalog/Model/Design.php +++ b/app/code/Magento/Catalog/Model/Design.php @@ -43,9 +43,10 @@ class Design extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\View\DesignInterface $design - * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource - * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection + * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource + * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data + * @param TranslateInterface|null $translator */ public function __construct( \Magento\Framework\Model\Context $context, diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ff1bf99162a8a..f889549a107a8 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -278,6 +278,7 @@ protected function getConfig($key) /** * Retrieve name of the current module + * * @return mixed */ protected function getControllerModuleName() From 7c6ecc33bf6d5707021548e0920650b7feec265c Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Wed, 7 Nov 2018 17:27:01 +0200 Subject: [PATCH 1067/1415] MAGETWO-70532: [GitHub] REST API Missing Product_Option values for Order Items in salesOrderManagementV1 and salesOrderItemRepositoryV1 #9326 - Added product options merger --- app/code/Magento/Sales/Model/Order/ItemRepository.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index e9764e7d38c5a..d7dc0ca67d81c 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -168,7 +168,9 @@ public function save(OrderItemInterface $entity) { if ($entity->getProductOption()) { $request = $this->getBuyRequest($entity); - $entity->setProductOptions(['info_buyRequest' => $request->toArray()]); + $productOptions = $entity->getProductOptions(); + $productOptions['info_buyRequest'] = $request->toArray(); + $entity->setProductOptions($productOptions); } $this->metadata->getMapper()->save($entity); From d7fca7216491ac404b00ca6ff43d0ac6751a5597 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 19:26:30 -0600 Subject: [PATCH 1068/1415] MAGETWO-95745: Signifyd case not created for WorldPay - revert MAGETWO-94269 --- .../Paypal/Controller/Payflow/ReturnUrl.php | 4 ++-- .../Unit/Controller/Payflow/ReturnUrlTest.php | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php index 56a5da40edb85..cf932f046d1be 100644 --- a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php +++ b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php @@ -6,6 +6,7 @@ */ namespace Magento\Paypal\Controller\Payflow; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\CsrfAwareActionInterface; use Magento\Framework\App\Request\InvalidRequestException; use Magento\Framework\App\RequestInterface; @@ -13,7 +14,7 @@ use Magento\Paypal\Model\Config; use Magento\Sales\Model\Order; -class ReturnUrl extends Payflow implements CsrfAwareActionInterface +class ReturnUrl extends Payflow implements CsrfAwareActionInterface, HttpGetActionInterface { /** * @var array of allowed order states on frontend @@ -68,7 +69,6 @@ public function execute() if ($order->getIncrementId()) { if ($this->checkOrderState($order)) { $redirectBlock->setData('goto_success_page', true); - $this->_eventManager->dispatch('paypal_checkout_success', ['order' => $order]); } else { if ($this->checkPaymentMethod($order)) { $gotoSection = $this->_cancelPayment((string)$this->getRequest()->getParam('RESPMSG')); diff --git a/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php b/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php index 44775d7e381bb..32d3f2c73b159 100644 --- a/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php @@ -5,7 +5,6 @@ */ namespace Magento\Paypal\Test\Unit\Controller\Payflow; -use Magento\Framework\Event\ManagerInterface; use Magento\Sales\Api\PaymentFailuresInterface; use Magento\Checkout\Block\Onepage\Success; use Magento\Checkout\Model\Session; @@ -97,11 +96,6 @@ class ReturnUrlTest extends \PHPUnit\Framework\TestCase */ private $paymentFailures; - /** - * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $eventManagerMock; - /** * @inheritdoc */ @@ -158,16 +152,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->context->method('getView') ->willReturn($this->view); $this->context->method('getRequest') ->willReturn($this->request); - $this->context->method('getEventManager') - ->willReturn($this->eventManagerMock); $this->returnUrl = $this->objectManager->getObject( ReturnUrl::class, @@ -199,10 +187,6 @@ public function testExecuteAllowedOrderState($state) ->with('goto_success_page', true) ->willReturnSelf(); - $this->eventManagerMock->expects($this->once()) - ->method('dispatch') - ->with('paypal_checkout_success', $this->arrayHasKey('order')); - $result = $this->returnUrl->execute(); $this->assertNull($result); } From 385b01ef801cfa5fc5e2745bd71154bee85f8c3b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 7 Nov 2018 10:58:54 -0600 Subject: [PATCH 1069/1415] MAGETWO-95745: Signifyd case not created for WorldPay - revert MAGETWO-71763 --- app/code/Magento/Signifyd/etc/events.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Signifyd/etc/events.xml b/app/code/Magento/Signifyd/etc/events.xml index e6418e2fdb6b4..d44665f9fb97b 100644 --- a/app/code/Magento/Signifyd/etc/events.xml +++ b/app/code/Magento/Signifyd/etc/events.xml @@ -9,9 +9,6 @@ <event name="checkout_submit_all_after"> <observer name="signifyd_place_order_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> - <event name="paypal_express_place_order_success"> - <observer name="signifyd_place_order_paypal_express_observer" instance="Magento\Signifyd\Observer\PlaceOrder"/> - </event> <event name="paypal_checkout_success"> <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> From 436f0d995df9c0a374ec504f4302d2bf6e909af5 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 7 Nov 2018 11:32:54 -0600 Subject: [PATCH 1070/1415] MAGETWO-95745: Signifyd case not created for WorldPay - fix static test failures --- app/code/Magento/Checkout/Controller/Onepage/Success.php | 4 +++- app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Controller/Onepage/Success.php b/app/code/Magento/Checkout/Controller/Onepage/Success.php index e0872b425cc7c..a657b23cca4d6 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/Success.php +++ b/app/code/Magento/Checkout/Controller/Onepage/Success.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,9 @@ use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; +/** + * Onepage checkout success controller class + */ class Success extends \Magento\Checkout\Controller\Onepage implements HttpGetActionInterface { /** diff --git a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php index cf932f046d1be..d2a14febe54dd 100644 --- a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php +++ b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -14,6 +13,9 @@ use Magento\Paypal\Model\Config; use Magento\Sales\Model\Order; +/** + * Paypal Payflow ReturnUrl controller class + */ class ReturnUrl extends Payflow implements CsrfAwareActionInterface, HttpGetActionInterface { /** From 240cfb3e8b2ed77cf63566d7326e537771e8bceb Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 7 Nov 2018 20:35:18 +0200 Subject: [PATCH 1071/1415] graphQl: fixed typos and wrong descriptions --- .../QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php | 8 ++++---- .../Model/Cart/SetShippingAddressesOnCartInterface.php | 3 ++- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 3 +-- .../GraphQl/Quote/SetShippingAddressOnCartTest.php | 9 ++++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 588d4f65cc565..960900682db4c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -59,7 +59,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s { if (count($shippingAddresses) > 1) { throw new GraphQlInputException( - __('Multiple addresses do not allowed here!') + __('You cannot specify multiple shipping addresses.') ); } $shippingAddress = current($shippingAddresses); @@ -68,19 +68,19 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s if (!$customerAddressId && !$addressInput) { throw new GraphQlInputException( - __('Shipping address should contain either "customer_address_id" or "address" input.') + __('The shipping address must contain either "customer_address_id" or "address".') ); } if ($customerAddressId && $addressInput) { throw new GraphQlInputException( - __('Shipping address can\'t contain "customer_address_id" and "address" input at the same time.') + __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') ); } if ($customerAddressId) { if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { throw new GraphQlAuthorizationException( __( - 'Address management allowed only for authorized customers.' + 'Guest users cannot manage addresses.' ) ); } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index ae337240c3a26..dde9cce9d8693 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -14,7 +14,8 @@ /** * Extension point for setting shipping addresses for a specified shopping cart * - * All objects that are responsible for set shipping addresses on cart via GraphQl should implement this interface. + * All objects that are responsible for setting shipping addresses on a cart via GraphQl + *should implement this interface. */ interface SetShippingAddressesOnCartInterface { diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 017b1f8119829..15d90c352ba62 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,11 +6,10 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 48ef8ebb790d1..2b4223cf67a89 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -139,13 +139,12 @@ public function testSetSavedShippingAddressOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Address management allowed only for authorized customers.'); + self::expectExceptionMessage('Guest users cannot manage addresses.'); $this->graphQlQuery($query); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php - * @magentoConfigFixture default_store multishipping/options/checkout_multiple 0 */ public function testSetMultipleShippingAddressesOnCartByGuest() { @@ -185,7 +184,7 @@ public function testSetMultipleShippingAddressesOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Multiple addresses do not allowed here!'); + self::expectExceptionMessage('You cannot specify multiple shipping addresses.'); $this->graphQlQuery($query); } @@ -240,7 +239,7 @@ public function testSetSavedAndNewShippingAddressOnCartAtTheSameTime() } QUERY; self::expectExceptionMessage( - 'Shipping address can\'t contain "customer_address_id" and "address" input at the same time.' + 'The shipping address cannot contain "customer_address_id" and "address" at the same time.' ); $this->graphQlQuery($query); } @@ -282,7 +281,7 @@ public function testSetShippingAddressOnCartWithNoAddresses() } QUERY; self::expectExceptionMessage( - 'Shipping address should contain either "customer_address_id" or "address" input.' + 'The shipping address must contain either "customer_address_id" or "address".' ); $this->graphQlQuery($query); } From b490fb16a0e21eb4b11327d4dcc2e54ebdfdaca4 Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Wed, 7 Nov 2018 20:35:28 +0100 Subject: [PATCH 1072/1415] #18956 Add TestCase for no root_category_id set --- .../Config/Importer/Processor/CreateTest.php | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php index 0901464224399..0fbf7bb7f044b 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php @@ -196,14 +196,30 @@ private function initTestData() 'root_category_id' => '1', 'default_store_id' => '1', 'code' => 'default', + ], + 2 => [ + 'group_id' => '1', + 'website_id' => '1', + 'name' => 'Default1', + 'default_store_id' => '1', + 'code' => 'default1', ] ]; - $this->trimmedGroup = [ - 'name' => 'Default', - 'root_category_id' => '1', - 'code' => 'default', - 'default_store_id' => '1', - ]; + $this->trimmedGroup = + [ + 0 => [ + 'name' => 'Default', + 'root_category_id' => '1', + 'code' => 'default', + 'default_store_id' => '1', + ], + 1 => [ + 'name' => 'Default1', + 'root_category_id' => '0', + 'code' => 'default1', + 'default_store_id' => '1' + ] + ]; $this->stores = [ 'default' => [ 'store_id' => '1', @@ -280,31 +296,34 @@ public function testRunGroup() [ScopeInterface::SCOPE_GROUPS, $this->groups, $this->groups], ]); - $this->websiteMock->expects($this->once()) + $this->websiteMock->expects($this->exactly(2)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setData') - ->with($this->trimmedGroup) - ->willReturnSelf(); - $this->groupMock->expects($this->exactly(3)) + ->withConsecutive( + [$this->equalTo($this->trimmedGroup[0])], + [$this->equalTo($this->trimmedGroup[1])] + )->willReturnSelf(); + + $this->groupMock->expects($this->exactly(6)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('getDefaultStoreId') ->willReturn($defaultStoreId); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setDefaultStoreId') ->with($storeId); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setWebsite') ->with($this->websiteMock); - $this->storeMock->expects($this->once()) + $this->storeMock->expects($this->exactly(2)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->storeMock->expects($this->once()) + $this->storeMock->expects($this->exactly(2)) ->method('getStoreId') ->willReturn($storeId); @@ -312,11 +331,11 @@ public function testRunGroup() ->method('load') ->withConsecutive([$this->websiteMock, 'base', 'code'], [$this->storeMock, 'default', 'code']) ->willReturnSelf(); - $this->abstractDbMock->expects($this->exactly(2)) + $this->abstractDbMock->expects($this->exactly(4)) ->method('save') ->with($this->groupMock) ->willReturnSelf(); - $this->abstractDbMock->expects($this->once()) + $this->abstractDbMock->expects($this->exactly(2)) ->method('addCommitCallback') ->willReturnCallback(function ($function) { return $function(); From c8ac4261ef79f5259855f7460e08a8662dad7589 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 7 Nov 2018 15:31:52 -0600 Subject: [PATCH 1073/1415] MAGETWO-95770: Saved multi line attribute data displayed incorrectly on customer edit address page - Fixed multiline customer address attribute data processing for admin --- .../Magento/Customer/Model/Customer/DataProvider.php | 11 +++++++++-- .../AdminCustomerAccountInformationSection.xml | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php index ce976d3f62c74..a3e121d3ce71a 100644 --- a/app/code/Magento/Customer/Model/Customer/DataProvider.php +++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php @@ -25,6 +25,7 @@ use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool; +use Magento\Ui\Component\Form\Element\Multiline; use Magento\Ui\Component\Form\Field; use Magento\Ui\DataProvider\EavValidationRules; @@ -596,8 +597,14 @@ protected function prepareAddressData($addressId, array &$addresses, array $cust ) { $addresses[$addressId]['default_shipping'] = $customer['default_shipping']; } - if (isset($addresses[$addressId]['street']) && !is_array($addresses[$addressId]['street'])) { - $addresses[$addressId]['street'] = explode("\n", $addresses[$addressId]['street']); + + foreach ($this->meta['address']['children'] as $attributeName => $attributeMeta) { + if ($attributeMeta['arguments']['data']['config']['dataType'] === Multiline::NAME + && isset($addresses[$addressId][$attributeName]) + && !is_array($addresses[$addressId][$attributeName]) + ) { + $addresses[$addressId][$attributeName] = explode("\n", $addresses[$addressId][$attributeName]); + } } } diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index a8c079824eff3..e9776a43e3df5 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -12,6 +12,7 @@ <element name="statusInactive" type="button" selector=".admin__actions-switch-label"/> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> <element name="accountInformationButton" type="text" selector="//a/span[text()='Account Information']"/> + <element name="addressesButton" type="text" selector="//a/span[text()='Addresses']"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> From e7247de8e972674bf95bc46f6eccb8b958c64392 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 7 Nov 2018 15:35:46 -0600 Subject: [PATCH 1074/1415] MAGETWO-95770: Saved multi line attribute data displayed incorrectly on customer edit address page - Fixed static issues --- app/code/Magento/Customer/Model/Customer/DataProvider.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php index a3e121d3ce71a..31f126e937c92 100644 --- a/app/code/Magento/Customer/Model/Customer/DataProvider.php +++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php @@ -30,6 +30,8 @@ use Magento\Ui\DataProvider\EavValidationRules; /** + * Supplies the data for the customer UI component + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * * @api @@ -156,10 +158,11 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider * @param Config $eavConfig * @param FilterPool $filterPool * @param FileProcessorFactory $fileProcessorFactory - * @param ContextInterface $context * @param array $meta * @param array $data + * @param ContextInterface $context * @param bool $allowToShowHiddenAttributes + * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( From b027ce062c33745cc23fae044566520c584ba459 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 7 Nov 2018 16:25:57 -0600 Subject: [PATCH 1075/1415] ENGCOM-3409: Skip randomly failing tests in PR #2316 --- ...dminSubmitConfigurableProductOrderTest.xml | 259 +++++++++--------- .../Test/Mftf/Test/AdminTaxReportGridTest.xml | 3 + .../Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 + 3 files changed, 137 insertions(+), 128 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml index e32e6b9e6ec5d..ff1e27a2efa08 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml @@ -1,129 +1,132 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminSubmitConfigurableProductOrderTest"> - <annotations> - <title value="Create Order in Admin and update product configuration"/> - <stories value="MAGETWO-59632: Create Sales > Order from admin add configurable product and change options click OK does not update Items Ordered List"/> - <description value="Create Order in Admin and update product configuration"/> - <features value="Sales"/> - <severity value="AVERAGE"/> - <testCaseId value="MAGETWO-59633"/> - <group value="Sales"/> - </annotations> - - <before> - <!--Set default flat rate shipping method settings--> - <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> - - <!--Create simple customer--> - <createData entity="Simple_US_Customer_CA" stepKey="simpleCustomer"/> - - <!-- Create the category --> - <createData entity="ApiCategory" stepKey="createCategory"/> - - <!-- Create the configurable product and add it to the category --> - <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - - <!-- Create an attribute with two options to be used in the first child product --> - <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> - <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <!-- Add the attribute we just created to default attribute set --> - <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <!-- Get the option of the attribute we created --> - <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - - <!-- Create a simple product and give it the attribute with option --> - <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption1"/> - </createData> - <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption2"/> - </createData> - - <!-- Create the configurable product --> - <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption1"/> - <requiredEntity createDataKey="getConfigAttributeOption2"/> - </createData> - - <!-- Add simple product to the configurable product --> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigChildProduct1"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigChildProduct2"/> - </createData> - - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - - <!--Create new customer order--> - <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> - <argument name="customer" value="$$simpleCustomer$$"/> - </actionGroup> - - <!--Add configurable product to order--> - <actionGroup ref="addConfigurableProductToOrderFromAdmin" stepKey="addConfigurableProductToOrder"> - <argument name="product" value="$$createConfigProduct$$"/> - <argument name="attribute" value="$$createConfigProductAttribute$$"/> - <argument name="option" value="$$getConfigAttributeOption1$$"/> - </actionGroup> - - <!--Configure ordered configurable product--> - <actionGroup ref="configureOrderedConfigurableProduct" stepKey="configureOrderedConfigurableProduct"> - <argument name="attribute" value="$$createConfigProductAttribute$$"/> - <argument name="option" value="$$getConfigAttributeOption2$$"/> - <argument name="quantity" value="2"/> - </actionGroup> - - <!--Select FlatRate shipping method--> - <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> - - <!--Submit order--> - <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="submitOrder"/> - - <!--Verify order information--> - <actionGroup ref="verifyCreatedOrderInformation" stepKey="verifyCreatedOrderInformation"/> - - <after> - <actionGroup ref="logout" stepKey="logout"/> - - <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> - - <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> - <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> - <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> - <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> - <deleteData createDataKey="createCategory" stepKey="deleteApiCategory"/> - </after> - </test> +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminSubmitConfigurableProductOrderTest"> + <annotations> + <title value="Create Order in Admin and update product configuration"/> + <stories value="MAGETWO-59632: Create Sales > Order from admin add configurable product and change options click OK does not update Items Ordered List"/> + <description value="Create Order in Admin and update product configuration"/> + <features value="Sales"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-59633"/> + <group value="Sales"/> + <skip> + <issueId value="MAGETWO-96196"/> + </skip> + </annotations> + + <before> + <!--Set default flat rate shipping method settings--> + <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> + + <!--Create simple customer--> + <createData entity="Simple_US_Customer_CA" stepKey="simpleCustomer"/> + + <!-- Create the category --> + <createData entity="ApiCategory" stepKey="createCategory"/> + + <!-- Create the configurable product and add it to the category --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Create an attribute with two options to be used in the first child product --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Add the attribute we just created to default attribute set --> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Get the option of the attribute we created --> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create a simple product and give it the attribute with option --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Create the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Add simple product to the configurable product --> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <!--Create new customer order--> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> + <argument name="customer" value="$$simpleCustomer$$"/> + </actionGroup> + + <!--Add configurable product to order--> + <actionGroup ref="addConfigurableProductToOrderFromAdmin" stepKey="addConfigurableProductToOrder"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="attribute" value="$$createConfigProductAttribute$$"/> + <argument name="option" value="$$getConfigAttributeOption1$$"/> + </actionGroup> + + <!--Configure ordered configurable product--> + <actionGroup ref="configureOrderedConfigurableProduct" stepKey="configureOrderedConfigurableProduct"> + <argument name="attribute" value="$$createConfigProductAttribute$$"/> + <argument name="option" value="$$getConfigAttributeOption2$$"/> + <argument name="quantity" value="2"/> + </actionGroup> + + <!--Select FlatRate shipping method--> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> + + <!--Submit order--> + <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="submitOrder"/> + + <!--Verify order information--> + <actionGroup ref="verifyCreatedOrderInformation" stepKey="verifyCreatedOrderInformation"/> + + <after> + <actionGroup ref="logout" stepKey="logout"/> + + <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> + + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <deleteData createDataKey="createCategory" stepKey="deleteApiCategory"/> + </after> + </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml index 68fe8087c4fcd..05b85a3a55cb1 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-94338"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96193"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 3b741e7bf79ec..b87ab626d3970 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-295"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96194"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 4c495f2faa29edcaeebfe1ca1691754f3ef41b55 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Wed, 7 Nov 2018 20:00:53 -0500 Subject: [PATCH 1076/1415] rebalance integration tests to prevent travis timeout --- dev/travis/before_script.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 1dccc310c7a20..3bd671dbaf800 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -13,9 +13,9 @@ case $TEST_SUITE in test_set_list=$(find testsuite/* -maxdepth 1 -mindepth 1 -type d | sort) test_set_count=$(printf "$test_set_list" | wc -l) - test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.17" | bc)) #17% - test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.27" | bc)) #27% - test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #56% + test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.13" | bc)) #13% + test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.30" | bc)) #30% + test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #55% echo "Total = ${test_set_count}; Batch #1 = ${test_set_size[1]}; Batch #2 = ${test_set_size[2]}; Batch #3 = ${test_set_size[3]};"; echo "==> preparing integration testsuite on index $INTEGRATION_INDEX with set size of ${test_set_size[$INTEGRATION_INDEX]}" From bd34b53918b3c159b5ceb87ac59f66c84f1b76ee Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 10:48:18 +0300 Subject: [PATCH 1077/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c06f615ae48e6..91454e8b3de78 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -114,7 +114,7 @@ define([ /** * - * @param {Array} recordData to reprocess + * @param {Array} - recordData to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { From e0360fea947d2392b66d4a11ccbe195fe8f3758e Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Thu, 8 Nov 2018 12:53:11 +0200 Subject: [PATCH 1078/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - create MFTF test to cover fix --- .../ActionGroup/AdminOrderBraintreeFill.xml | 43 +++++++ .../Test/Mftf/Data/BraintreeData.xml | 1 + .../Test/Mftf/Section/AdminMenuSection.xml | 2 +- ...thOnlinePaymentIncludingTaxAndDiscount.xml | 110 ++++++++++++++++++ .../ActionGroup/AdminInvoiceActionGroup.xml | 13 +++ .../ActionGroup/AdminOrderActionGroup.xml | 1 + .../AdminInvoiceMainActionsSection.xml | 2 + .../Section/AdminOrderInvoicesTabSection.xml | 1 + .../AdminCreateCartPriceRuleActionGroup.xml | 31 +++++ .../AdminCartPriceRulesFormSection.xml | 1 + .../Section/CartPriceRulesSubmenuSection.xml | 14 +++ .../Mftf/ActionGroup/AdminTaxActionGroup.xml | 27 +++++ .../Mftf/Section/AdminConfigureTaxSection.xml | 4 + 13 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml create mode 100644 app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Section/CartPriceRulesSubmenuSection.xml diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml new file mode 100644 index 0000000000000..6ef70b1f38660 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + + <actionGroup name="AdminOrderBraintreeFill"> + + <!--Select Braintree Payment method on Admin Order Create Page--> + <click stepKey="chooseBraintree" selector="{{NewOrderSection.creditCardBraintree}}"/> + <waitForPageLoad stepKey="waitForBraintreeConfigs" time="5"/> + <click stepKey="openCardTypes" selector="{{NewOrderSection.openCardTypes}}"/> + <waitForPageLoad stepKey="waitForCardTypes" time="3"/> + <click stepKey="chooseCardType" selector="{{NewOrderSection.masterCard}}"/> + <waitForPageLoad stepKey="waitForCardSelected" time="3"/> + + <!--Choose Master Card from drop-down list--> + <switchToIFrame stepKey="switchToCardNumber" selector="{{NewOrderSection.cardFrame}}"/> + <fillField stepKey="fillCardNumber" selector="{{NewOrderSection.creditCardNumber}}" userInput="{{PaymentAndShippingInfo.cardNumber}}"/> + <waitForPageLoad stepKey="waitForFillCardNumber" time="1"/> + <switchToIFrame stepKey="switchBackFromCard"/> + + <!--Fill expire date--> + <switchToIFrame stepKey="switchToExpirationMonth" selector="{{NewOrderSection.monthFrame}}"/> + <fillField stepKey="fillMonth" selector="{{NewOrderSection.expirationMonth}}" userInput="{{PaymentAndShippingInfo.month}}"/> + <waitForPageLoad stepKey="waitForFillMonth" time="1"/> + <switchToIFrame stepKey="switchBackFromMonth"/> + <switchToIFrame stepKey="switchToExpirationYear" selector="{{NewOrderSection.yearFrame}}"/> + <fillField stepKey="fillYear" selector="{{NewOrderSection.expirationYear}}" userInput="{{PaymentAndShippingInfo.year}}"/> + <waitForPageLoad stepKey="waitForFillYear" time="1"/> + <switchToIFrame stepKey="switchBackFromYear"/> + + <!--Fill CVW code--> + <switchToIFrame stepKey="switchToCVV" selector="{{NewOrderSection.cvvFrame}}"/> + <fillField stepKey="fillCVV" selector="{{NewOrderSection.cvv}}" userInput="{{PaymentAndShippingInfo.cvv}}"/> + <wait stepKey="waitForFillCVV" time="1"/> + <switchToIFrame stepKey="switchBackFromCVV"/> + </actionGroup> +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml index 8f2588a6effa5..ff98b6c91b5a9 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml @@ -42,6 +42,7 @@ <requiredEntity type="merchant_id">MerchantId</requiredEntity> <requiredEntity type="public_key">PublicKey</requiredEntity> <requiredEntity type="private_key">PrivateKey</requiredEntity> + <requiredEntity type="active">Status</requiredEntity> </entity> <entity name="BraintreeTitle" type="title"> <data key="value">Credit Card (Braintree)</data> diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/AdminMenuSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/AdminMenuSection.xml index 660c7393b4061..eb7a9ce2c376e 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Section/AdminMenuSection.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Section/AdminMenuSection.xml @@ -13,7 +13,7 @@ <element name="sales" type="button" selector="//li[@id='menu-magento-sales-sales']"/> <element name="catalog" type="button" selector="//li[@id='menu-magento-catalog-catalog']"/> <element name="customers" type="button" selector="//li[@id='menu-magento-customer-customer']"/> - <element name="marketing" type="button" selector="//li[@id='//li[@id='menu-magento-backend-marketing']']"/> + <element name="marketing" type="button" selector="//li[@id='menu-magento-backend-marketing']"/> <element name="content" type="button" selector="//li[@id='menu-magento-backend-content']"/> <element name="reports" type="button" selector="//li[@id='menu-magento-reports-report']"/> <element name="stores" type="button" selector="//li[@id='menu-magento-backend-stores']"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml new file mode 100644 index 0000000000000..470c425f3dae1 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CreateAdminOrderPayedWithOnlinePaymentIncludingTaxAndDiscount"> + <annotations> + <features value="Sales"/> + <stories value="Get access to a New Credit Memo Page from Invocie for Order payed with online payment via Admin"/> + <title value="Admin should be able to open a New Credit Memo Page from Invoice Page for Order with tax and discount and payed using online payment method"/> + <description value="Admin should be able to open a New Credit Memo Page from Invoice Page for Order with tax and discount and payed using online payment method"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-94472"/> + <group value="sales"/> + </annotations> + + <before> + <!--Create Default Category--> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + + <!--Create Simple product with Special Price--> + <createData entity="_defaultProduct" stepKey="simpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!--Create Tax Rule is based on default tax rates (Stores>Tax Rule) US-CA-*-Rate 1 = 8.2500 US-NY-*-Rate 1 = 8.3750 --> + <createData entity="SimpleTaxRule" stepKey="createTaxRule"/> + + <!--Configure Braintree Payment method--> + <createData entity="BraintreeConfig" stepKey="BraintreeConfigurationData"/> + <createData entity="CustomBraintreeConfigurationData" stepKey="enableBraintree"/> + + <!--Create Retailer Customer with US_CA address--> + <createData entity="Simple_US_Customer_CA" stepKey="simpleCustomer"> + <field key="group_id">3</field> + </createData> + + <!--Login as Admin User--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <!--Delete Cart Price Rule--> + <actionGroup ref="AdminDeleteCartPriceRuleForRetailerActionGroup" stepKey="deleteSalesRule"/> + + <!--Delete Simple Sub Category--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + + <!--Delete Simple Product--> + <deleteData createDataKey="simpleProduct" stepKey="deleteSimpleProduct"/> + + <!-- Delete Tax Rule --> + <deleteData createDataKey="createTaxRule" stepKey="deleteTaxRule"/> + + <!-- Rollback Braintree to Default --> + <createData entity="DefaultBraintreeConfig" stepKey="DefaultBraintreeConfig"/> + + <!--Delete Customer--> + <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> + + <!--Log Out--> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!-- Create a cart price rule for Fixed amount discount for whole cart --> + <actionGroup ref="AdminCreateCartPriceRuleForRetailerActionGroup" stepKey="createCartPriceRule"/> + + <!--Set Taxable Goods for Shipping Tax Class--> + <actionGroup ref="changeShippingTaxClass" stepKey="changeShippingTaxClass"/> + + <!--Adding Special price to product--> + <amOnPage url="{{AdminProductEditPage.url($$simpleProduct.id$$)}}" stepKey="openAdminProductEditPage"/> + <actionGroup ref="AddSpecialPriceToProductActionGroup" stepKey="addSpecialPrice"/> + <actionGroup ref="saveProductForm" stepKey="saveProductForm"/> + + <!--Create New Order--> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> + <argument name="customer" value="$$simpleCustomer$$"/> + </actionGroup> + + <!--Add a product to order--> + <actionGroup ref="addSimpleProductToOrder" stepKey="addProductToOrder"> + <argument name="product" value="$$simpleProduct$$"/> + </actionGroup> + + <!--Select FlatRate shipping method--> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> + + <!--Select Braintree online Payment method --> + <actionGroup ref="AdminOrderBraintreeFill" stepKey="selectCreditCardPayment"/> + + <!--Submit Order--> + <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> + <waitForPageLoad stepKey="waitForSaveConfig" time="10"/> + <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="5"/> + + <!-- Create New invoice--> + <actionGroup ref="adminFastCreateInvoice" stepKey="createInvoice"/> + + <!--Get access to Credit Memo page from Invocie page--> + <click selector="{{AdminInvoiceMainActionsSection.openNewCreditMemoFromInvoice}}" stepKey="clickCreateNewCreditMemo"/> + <waitForPageLoad stepKey="waitForLoadNewCreditMemoPage" time="5"/> + <waitForElementVisible selector="{{AdminCreditMemoOrderInformationSection.orderId}}" stepKey="waitForOrderIdOnCreditMemoPage"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml index 15aff7c751a11..6cda4e143c926 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml @@ -38,4 +38,17 @@ </arguments> <see selector="{{AdminInvoiceItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> + + <!--Admin Fast Create Invoice--> + <actionGroup name="adminFastCreateInvoice"> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> + <waitForPageLoad stepKey="waitForNewInvoicePageLoad" time="3"/> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <waitForPageLoad stepKey="waitForSuccessMessageLoad" time="5"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> + <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoices"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask5" /> + <click selector="{{AdminOrderInvoicesTabSection.viewInvoice}}" stepKey="openInvoicePage"/> + <waitForPageLoad stepKey="waitForInvoicePageLoad" time="5"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index c82623632d782..4801c3c6f85a6 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -92,6 +92,7 @@ <fillField selector="{{AdminOrderFormItemsSection.rowQty('1')}}" userInput="1" stepKey="fillProductQty"/> <scrollTo selector="{{AdminOrderFormItemsSection.addSelected}}" x="0" y="-100" stepKey="scrollToAddSelectedButton"/> <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickAddSelectedProducts"/> + <wait time="5" stepKey="waitForOptionsToLoad"/> </actionGroup> <!--Add configurable product to order --> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceMainActionsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceMainActionsSection.xml index 2a241708517bf..bc7fc8145af33 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceMainActionsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceMainActionsSection.xml @@ -10,5 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminInvoiceMainActionsSection"> <element name="submitInvoice" type="button" selector=".action-default.scalable.save.submit-button.primary"/> + <element name="openNewCreditMemoFromInvoice" type="button" selector=".action-default.scalable.credit-memo"/> + <element name="submitNewRefundFromInvoice" type="button" selector=".action-default.scalable.save.submit-button refund primary"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderInvoicesTabSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderInvoicesTabSection.xml index b33276bed527e..4ebce4de6b383 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderInvoicesTabSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderInvoicesTabSection.xml @@ -12,5 +12,6 @@ <element name="spinner" type="text" selector="[data-role='spinner'][data-component*='sales_order_view_invoice']"/> <element name="gridRow" type="text" selector="#sales_order_view_tabs_order_invoices_content .data-grid tbody > tr:nth-of-type({{row}})" parameterized="true"/> <element name="viewGridRow" type="button" selector="#sales_order_view_tabs_order_invoices_content .data-grid tbody > tr:nth-of-type({{row}}) a[href*='order_invoice/view']" parameterized="true"/> + <element name="viewInvoice" type="button" selector="//div[@class='admin__data-grid-wrap']//a[@class='action-menu-item']"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index 87947fba8095a..6a837577ece3d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -23,4 +23,35 @@ <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> <see selector="{{AdminCartPriceRulesFormSection.successMessage}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> </actionGroup> + + <!--Create Cart price Rule for Retailer customer--> + <actionGroup name="AdminCreateCartPriceRuleForRetailerActionGroup"> + <click selector="{{AdminMenuSection.marketing}}" stepKey="clickOnMarketing" /> + <waitForPageLoad stepKey="waitForMarketing" time="3"/> + <click selector="{{CartPriceRulesSubmenuSection.cartPriceRules}}" stepKey="clickOnCartPriceRules"/> + <waitForPageLoad stepKey="waitForCartPriceRules" time="5"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectCustomerGroup"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <waitForPageLoad stepKey="waitForCartRuleLoad" time="5"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + </actionGroup> + + <!--Delete Cart price Rule for Retailer customer--> + <actionGroup name="AdminDeleteCartPriceRuleForRetailerActionGroup"> + <click selector="{{AdminMenuSection.marketing}}" stepKey="clickOnMarketing" /> + <waitForPageLoad stepKey="waitForMarketing" time="3"/> + <click selector="{{CartPriceRulesSubmenuSection.cartPriceRules}}" stepKey="clickOnCartPriceRules"/> + <waitForPageLoad stepKey="waitForCartPriceRules" time="5"/> + <fillField selector="{{AdminCartPriceRulesSection.filterByNameInput}}" userInput="{{SimpleSalesRule.name}}" stepKey="filterByName"/> + <click selector="{{AdminCartPriceRulesSection.searchButton}}" stepKey="doFilter"/> + <click selector="{{AdminCartPriceRulesSection.rowByIndex('1')}}" stepKey="goToEditRulePage"/> + <click selector="{{AdminCartPriceRulesFormSection.delete}}" stepKey="clickDeleteButton"/> + <click selector="{{AdminCartPriceRulesFormSection.modalAcceptButton}}" stepKey="confirmDelete"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index d8253505c42e4..480c266101dba 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -26,6 +26,7 @@ <element name="priority" type="input" selector="//*[@name='sort_order']"/> <!-- Actions sub-form --> + <element name="actionsTab" type="text" selector="//div[@data-index='actions']//span[contains(.,'Actions')][1]"/> <element name="actionsHeader" type="button" selector="div[data-index='actions']" timeout="30"/> <element name="apply" type="select" selector="select[name='simple_action']"/> <element name="conditions" type="button" selector=".rule-param.rule-param-new-child > a"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/CartPriceRulesSubmenuSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/CartPriceRulesSubmenuSection.xml new file mode 100644 index 0000000000000..f3d5e9627efcf --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/CartPriceRulesSubmenuSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="CartPriceRulesSubmenuSection"> + <element name="cartPriceRules" type="button" selector="//li[@data-ui-id='menu-magento-catalogrule-promo']//li[@data-ui-id='menu-magento-salesrule-promo-quote']"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml index 1a95bf0282b40..15dcaf66f1220 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml @@ -115,4 +115,31 @@ <!-- Save the tax rate --> <click stepKey="saveTaxRate" selector="{{AdminTaxRulesSection.save}}"/> </actionGroup> + + <!--Set Tax Class for Shipping--> + <actionGroup name="changeShippingTaxClass"> + <!--Select Configuration menu from Store--> + <click selector="{{AdminMenuSection.stores}}" stepKey="clickOnSTORES" /> + <waitForPageLoad stepKey="waitForConfiguration" time="5"/> + <click selector="{{StoresSubmenuSection.configuration}}" stepKey="clickOnConfigurations"/> + <waitForPageLoad stepKey="waitForSales" time="5"/> + <!--Double click the same to fix flaky issue with redirection to Dashboard--> + <click selector="{{AdminMenuSection.stores}}" stepKey="clickOnSTORES1" /> + <waitForPageLoad stepKey="waitForConfiguration1" time="5"/> + <click selector="{{StoresSubmenuSection.configuration}}" stepKey="clickOnConfigurations1"/> + <waitForPageLoad stepKey="waitForSales1" time="5"/> + <!--Change default tax class for Shipping on Taxable Goods--> + <click selector="{{ConfigurationListSection.sales}}" stepKey="clickOnSales" /> + <waitForPageLoad stepKey="waitForPaymentMethods" time="5"/> + <click selector="{{AdminConfigureTaxSection.salesTax}}" stepKey="clickOnTax"/> + <waitForPageLoad stepKey="waitForTax" time="5"/> + <seeInCurrentUrl url="{{AdminTaxConfigurationPage.url}}" stepKey="adminTaxConfiguration"/> + <seeElement selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="taxClassSectionC"/> + <selectOption selector="{{AdminConfigureTaxSection.taxClassShipping}}" userInput="Taxable Goods" stepKey="setTaxClassForShipping"/> + <!-- Save the settings --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="saveTaxOptions" selector="{{AdminCategoryMainActionsSection.SaveButton}}"/> + <waitForPageLoad stepKey="waitForTaxSaved"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the configuration."/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml index 8e52800516dae..e0a3092c13321 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml @@ -10,7 +10,11 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminConfigureTaxSection"> <!-- on page /admin/admin/system_config/edit/section/tax/ --> + <element name="salesTax" type="button" selector="//a[contains(@class, 'admin__page-nav-link item-nav')]/span[text()='Tax']"/> <element name="taxClasses" type="block" selector="#tax_classes-head" timeout="30"/> + <element name="taxClassShipping" type="select" selector="#tax_classes_shipping_tax_class"/> + <element name="taxClassProduct" type="select" selector="#tax_classes_default_product_tax_class"/> + <element name="taxClassCustomer" type="select" selector="#tax_classes_default_customer_tax_class"/> <element name="taxCalculationSettings" type="block" selector="#tax_calculation-head" timeout="30"/> <element name="taxCalculationSettingsOpened" type="block" selector="#tax_calculation-head.open" timeout="30"/> From c7a140ea0d878c43699d535b3c307ed2ffc5f7a0 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 16:02:50 +0300 Subject: [PATCH 1079/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 91454e8b3de78..58c3b79022a62 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -114,7 +114,7 @@ define([ /** * - * @param {Array} - recordData to reprocess + * @param {Array} recordData - to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { From 50fb1cc2f50ac0b4e0c892ce474bc6c3b770cc7a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 8 Nov 2018 15:25:05 +0200 Subject: [PATCH 1080/1415] MAGETWO-96063: [TSG] Pull Request MFTF 8 stabilization --- .../Test/Mftf/Page/AdminConfigPage.xml | 12 ++++ ...> AdminConfigAdvancedReportingSection.xml} | 7 +- .../AdminConfigurationBlankIndustryTest.xml | 15 ++-- ...onfigurationEnableDisableAnalyticsTest.xml | 35 +++++----- .../Test/AdminConfigurationIndustryTest.xml | 13 ++-- .../Test/AdminConfigurationPermissionTest.xml | 69 ++++++++++--------- .../AdminConfigurationTimeToSendDataTest.xml | 18 +++-- .../BraintreeCreditCardOnCheckoutTest.xml | 2 +- ...CategoryProductsUsingScopeSelectorTest.xml | 8 +-- ...efrontPurchaseProductWithCustomOptions.xml | 15 ++-- ...ctWithCustomOptionsWithLongValuesTitle.xml | 9 ++- .../ActionGroup/AdminCheckoutActionGroup.xml | 18 +++++ .../Mftf/ActionGroup/CheckoutActionGroup.xml | 14 +++- .../StorefrontProductCartActionGroup.xml | 4 +- .../Section/AdminCheckoutPaymentSection.xml | 14 ++++ .../Mftf/Section/CheckoutPaymentSection.xml | 2 +- ...StorefrontCheckoutPaymentMethodSection.xml | 15 ++++ .../Mftf/Test/StorefrontGuestCheckoutTest.xml | 1 + .../Test/Mftf/Section/AdminConfigSection.xml | 5 +- .../Test/Mftf/Test/AdminCreateInvoiceTest.xml | 1 + .../Mftf/Test/StorefrontTaxQuoteCartTest.xml | 4 ++ ...AssertBundleProductOnConfigureCartPage.php | 5 ++ .../app/Magento/Checkout/Test/Block/Cart.php | 17 +++++ .../Checkout/Test/Block/Cart/Shipping.php | 54 +++++++++++++++ .../Checkout/Test/Block/Cart/Totals.php | 11 +++ .../Constraint/AssertCartItemsOptions.php | 5 ++ .../AssertGrandTotalInShoppingCart.php | 4 ++ .../Constraint/AssertPriceInShoppingCart.php | 5 ++ .../AssertProductQtyInShoppingCart.php | 5 ++ .../AssertSubtotalInShoppingCart.php | 4 ++ .../Constraint/Utils/CartPageLoadTrait.php | 30 ++++++++ ...eProductFromMiniShoppingCartEntityTest.php | 1 + .../ProductsInCartReportEntityTest.php | 2 + ...oveShoppingCartProductsOnOrderPageTest.php | 1 + 34 files changed, 327 insertions(+), 98 deletions(-) create mode 100644 app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml rename app/code/Magento/Analytics/Test/Mftf/Section/{AdminConfigSection.xml => AdminConfigAdvancedReportingSection.xml} (86%) create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml create mode 100644 dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php diff --git a/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml new file mode 100644 index 0000000000000..c4ced12e67e07 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminConfigGeneralAnalyticsPage" url="admin/system_config/edit/section/analytics/" area="admin" module="Magento_Config"> + <section name="AdminConfigAdvancedReportingSection"/> + </page> +</pages> diff --git a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml similarity index 86% rename from app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml rename to app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml index f8554a4ea115b..2e5f2b762a7b1 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml @@ -6,8 +6,8 @@ */ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="AdminConfigSection"> - <element name="advancedReportingMenuItem" type="text" selector="//*[@id='system_config_tabs']/div[1]//span[text()='Advanced Reporting']"/> + <section name="AdminConfigAdvancedReportingSection"> + <element name="advancedReportingMenuItem" type="text" selector="//*[@class='admin__page-nav-link item-nav']//span[text()='Advanced Reporting']"/> <element name="advancedReportingService" type="select" selector="#analytics_general_enabled"/> <element name="advancedReportingServiceLabel" type="text" selector="#row_analytics_general_enabled>td.label>label>span"/> <element name="advancedReportingServiceStatus" type="text" selector="#row_analytics_general_enabled>td.value>p>span"/> @@ -17,6 +17,5 @@ <element name="advancedReportingMinute" type="select" selector="#row_analytics_general_collection_time>td:nth-child(2)>select:nth-child(3)"/> <element name="advancedReportingSeconds" type="select" selector="#row_analytics_general_collection_time>td:nth-child(2)>select:nth-child(4)"/> <element name="advancedReportingBlankIndustryError" type="text" selector=".message-error>div"/> - <element name="advancedReportingSuccessMessage" type="text" selector=".message-success>div"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml index ff89ca9b663ee..914cb59b64e4e 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml @@ -18,15 +18,14 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <waitForPageLoad stepKey="waitForAdminConfig"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="--Please Select--"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeBlankIndustryErrorMessage" selector="{{AdminConfigSection.advancedReportingBlankIndustryError}}" userInput="Please select an industry."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="--Please Select--" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingBlankIndustryError}}" userInput="Please select an industry." stepKey="seeBlankIndustryErrorMessage"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml index 1706383fc7866..1c1a3b27b06af 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml @@ -18,27 +18,24 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <!--Goto admin stores configure page --> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <!--Enable Advanced Reporting--> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingServiceLabelEnabled" selector="{{AdminConfigSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service"/> - <selectOption stepKey="selectAdvancedReportingServiceEnabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Enable"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <click stepKey="clickSaveConfigButtonEnabled" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeSaveConfigurationMessageEnabled" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> - <see stepKey="seeAdvancedReportingServiceEnabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Enable"/> - <see stepKey="seeAdvancedReportingServiceStatusEnabled" selector="{{AdminConfigSection.advancedReportingServiceStatus}}" userInput="Subscription status: Pending"/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service" stepKey="seeAdvancedReportingServiceLabelEnabled"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton1"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="seeAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceStatus}}" userInput="Subscription status: Pending" stepKey="seeAdvancedReportingServiceStatusEnabled"/> <!--Disable Advanced Reporting--> - <see stepKey="seeAdvancedReportingServiceLabelDisabled" selector="{{AdminConfigSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service"/> - <selectOption stepKey="selectAdvancedReportingServiceDisabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Disable"/> - <click stepKey="clickSaveConfigButtonDisabled" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeSaveConfigurationMessageDisabled" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> - <see stepKey="seeAdvancedReportingServiceDisabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Disable"/> - <see stepKey="seeAdvancedReportingServiceStatusDisabled" selector="{{AdminConfigSection.advancedReportingServiceStatus}}" userInput="Subscription status: Disabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service" stepKey="seeAdvancedReportingServiceLabelDisabled"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Disable" stepKey="selectAdvancedReportingServiceDisabled"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton2"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess2"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Disable" stepKey="seeAdvancedReportingServiceDisabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceStatus}}" userInput="Subscription status: Disabled" stepKey="seeAdvancedReportingServiceStatusDisabled"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index dcfdca9e8edd7..bb682c4468012 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -20,12 +20,11 @@ </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeIndustrySuccessMessage" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml index 5414e9c2a5c18..58e809ec45c4a 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml @@ -19,44 +19,47 @@ <group value="analytics"/> </annotations> <before> - <createData stepKey="noReportUserRole" entity="adminNoReportRole"/> - <createData stepKey="noReportUser" entity="adminNoReport"/> + <createData entity="adminNoReportRole" stepKey="noReportUserRole"/> + <createData entity="adminNoReport" stepKey="noReportUser"/> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> - <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + <amOnPage url="{{AdminUsersPage.url}}" stepKey="amOnAdminUsersPage"/> + <fillField selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="$$noReportUser.username$$" stepKey="fillUsernameSearch"/> + <click selector="{{AdminUserGridSection.searchButton}}" stepKey="clickSearchButton"/> + <waitForPageLoad time="10" stepKey="wait1"/> + <see selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="$$noReportUser.username$$" stepKey="seeFoundUsername"/> + <click selector="{{AdminUserGridSection.searchResultFirstRow}}" stepKey="clickFoundUsername"/> + <waitForPageLoad time="30" stepKey="wait2"/> + <seeInField selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$" stepKey="seeUsernameInField"/> + <fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="fillCurrentPassword"/> + <click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/> - <amOnPage stepKey="amOnAdminUsersPage" url="{{AdminUsersPage.url}}"/> - <fillField stepKey="fillUsernameSearch" selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="$$noReportUser.username$$"/> - <click stepKey="clickSearchButton" selector="{{AdminUserGridSection.searchButton}}"/> - <waitForPageLoad stepKey="wait1" time="10"/> - <see stepKey="seeFoundUsername" selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="$$noReportUser.username$$"/> - <click stepKey="clickFoundUsername" selector="{{AdminUserGridSection.searchResultFirstRow}}"/> - <waitForPageLoad stepKey="wait2" time="30"/> - <seeInField stepKey="seeUsernameInField" selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$"/> - <fillField stepKey="fillCurrentPassword" selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> - <click stepKey="clickUserRoleTab" selector="{{AdminEditUserSection.userRoleTab}}"/> + <fillField selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$" stepKey="fillRoleNameSearch"/> + <click selector="{{AdminEditUserSection.searchButton}}" stepKey="clickSearchButtonUserRole"/> + <waitForPageLoad time="10" stepKey="wait3"/> + <see selector="{{AdminEditUserSection.roleNameInFirstRow}}" userInput="$$noReportUserRole.rolename$$" stepKey="seeFoundRoleName"/> + <click selector="{{AdminEditUserSection.searchResultFirstRow}}" stepKey="clickFoundRoleName"/> + <click selector="{{AdminEditUserSection.saveButton}}" stepKey="clickSaveButton"/> + <waitForPageLoad time="10" stepKey="wait4"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the user." stepKey="seeSuccess"/> - <fillField stepKey="fillRoleNameSearch" selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$"/> - <click stepKey="clickSearchButtonUserRole" selector="{{AdminEditUserSection.searchButton}}"/> - <waitForPageLoad stepKey="wait3" time="10"/> - <see stepKey="seeFoundRoleName" selector="{{AdminEditUserSection.roleNameInFirstRow}}" userInput="$$noReportUserRole.rolename$$"/> - <click stepKey="clickFoundRoleName" selector="{{AdminEditUserSection.searchResultFirstRow}}"/> - <click stepKey="clickSaveButton" selector="{{AdminEditUserSection.saveButton}}"/> - <waitForPageLoad stepKey="wait4" time="10"/> - <see stepKey="saveUserSuccessMessage" selector="{{AdminUserGridSection.successMessage}}" userInput="You saved the user."/> + <amOnPage url="{{AdminConfigPage.url}}" stepKey="amOnAdminConfig"/> + <conditionalClick selector="{{AdminConfigSection.generalTab}}" dependentSelector="{{AdminConfigSection.generalTabOpened}}" visible="false" stepKey="openGeneralTabIfClosed"/> + <scrollTo selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="scrollToMenuItem"/> + <!--<see stepKey="seeAdvancedReportingConfigMenuItem" selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/>--> + <seeElementInDOM selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="seeAdvancedReportingConfigMenuItem"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin2"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <see stepKey="seeAdvancedReportingConfigMenuItem" selector="{{AdminConfigSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/> - <amOnPage stepKey="amOnLogoutPage2" url="admin/admin/auth/logout/"/> - - <amOnPage stepKey="amOnAdminLoginPage" url="{{AdminLoginPage.url}}"/> - <fillField stepKey="fillUsernameNoReport" selector="{{AdminLoginFormSection.username}}" userInput="$$noReportUser.username$$"/> - <fillField stepKey="fillPasswordNoReport" selector="{{AdminLoginFormSection.password}}" userInput="$$noReportUser.password$$"/> - <click stepKey="clickOnSignIn2" selector="{{AdminLoginFormSection.signIn}}"/> - <waitForPageLoad stepKey="wait5" time="10"/> - <amOnPage stepKey="amOnAdminConfig2" url="{{AdminConfigPage.url}}"/> - <dontSee stepKey="dontSeeAdvancedReportingConfigMenuItem" selector="{{AdminConfigSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/> + <amOnPage url="{{AdminLoginPage.url}}" stepKey="amOnAdminLoginPage"/> + <fillField selector="{{AdminLoginFormSection.username}}" userInput="$$noReportUser.username$$" stepKey="fillUsernameNoReport"/> + <fillField selector="{{AdminLoginFormSection.password}}" userInput="$$noReportUser.password$$" stepKey="fillPasswordNoReport"/> + <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickOnSignIn2"/> + <waitForPageLoad time="10" stepKey="wait5"/> + <amOnPage url="{{AdminConfigPage.url}}" stepKey="amOnAdminConfig2"/> + <conditionalClick selector="{{AdminConfigSection.generalTab}}" dependentSelector="{{AdminConfigSection.generalTabOpened}}" visible="false" stepKey="openGeneralTabIfClosed2"/> + <dontSeeElementInDOM selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="dontSeeAdvancedReportingConfigMenuItem"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 3f17df108b50b..9dc967971f63a 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -19,17 +19,15 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <waitForPageLoad stepKey="waitForAdminConfig"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <selectOption stepKey="selectAdvancedReportingHour" selector="{{AdminConfigSection.advancedReportingHour}}" userInput="11"/> - <selectOption stepKey="selectAdvancedReportingMinute" selector="{{AdminConfigSection.advancedReportingMinute}}" userInput="11"/> - <selectOption stepKey="selectAdvancedReportingSeconds" selector="{{AdminConfigSection.advancedReportingSeconds}}" userInput="00"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeBlankIndustryErrorMessage" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="00" stepKey="selectAdvancedReportingSeconds"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> </tests> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml index 114c79189101a..2b5d60bea24e1 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -65,7 +65,7 @@ <actionGroup ref="StorefrontFillCartDataActionGroup" stepKey="StorefrontFillCartDataActionGroup"/> <waitForPageLoad stepKey="waitForPageLoad4"/> <!--Place order--> - <click selector="{{BraintreeConfigurationPaymentSection.paymentMethodContainer}} {{CheckoutPaymentSection.placeOrder}}" + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="PlaceOrder"/> <waitForPageLoad stepKey="waitForPageLoad5"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index a4bd507d98f55..a748635ac9a53 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -129,8 +129,8 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('Default Store View')}}" stepKey="clickStoreView"/> - <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" - stepKey="waitForModalAccept"/> + <waitForElementVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForPopup1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept"/> <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="waitForNotVisibleModalAccept"/> @@ -152,8 +152,8 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad3"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('secondStoreView')}}" stepKey="clickStoreView1"/> - <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" - stepKey="waitForModalAccept1"/> + <waitForElementVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForPopup2"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept1"/> <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml index 6b444f1f6663b..c845a27773170 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml @@ -103,12 +103,15 @@ <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="Jan 1, 2018" stepKey="seeProductOptionDateAndTimeInput" /> <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="1/1/18, 1:00 AM" stepKey="seeProductOptionDataInput" /> <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="1:00 AM" stepKey="seeProductOptionTimeInput" /> - + <!--Select shipping method--> + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> - + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> + <!--Select payment method--> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> <!-- Place Order --> - - <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> @@ -119,6 +122,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> @@ -141,6 +145,7 @@ <!-- Reorder and Checking the correctness of displayed custom options for user parameters on Order and correctness of displayed price Subtotal--> <click selector="{{AdminOrderDetailsMainActionsSection.reorder}}" stepKey="clickReorder"/> + <actionGroup ref="AdminCheckoutSelectCheckMoneyOrderBillingMethodActionGroup" stepKey="selectBillingMethod"/> <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="trySubmitOrder"/> <see selector="{{AdminOrderItemsOrderedSection.productNameOptions}}" userInput="{{ProductOptionField.title}}" stepKey="seeAdminOrderProductOptionField1" /> @@ -179,4 +184,4 @@ <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> </test> -</tests> \ No newline at end of file +</tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml index a03636e52ee97..fcdb92d71f1f8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml @@ -71,11 +71,17 @@ <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($$createProduct.name$$)}}" userInput="{{ProductOptionValueDropdownLongTitle1.title}}" stepKey="seeProductOptionValueDropdown1Input1"/> + <!--Select shipping method--> + + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> <!-- Place Order --> - <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> @@ -86,6 +92,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml new file mode 100644 index 0000000000000..a29564b2457a9 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Checkout select Check/Money billing method --> + <actionGroup name="AdminCheckoutSelectCheckMoneyOrderBillingMethodActionGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <conditionalClick selector="{{AdminCheckoutPaymentSection.checkBillingMethodByName('Check / Money order')}}" dependentSelector="{{AdminCheckoutPaymentSection.checkBillingMethodByName('Check / Money order')}}" visible="true" stepKey="selectCheckmoBillingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterBillingMethodSelection"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 41b1e0d811851..1d30fcaa752a9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -8,6 +8,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Checkout select Flat Rate shipping method --> + <actionGroup name="CheckoutSelectFlatRateShippingMethodActionGroup"> + <conditionalClick selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" dependentSelector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" visible="true" stepKey="selectFlatRateShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskForNextButton"/> + </actionGroup> + <!-- Go to checkout from minicart --> <actionGroup name="GoToCheckoutFromMinicartActionGroup"> <wait stepKey="wait" time="10" /> @@ -180,8 +186,10 @@ <!-- Checkout select Check/Money Order payment --> <actionGroup name="CheckoutSelectCheckMoneyOrderPaymentActionGroup"> - <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> - <conditionalClick selector="{{CheckoutPaymentSection.checkMoneyOrderPayment}}" dependentSelector="{{CheckoutPaymentSection.billingAddress}}" visible="false" stepKey="clickCheckMoneyOrderPayment" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <conditionalClick selector="{{StorefrontCheckoutPaymentMethodSection.checkPaymentMethodByName('Check / Money order')}}" dependentSelector="{{StorefrontCheckoutPaymentMethodSection.checkPaymentMethodByName('Check / Money order')}}" visible="true" stepKey="selectCheckmoPaymentMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterPaymentMethodSelection"/> </actionGroup> <!-- Check billing address in checkout --> @@ -228,4 +236,4 @@ <see userInput="You are signed out" stepKey="signOut"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..d832b7941c9d7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -84,6 +84,8 @@ <argument name="total"/> </arguments> <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> + <waitForPageLoad stepKey="waitPageFullyLoaded"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> @@ -109,4 +111,4 @@ <fillField stepKey="fillZip" selector="{{CheckoutCartSummarySection.postcode}}" userInput="{{taxCode.zip}}"/> <waitForPageLoad stepKey="waitForFormUpdate"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml new file mode 100644 index 0000000000000..2b5dd512bc4e4 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCheckoutPaymentSection"> + <element name="checkBillingMethodByName" type="radio" selector="//div[@id='order-billing_method']//dl[@class='admin__payment-methods']//dt//label[contains(., '{{methodName}}')]/..//input" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 846b20ed225dd..4a74ac8d60609 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -27,7 +27,7 @@ <element name="cartItemsArea" type="button" selector="div.block.items-in-cart"/> <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active"/> <element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/> - <element name="placeOrder" type="button" selector="button.action.primary.checkout" timeout="30"/> + <element name="placeOrder" type="button" selector=".payment-method._active button.action.primary.checkout" timeout="30"/> <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[text()='Payment Method']" /> <element name="orderSummarySubtotal" type="text" selector="//tr[@class='totals sub']//span[@class='price']" /> <element name="orderSummaryShippingTotal" type="text" selector="//tr[@class='totals shipping excl']//span[@class='price']" /> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml new file mode 100644 index 0000000000000..c06af54f030e7 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutPaymentMethodSection"> + <element name="billingAddress" type="text" selector=".checkout-billing-address"/> + <element name="checkPaymentMethodByName" type="radio" selector="//div[@id='checkout-payment-method-load']//div[@class='payment-method']//label//span[contains(., '{{methodName}}')]/../..//input" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index 02cc233acc7bc..f9533fd946f35 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -57,6 +57,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml index f4698b6865779..8a56c2777084e 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml @@ -8,5 +8,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminConfigSection"> <element name="saveButton" type="button" selector="#save"/> + <element name="generalTab" type="text" selector="//div[@class='admin__page-nav-title title _collapsible']//strong[text()='General']"/> + <element name="generalTabClosed" type="text" selector="//div[@class='admin__page-nav-title title _collapsible' and @aria-expanded='false' or @aria-expanded='0']//strong[text()='General']"/> + <element name="generalTabOpened" type="text" selector="//div[@class='admin__page-nav-title title _collapsible' and @aria-expanded='true' or @aria-expanded='1']//strong[text()='General']"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 0032a6c987e82..24266b5bcfe9f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -61,6 +61,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask3"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="searchOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 3b741e7bf79ec..65cde53d144e7 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -92,6 +92,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> @@ -208,6 +209,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> @@ -314,6 +316,7 @@ <!-- Assert that taxes are applied correctly for CA --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> @@ -420,6 +423,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <!-- Assert that taxes are applied correctly for CA --> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php index efa75981db7bf..b97a954a981b2 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php @@ -8,6 +8,7 @@ use Magento\Bundle\Test\Fixture\BundleProduct; use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Constraint\AbstractAssertForm; @@ -17,6 +18,8 @@ */ class AssertBundleProductOnConfigureCartPage extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Check bundle product options correctly displayed on cart configuration page. * @@ -28,6 +31,8 @@ class AssertBundleProductOnConfigureCartPage extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart, CatalogProductView $catalogProductView) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); foreach ($cart->getItems() as $key => $item) { diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php index b0e996355642a..bbe6fe293ab50 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php @@ -106,6 +106,13 @@ class Cart extends Block */ protected $cartItemClass = \Magento\Checkout\Test\Block\Cart\CartItem::class; + /** + * Locator for page with ajax loading state. + * + * @var string + */ + private $ajaxLoading = 'body.ajax-loading'; + /** * Wait for PayPal page is loaded. * @@ -273,4 +280,14 @@ public function waitForCheckoutButton() { $this->waitForElementVisible($this->inContextPaypalCheckoutButton); } + + /** + * Wait loading. + * + * @return void + */ + public function waitForLoader() + { + $this->waitForElementNotVisible($this->ajaxLoading); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php index 10299486a08ce..3d293700db8c9 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php @@ -72,6 +72,13 @@ class Shipping extends Form */ protected $commonShippingPriceSelector = '.totals.shipping .price'; + /** + * Estimate shipping and tax form locator. + * + * @var string + */ + private $estimateShippingForm = '#shipping-zip-form'; + /** * Open estimate shipping and tax form. * @@ -250,4 +257,51 @@ public function waitForCommonShippingPriceBlock() { $this->waitForElementVisible($this->commonShippingPriceSelector, Locator::SELECTOR_CSS); } + + /** + * Wait until estimation form to appear. + * + * @return void + */ + public function waitForEstimateShippingAndTaxForm() + { + $browser = $this->browser; + $selector = $this->estimateShippingForm; + + $browser->waitUntil( + function () use ($browser, $selector) { + $element = $browser->find($selector); + return $element->isPresent() ? true : null; + } + ); + } + + /** + * Wait for shipping method form. + * + * @return void + */ + public function waitForShippingMethodForm() + { + $browser = $this->browser; + $selector = $this->shippingMethodForm; + + $browser->waitUntil( + function () use ($browser, $selector) { + $element = $browser->find($selector); + return $element->isPresent() ? true : null; + } + ); + } + + /** + * Wait for summary block to be loaded. + * + * @return void + */ + public function waitForSummaryBlock() + { + $this->waitForEstimateShippingAndTaxForm(); + $this->waitForShippingMethodForm(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php index fda29a2fe78fc..f632cdc3d7464 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php @@ -264,4 +264,15 @@ public function waitForShippingPriceBlock() { $this->waitForElementVisible($this->shippingPriceBlockSelector, Locator::SELECTOR_CSS); } + + /** + * Wait for "Grand Total" row to appear. + * + * @return void + */ + public function waitForGrandTotal() + { + $this->waitForUpdatedTotals(); + $this->waitForElementVisible($this->grandTotal); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php index 144e41dca0d92..b0ed9d358f93a 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -21,6 +22,8 @@ */ class AssertCartItemsOptions extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Error message for verify options * @@ -44,6 +47,8 @@ class AssertCartItemsOptions extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php index 9bedda350d065..432bbd4f2146e 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php @@ -6,6 +6,7 @@ namespace Magento\Checkout\Test\Constraint; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Constraint\AbstractConstraint; @@ -16,6 +17,8 @@ */ class AssertGrandTotalInShoppingCart extends AbstractConstraint { + use CartPageLoadTrait; + /** * Assert that grand total is equal to expected * @@ -28,6 +31,7 @@ public function processAssert(CheckoutCart $checkoutCart, Cart $cart, $requireRe { if ($requireReload) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); $checkoutCart->getTotalsBlock()->waitForUpdatedTotals(); } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php index 42c79c1280e38..88d4a3e8d35ba 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertPriceInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that price in the shopping cart equals to expected price from data set * @@ -29,6 +32,8 @@ class AssertPriceInShoppingCart extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php index 40eb41e127245..b80b4c85227c0 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertProductQtyInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that quantity in the shopping cart is equals to expected quantity from data set * @@ -29,6 +32,8 @@ class AssertProductQtyInShoppingCart extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php index 2ee9caa251a74..5e743e735d42f 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertSubtotalInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that subtotal total in the shopping cart is equals to expected total from data set * @@ -31,6 +34,7 @@ public function processAssert(CheckoutCart $checkoutCart, Cart $cart, $requireRe { if ($requireReload) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); } /** @var Items $sourceProducts */ diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php new file mode 100644 index 0000000000000..fa349554fa139 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Checkout\Test\Constraint\Utils; + +use Magento\Checkout\Test\Page\CheckoutCart; + +/** + * Check if cart page is fully loaded. + */ +trait CartPageLoadTrait +{ + /** + * @param CheckoutCart $checkoutCart + * @return void + */ + public function waitForCartPageLoaded(CheckoutCart $checkoutCart) : void + { + $checkoutCart->getCartBlock()->waitForLoader(); + if (!$checkoutCart->getCartBlock()->cartIsEmpty()) { + $checkoutCart->getShippingBlock()->waitForSummaryBlock(); + $checkoutCart->getTotalsBlock()->waitForGrandTotal(); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php index 5935a68c43c21..af267cfa30ec1 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php @@ -115,6 +115,7 @@ public function test( } else { $miniShoppingCart->getCartItem($newProduct)->clickEditItem(); $this->catalogProductView->getViewBlock()->addToCart($newProduct); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); } // Prepare data for asserts: $cart['data']['items'] = ['products' => [$newProduct]]; diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php index 30e790f978c42..1a4cb787bf1c7 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php @@ -102,10 +102,12 @@ public function test( $productUrl = $_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'; $browser->open($productUrl); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); if ($isGuest) { $this->objectManager->create(\Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep::class)->run(); $browser->open($productUrl); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php index 2b0bd7178cdad..91b4f711700b5 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php @@ -144,6 +144,7 @@ public function test(Customer $customer, $product) )->run(); $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); //Steps $this->customerIndex->open(); From 3de065bfeefbe324d1db903800efb6a95824e076 Mon Sep 17 00:00:00 2001 From: Rain2o <jrainwater@thinkpyxl.com> Date: Wed, 11 Jul 2018 17:29:24 -0400 Subject: [PATCH 1081/1415] Include multiselect options using custom source models --- .../Product/Indexer/Eav/Source.php | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index 3a61e7e364454..30b49dfeda103 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -24,22 +24,29 @@ class Source extends AbstractEav */ protected $_resourceHelper; - /** - * Construct - * - * @param \Magento\Framework\Model\ResourceModel\Db\Context $context - * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy - * @param \Magento\Eav\Model\Config $eavConfig - * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper - * @param null|string $connectionName - */ + /** + * @var \Magento\Eav\Api\AttributeRepositoryInterface + */ + protected $_attributeRepository; + + /** + * Construct + * + * @param \Magento\Framework\Model\ResourceModel\Db\Context $context + * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy + * @param \Magento\Eav\Model\Config $eavConfig + * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository + * @param null|string $connectionName + */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy, \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, + \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, $connectionName = null ) { parent::__construct( @@ -50,6 +57,7 @@ public function __construct( $connectionName ); $this->_resourceHelper = $resourceHelper; + $this->_attributeRepository = $attributeRepository; } /** @@ -234,6 +242,9 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu $options[$row['attribute_id']][$row['option_id']] = true; } + // Include custom source model options + $options = $this->_getMultiSelectAttributeWithSourceModels($attrIds, $options); + // prepare get multiselect values query $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value'); $select = $connection->select()->from( @@ -297,6 +308,46 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu return $this; } + /** + * Get options for multiselect attributes using custom source models + * @maderlock's fix from: https://github.com/magento/magento2/issues/417#issuecomment-265146285 + * + * @param array $attrIds + * @param array $options + * + * @return array + * @throws \Zend_Db_Statement_Exception + */ + protected function _getMultiSelectAttributeWithSourceModels( $attrIds, $options ) { + // Add options from custom source models + $select = $this->getConnection()->select() + ->from( + ['ea' => $this->getTable('eav_attribute')], + ['attribute_id','entity_type_id', 'attribute_code'] + ) + ->where('attribute_id IN(?)', $attrIds) + ->where('source_model is not null'); + $query = $select->query(); + + while ($row = $query->fetch()) { + try { + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ + $attribute = $this->_attributeRepository->get($row['entity_type_id'], $row['attribute_code']); + $sourceModelOptions = $attribute->getOptions(); + // Add options to list used below + foreach ($sourceModelOptions as $o) { + $options[$row['attribute_id']][$o->getValue()] = true; + } + } catch (\BadMethodCallException $e) { + // Skip + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + // skip + } + } + + return $options; + } + /** * Save a data to temporary source index table * From c6352c6c9166eba48d86852774b876ecaf34ebd8 Mon Sep 17 00:00:00 2001 From: Rain2o <jrainwater@thinkpyxl.com> Date: Thu, 12 Jul 2018 10:34:35 -0400 Subject: [PATCH 1082/1415] Fixed PHP sniffer errors. --- .../Product/Indexer/Eav/Source.php | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index 30b49dfeda103..ab09171a6f2ed 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -24,29 +24,29 @@ class Source extends AbstractEav */ protected $_resourceHelper; - /** - * @var \Magento\Eav\Api\AttributeRepositoryInterface - */ + /** + * @var \Magento\Eav\Api\AttributeRepositoryInterface + */ protected $_attributeRepository; - /** - * Construct - * - * @param \Magento\Framework\Model\ResourceModel\Db\Context $context - * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy - * @param \Magento\Eav\Model\Config $eavConfig - * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper - * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository - * @param null|string $connectionName - */ + /** + * Construct + * + * @param \Magento\Framework\Model\ResourceModel\Db\Context $context + * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy + * @param \Magento\Eav\Model\Config $eavConfig + * @param \Magento\Framework\Event\ManagerInterface $eventManager + * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository + * @param null|string $connectionName + */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy, \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, - \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, + \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, $connectionName = null ) { parent::__construct( @@ -242,8 +242,8 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu $options[$row['attribute_id']][$row['option_id']] = true; } - // Include custom source model options - $options = $this->_getMultiSelectAttributeWithSourceModels($attrIds, $options); + // Include custom source model options + $options = $this->_getMultiSelectAttributeWithSourceModels($attrIds, $options); // prepare get multiselect values query $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value'); @@ -308,45 +308,46 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu return $this; } - /** - * Get options for multiselect attributes using custom source models - * @maderlock's fix from: https://github.com/magento/magento2/issues/417#issuecomment-265146285 - * - * @param array $attrIds - * @param array $options - * - * @return array - * @throws \Zend_Db_Statement_Exception - */ - protected function _getMultiSelectAttributeWithSourceModels( $attrIds, $options ) { - // Add options from custom source models - $select = $this->getConnection()->select() - ->from( - ['ea' => $this->getTable('eav_attribute')], - ['attribute_id','entity_type_id', 'attribute_code'] - ) - ->where('attribute_id IN(?)', $attrIds) - ->where('source_model is not null'); - $query = $select->query(); - - while ($row = $query->fetch()) { - try { - /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ - $attribute = $this->_attributeRepository->get($row['entity_type_id'], $row['attribute_code']); - $sourceModelOptions = $attribute->getOptions(); - // Add options to list used below - foreach ($sourceModelOptions as $o) { - $options[$row['attribute_id']][$o->getValue()] = true; - } - } catch (\BadMethodCallException $e) { - // Skip - } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { - // skip - } - } - - return $options; - } + /** + * Get options for multiselect attributes using custom source models + * @maderlock's fix from: https://github.com/magento/magento2/issues/417#issuecomment-265146285 + * + * @param array $attrIds + * @param array $options + * + * @return array + * @throws \Zend_Db_Statement_Exception + */ + protected function _getMultiSelectAttributeWithSourceModels($attrIds, $options) + { + // Add options from custom source models + $select = $this->getConnection()->select() + ->from( + ['ea' => $this->getTable('eav_attribute')], + ['attribute_id','entity_type_id', 'attribute_code'] + ) + ->where('attribute_id IN(?)', $attrIds) + ->where('source_model is not null'); + $query = $select->query(); + + while ($row = $query->fetch()) { + try { + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ + $attribute = $this->_attributeRepository->get($row['entity_type_id'], $row['attribute_code']); + $sourceModelOptions = $attribute->getOptions(); + // Add options to list used below + foreach ($sourceModelOptions as $o) { + $options[$row['attribute_id']][$o->getValue()] = true; + } + } catch (\BadMethodCallException $e) { + // Skip + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + // skip + } + } + + return $options; + } /** * Save a data to temporary source index table From cb69dcc551dd99d0bd7c1829c420d796d77847ec Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 8 Nov 2018 16:05:07 +0200 Subject: [PATCH 1083/1415] MAGETWO-95829: Product positions are incorrect after import - Fixed to correct zero position during product import process - Fixed to correct sorting position on admin Category edit page --- .../Magento/Catalog/Model/Category/Product/PositionResolver.php | 2 ++ .../Test/Unit/Model/Category/Product/PositionResolverTest.php | 2 +- app/code/Magento/CatalogImportExport/Model/Import/Product.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php index 1e07c0cdd924e..44bf153f83697 100644 --- a/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php +++ b/app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php @@ -43,6 +43,8 @@ public function getPositions(int $categoryId): array $categoryId )->order( 'ccp.position ' . \Magento\Framework\DB\Select::SQL_ASC + )->order( + 'ccp.product_id ' . \Magento\Framework\DB\Select::SQL_DESC ); return array_flip($connection->fetchCol($select)); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php index 1ff3a1bae5c28..7ad8b1a0ab3f8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Product/PositionResolverTest.php @@ -107,7 +107,7 @@ public function testGetPositions() $this->select->expects($this->once()) ->method('where') ->willReturnSelf(); - $this->select->expects($this->once()) + $this->select->expects($this->exactly(2)) ->method('order') ->willReturnSelf(); $this->select->expects($this->once()) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 6f8b2248d8d89..ce699b73131f1 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1423,7 +1423,7 @@ protected function _saveProductCategories(array $categoriesData) $delProductId[] = $productId; foreach (array_keys($categories) as $categoryId) { - $categoriesIn[] = ['product_id' => $productId, 'category_id' => $categoryId, 'position' => 1]; + $categoriesIn[] = ['product_id' => $productId, 'category_id' => $categoryId, 'position' => 0]; } } if (Import::BEHAVIOR_APPEND != $this->getBehavior()) { From 7bedc1a87767a148468586906eb68f76fae84a94 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 8 Nov 2018 16:07:46 +0200 Subject: [PATCH 1084/1415] magento-engcom/magento2ce#2316: Skipped MFTF test --- .../Test/Mftf/Test/AdminConfigurationIndustryTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index dcfdca9e8edd7..4b18fc7b98309 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-63898"/> <group value="analytics"/> + <skip> + <issueId value="MAGETWO-96223"/> + </skip> </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> From 7b3a047c27dc072938f85f7f0c0561d56c7ffd7c Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 8 Nov 2018 16:12:44 +0200 Subject: [PATCH 1085/1415] MAGETWO-96063: [TSG] Pull Request MFTF 8 stabilization --- .../Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 9dc967971f63a..58e62500b8203 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -23,6 +23,7 @@ </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> From f9acb655f01565c58d1df26643b4446407c4eb0a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:18:58 +0100 Subject: [PATCH 1086/1415] Added a separate resolver for returning category products count --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 - .../Magento/CatalogGraphQl/Model/Resolver/Category/Products.php | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index f0cdab9498abb..e783c749fdc6e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -52,7 +52,6 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData = $category->getData(); } else { $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); - $categoryData['product_count'] = $category->getProductCount(); } $categoryData['id'] = $category->getId(); $categoryData['children'] = []; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..59c21b6b0109d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5d62cb63f1662..7f31266ebf266 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -379,7 +379,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model level: Int @doc(description: "Indicates the depth of the category within the tree") created_at: String @doc(description: "Timestamp indicating when the category was created") updated_at: String @doc(description: "Timestamp indicating when the category was updated") - product_count: Int @doc(description: "The number of products in the category") + product_count: Int @doc(description: "The number of products in the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\ProductsCount") default_sort_by: String @doc(description: "The attribute to use for sorting") products( pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), From 9aacf0e0f9044c133786de725fbe5d926c0223d5 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:29:11 +0100 Subject: [PATCH 1087/1415] Missing resolver added --- .../Model/Resolver/Category/Products.php | 2 +- .../Model/Resolver/Category/ProductsCount.php | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 59c21b6b0109d..557c7e08ff432 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php new file mode 100644 index 0000000000000..397fd12b7e714 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Category; + +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product\Visibility; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\StockProcessor; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; + +/** + * Retrieves products count for a category + */ +class ProductsCount implements ResolverInterface +{ + /** + * @var Visibility + */ + private $catalogProductVisibility; + + /** + * @var StockProcessor + */ + private $stockProcessor; + + /** + * @var SearchCriteriaInterface + */ + private $searchCriteria; + + /** + * @param Visibility $catalogProductVisibility + * @param SearchCriteriaInterface $searchCriteria + * @param StockProcessor $stockProcessor + */ + public function __construct( + Visibility $catalogProductVisibility, + SearchCriteriaInterface $searchCriteria, + StockProcessor $stockProcessor + ) { + $this->catalogProductVisibility = $catalogProductVisibility; + $this->searchCriteria = $searchCriteria; + $this->stockProcessor = $stockProcessor; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + /** @var Category $category */ + $category = $value['model']; + $productsCollection = $category->getProductCollection(); + $productsCollection->setVisibility($this->catalogProductVisibility->getVisibleInSiteIds()); + $productsCollection = $this->stockProcessor->process($productsCollection, $this->searchCriteria, []); + + return $productsCollection->getSize(); + } +} From 53e6f67300259358f6e533c3eed8e0e939ca782f Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Thu, 8 Nov 2018 16:29:40 +0200 Subject: [PATCH 1088/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - add minor changes to test --- ...raintreeFill.xml => AdminOrderBraintreeFillActionGroup.xml} | 3 +-- ...etateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename app/code/Magento/Braintree/Test/Mftf/ActionGroup/{AdminOrderBraintreeFill.xml => AdminOrderBraintreeFillActionGroup.xml} (97%) diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFillActionGroup.xml similarity index 97% rename from app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml rename to app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFillActionGroup.xml index 6ef70b1f38660..c2e6af9dcd735 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFill.xml +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/AdminOrderBraintreeFillActionGroup.xml @@ -8,8 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminOrderBraintreeFill"> - + <actionGroup name="AdminOrderBraintreeFillActionGroup"> <!--Select Braintree Payment method on Admin Order Create Page--> <click stepKey="chooseBraintree" selector="{{NewOrderSection.creditCardBraintree}}"/> <waitForPageLoad stepKey="waitForBraintreeConfigs" time="5"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml index 470c425f3dae1..a7c0e8f62544e 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -92,7 +92,7 @@ <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> <!--Select Braintree online Payment method --> - <actionGroup ref="AdminOrderBraintreeFill" stepKey="selectCreditCardPayment"/> + <actionGroup ref="AdminOrderBraintreeFillActionGroup" stepKey="selectCreditCardPayment"/> <!--Submit Order--> <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> From c713b675dc4c473d9d001ec2ade980aeeaf254f3 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:39:28 +0100 Subject: [PATCH 1089/1415] Added test for setting shipping methods as guest for a customer cart --- .../Quote/SetShippingMethodOnCartTest.php | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php index 932c8ac386c27..7e77284c6b220 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -161,7 +161,35 @@ public function testSetShippingMethodWithNonExistingAddress() $this->sendRequestWithToken($query); } - // TODO: TBD - add check for guest with attempt to set shipping method to the customer's shopping cart + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodByGuestToCustomerCart() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage( + "The current user cannot perform operations on cart \"$maskedQuoteId\"" + ); + + $this->graphQlQuery($query); + } /** * Generates query for setting the specified shipping method on cart From 9b853a7303093342c2a29a17f3029da4428f8839 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 5 Nov 2018 15:42:06 -0600 Subject: [PATCH 1090/1415] MAGETWO-95906: Sales rules sets default time using UTC timezone when left empty --- .../Page/AdminConfigurationStoresPage.xml | 3 + .../Mftf/Section/LocaleOptionsSection.xml | 15 +++ .../StorefrontProductCartActionGroup.xml | 2 +- .../Controller/Adminhtml/Promo/Quote/Save.php | 38 ++++++- ...inCreateCartPriceRuleEmptyFromDateTest.xml | 104 ++++++++++++++++++ 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml index d1bf3c2cb2ed6..8afc2c5bbb32f 100644 --- a/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml +++ b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml @@ -14,4 +14,7 @@ <page name="WebConfigurationPage" url="admin/system_config/edit/section/web/" area="admin" module="Backend"> <section name="WYSIWYGOptionsSection"/> </page> + <page name="GeneralConfigurationPage" url="admin/system_config/edit/section/general/" area="admin" module="Backend"> + <section name="LocaleOptionsSection"/> + </page> </pages> diff --git a/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml new file mode 100644 index 0000000000000..c50bf0664f9cb --- /dev/null +++ b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="LocaleOptionsSection"> + <element name="sectionHeader" type="text" selector="#general_locale-head"/> + <element name="timezone" type="select" selector="#general_locale_timezone"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..1473618ceeb34 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -86,8 +86,8 @@ <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> - <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> <see userInput="({{shippingMethod}})" selector="{{CheckoutCartSummarySection.shippingMethod}}" stepKey="assertShippingMethod"/> + <waitForText userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" time="30" stepKey="assertShipping"/> <see userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" stepKey="assertTotal"/> </actionGroup> diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php index a5b71130e70eb..388679e6d9eff 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php @@ -6,8 +6,41 @@ */ namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote; -class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; + +/** + * SalesRule save controller + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpPostActionInterface { + /** + * @var TimezoneInterface + */ + private $timezone; + + /** + * @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 TimezoneInterface $timezone + */ + 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, + TimezoneInterface $timezone = null + ) { + parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter); + $this->timezone = $timezone ?? \Magento\Framework\App\ObjectManager::getInstance()->get( + TimezoneInterface::class + ); + } + /** * Promo quote save action * @@ -26,6 +59,9 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); + if (empty($data['from_date'])) { + $data['from_date'] = $this->timezone->formatDate(); + } $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml new file mode 100644 index 0000000000000..e6676dab4eb5e --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateCartPriceRuleEmptyFromDateTest"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Admin should be able to create a cart price rule with no starting date"/> + <description value="Admin should be able to create a cart price rule without specifying the from_date and it should be set with the current date"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-5299"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="SimpleProduct" stepKey="product"> + <requiredEntity createDataKey="category"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <!-- Delete the cart price rule we made during the test --> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{_defaultCoupon.code}}"/> + </actionGroup> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="product" stepKey="deleteProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Set timezone--> + <!--Set timezone so we need compare with the same timezone used in "generateDate" action--> + <amOnPage url="{{GeneralConfigurationPage.url}}" stepKey="goToGeneralConfig"/> + <waitForPageLoad stepKey="waitForConfigPage"/> + <wait stepKey="wait" time="10"/> + <conditionalClick selector="{{LocaleOptionsSection.sectionHeader}}" dependentSelector="{{LocaleOptionsSection.timezone}}" visible="false" stepKey="openLocaleSection"/> + <grabValueFrom selector="{{LocaleOptionsSection.timezone}}" stepKey="originalTimezone"/> + <selectOption selector="{{LocaleOptionsSection.timezone}}" userInput="America/Los_Angeles" stepKey="setTimezone"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfig"/> + + <!-- Create a cart price rule based on a coupon code --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForPriceList"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + + <!-- Verify initial successful save --> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + <fillField selector="{{AdminCartPriceRulesSection.filterByNameInput}}" userInput="{{_defaultCoupon.code}}" stepKey="filterByName"/> + <click selector="{{AdminCartPriceRulesSection.searchButton}}" stepKey="doFilter"/> + <see selector="{{AdminCartPriceRulesSection.nameColumns}}" userInput="{{_defaultCoupon.code}}" stepKey="seeRuleInResults"/> + + <!-- Verify further on the Rule's edit page --> + <click selector="{{AdminCartPriceRulesSection.rowContainingText(_defaultCoupon.code)}}" stepKey="goToEditRule"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="seeRuleName"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="seeWebsites"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="seeCouponType"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="seeCouponCode"/> + <generateDate date="now" format="m/j/Y" timezone="America/Los_Angeles" stepKey="today"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="$today" stepKey="seeCorrectFromDate"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.toDate}}" userInput="" stepKey="seeEmptyToDate"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions2"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="seeActionType"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="seeDiscountAmount"/> + + <!-- Spot check the storefront --> + <amOnPage url="$$product.custom_attributes[url_key]$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontApplyCouponActionGroup" stepKey="applyCoupon"> + <argument name="coupon" value="_defaultCoupon"/> + </actionGroup> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$5.00" stepKey="seeDiscountTotal"/> + + <!--Reset timezone--> + <amOnPage url="{{GeneralConfigurationPage.url}}" stepKey="goToGeneralConfigReset"/> + <waitForPageLoad stepKey="waitForConfigPageReset"/> + <conditionalClick selector="{{LocaleOptionsSection.sectionHeader}}" dependentSelector="{{LocaleOptionsSection.timezone}}" visible="false" stepKey="openLocaleSectionReset"/> + <selectOption selector="{{LocaleOptionsSection.timezone}}" userInput="$originalTimezone" stepKey="resetTimezone"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigReset"/> + </test> +</tests> From 13f4ad193092a153338418024facef621e598468 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 8 Nov 2018 08:41:45 -0600 Subject: [PATCH 1091/1415] MAGETWO-96192: Products with "Less Than", "Greater Than", "Less Than Or Equal", "Greater Than Or Equal" condition returns error on storefront - Added < and > to list of encoded characters --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 3 +++ ...oWYSIWYGWithCatalogProductListTypeTest.xml | 23 ++++++++++++++++++- .../Framework/Data/Wysiwyg/Normalizer.php | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index 92112661846c0..c7ea85e441bb9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -98,6 +98,9 @@ <element name="AddParam" type="button" selector=".rule-param-add"/> <element name="ConditionsDropdown" type="select" selector="#conditions__1__new_child"/> <element name="RuleParam" type="button" selector="//a[text()='...']"/> + <element name="RuleParamSelect" type="select" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//select" parameterized="true"/> + <element name="RuleParamInput" type="input" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//input" parameterized="true"/> + <element name="RuleParamLabel" type="input" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//a" parameterized="true"/> <element name="Chooser" type="button" selector="//img[@title='Open Chooser']"/> <element name="PageSize" type="input" selector="input[name='parameters[page_size]']"/> <element name="ProductAttribute" type="multiselect" selector="select[name='parameters[show_attributes][]']" /> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml index 705f2883f5839..2586ffc11d086 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml @@ -57,8 +57,29 @@ <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam" /> <waitForElementVisible selector="{{WidgetSection.Chooser}}" stepKey="waitForElement" /> <click selector="{{WidgetSection.Chooser}}" stepKey="clickChooser" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear3" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear4" /> <click selector="{{WidgetSection.PreCreateCategory('$$createPreReqCategory.name$$')}}" stepKey="selectPreCategory" /> + + <!-- Test that the "<" operand functions correctly --> + <click selector="{{WidgetSection.AddParam}}" stepKey="clickAddParamBtn2" /> + <waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}" stepKey="waitForDropdownVisible2"/> + <selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="Price" stepKey="selectPriceCondition"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear3"/> + <click selector="{{WidgetSection.RuleParamLabel('2','1')}}" stepKey="clickOperatorLabel"/> + <selectOption selector="{{WidgetSection.RuleParamSelect('2','1')}}" userInput="<" stepKey="selectLessThanCondition"/> + <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam2"/> + <fillField selector="{{WidgetSection.RuleParamInput('2','2')}}" userInput="125" stepKey="fillMaxPrice"/> + + <!-- Test that the ">" operand functions correctly --> + <click selector="{{WidgetSection.AddParam}}" stepKey="clickAddParamBtn3" /> + <waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}" stepKey="waitForDropdownVisible3"/> + <selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="Price" stepKey="selectPriceCondition2"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear5"/> + <click selector="{{WidgetSection.RuleParamLabel('3','1')}}" stepKey="clickOperatorLabel2"/> + <selectOption selector="{{WidgetSection.RuleParamSelect('3','1')}}" userInput=">" stepKey="selectLessThanCondition2"/> + <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam3"/> + <fillField selector="{{WidgetSection.RuleParamInput('3','2')}}" userInput="1" stepKey="fillMinPrice"/> + <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" /> <waitForPageLoad stepKey="wait6" /> <scrollTo selector="{{CmsNewPagePageSeoSection.header}}" stepKey="scrollToSearchEngineTab" /> diff --git a/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php index 62e7500a302a6..bbf10e9f574cf 100644 --- a/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php +++ b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php @@ -10,12 +10,13 @@ */ class Normalizer { - const WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP = [ '{' => '^[', '}' => '^]', '"' => '`', '\\' => '|', + '<' => '^(', + '>' => '^)' ]; /** From e5e7db172a906ae3baf94379d673db4856a78643 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 17:48:37 +0300 Subject: [PATCH 1092/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 58c3b79022a62..28553eaa41d12 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -128,7 +128,7 @@ define([ * Event handler for "Send to bottom" button * * @param {Object} positionObj - * @return {boolean} + * @return {Boolean} */ sendToBottom: function (positionObj) { @@ -152,7 +152,7 @@ define([ * Event handler for "Send to top" button * * @param {Object} positionObj - * @returns {boolean} + * @return {Boolean} */ sendToTop: function (positionObj) { var objectToUpdate = this.getObjectToUpdate(positionObj), @@ -189,7 +189,7 @@ define([ * Value function for position input * * @param {Object} data - * @return {number} + * @return {Number} */ getCalculatedPosition: function (data) { return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); @@ -198,7 +198,7 @@ define([ /** * Return Page Boundary * - * @return {number} + * @return {Number} */ getDefaultPageBoundary: function () { return ~~this.currentPage() * this.pageSize - 1; @@ -207,7 +207,7 @@ define([ /** * Returns position for last element to be moved after * - * @return {number} + * @return {Number} */ getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { From 803cdb1a15c3f6736c3674a8eb24aa8713992e63 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 09:23:21 -0600 Subject: [PATCH 1093/1415] ENGCOM-3408: #18956 Fixes for set root_category_id #18958 - fixed docblocks --- .../Model/Config/Importer/Processor/Create.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 71ffa5303293d..1fb9f1c224d3e 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -17,8 +17,6 @@ /** * The processor for creating of new entities. - * - * {@inheritdoc} */ class Create implements ProcessorInterface { @@ -85,7 +83,9 @@ public function __construct( /** * Creates entities in application according to the data set. * - * {@inheritdoc} + * @param array $data The data to be processed + * @return void + * @throws RuntimeException If processor was unable to finish execution */ public function run(array $data) { @@ -230,8 +230,7 @@ private function createStores(array $items, array $data) } /** - * Searches through given websites and compares with current websites. - * Returns found website. + * Searches through given websites and compares with current websites and returns found website. * * @param array $data The data to be searched in * @param string $websiteId The website id @@ -253,8 +252,7 @@ private function detectWebsiteById(array $data, $websiteId) } /** - * Searches through given groups and compares with current websites. - * Returns found group. + * Searches through given groups and compares with current websites and returns found group. * * @param array $data The data to be searched in * @param string $groupId The group id @@ -276,8 +274,7 @@ private function detectGroupById(array $data, $groupId) } /** - * Searches through given stores and compares with current stores. - * Returns found store. + * Searches through given stores and compares with current stores and returns found store. * * @param array $data The data to be searched in * @param string $storeId The store id From fad135663cc088694ef492a0d676c9a85e30450b Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 8 Nov 2018 09:47:07 -0600 Subject: [PATCH 1094/1415] MAGETWO-95770: Saved multi line attribute data displayed incorrectly on customer edit address page - Adjusted test --- .../Customer/Test/Unit/Model/Customer/DataProviderTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php index 50c21379054bf..d13c173cb12c2 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php @@ -649,10 +649,8 @@ public function testGetData() 2 => [ 'firstname' => 'firstname', 'lastname' => 'lastname', - 'street' => [ - 'street', - 'street', - ], + // Won't be an array because it isn't defined as a multiline field in this test + 'street' => "street\nstreet", 'default_billing' => 2, 'default_shipping' => 2, ] From a6aa2394b1674c428cf5c466dd92133aea1722c0 Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Thu, 8 Nov 2018 18:20:49 +0200 Subject: [PATCH 1095/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - add action --- .../Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml index 889db82db644d..357f496b1cba0 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml @@ -135,6 +135,7 @@ <waitForPageLoad stepKey="waitForTax" time="5"/> <seeInCurrentUrl url="{{AdminTaxConfigurationPage.url}}" stepKey="adminTaxConfiguration"/> <seeElement selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="taxClassSectionC"/> + <click selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="openTaxClassSection"/> <selectOption selector="{{AdminConfigureTaxSection.taxClassShipping}}" userInput="Taxable Goods" stepKey="setTaxClassForShipping"/> <!-- Save the settings --> <scrollToTopOfPage stepKey="scrollToTop"/> From f70f7f772f7ad16f115e989812a7462d0d8a2f39 Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Thu, 8 Nov 2018 18:56:16 +0200 Subject: [PATCH 1096/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - add element and action on it --- .../Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml | 1 + .../Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml index 357f496b1cba0..3009fa1fc8a25 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml @@ -136,6 +136,7 @@ <seeInCurrentUrl url="{{AdminTaxConfigurationPage.url}}" stepKey="adminTaxConfiguration"/> <seeElement selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="taxClassSectionC"/> <click selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="openTaxClassSection"/> + <click selector="{{AdminConfigureTaxSection.taxShippingClassSystem}}" stepKey="uncheckSystemValue"/> <selectOption selector="{{AdminConfigureTaxSection.taxClassShipping}}" userInput="Taxable Goods" stepKey="setTaxClassForShipping"/> <!-- Save the settings --> <scrollToTopOfPage stepKey="scrollToTop"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml index e0a3092c13321..681b3a37f506c 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml @@ -12,6 +12,7 @@ <!-- on page /admin/admin/system_config/edit/section/tax/ --> <element name="salesTax" type="button" selector="//a[contains(@class, 'admin__page-nav-link item-nav')]/span[text()='Tax']"/> <element name="taxClasses" type="block" selector="#tax_classes-head" timeout="30"/> + <element name="taxShippingClassSystem" type="checkbox" selector="#tax_classes_shipping_tax_class_inherit"/> <element name="taxClassShipping" type="select" selector="#tax_classes_shipping_tax_class"/> <element name="taxClassProduct" type="select" selector="#tax_classes_default_product_tax_class"/> <element name="taxClassCustomer" type="select" selector="#tax_classes_default_customer_tax_class"/> From 1862d2c02744a33a5b8b1a44eab53adf1bb79048 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 11:53:19 -0600 Subject: [PATCH 1097/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed docblock --- .../Framework/Interception/AbstractPlugin.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php index 60eb511dcb6b5..2a34f18fb0a0d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php @@ -7,25 +7,35 @@ /** * Class GeneralTest + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ abstract class AbstractPlugin extends \PHPUnit\Framework\TestCase { /** + * Config reader + * * @var \PHPUnit_Framework_MockObject_MockObject */ protected $_configReader; /** + * Object Manager + * * @var \Magento\Framework\ObjectManagerInterface */ protected $_objectManager; /** + * Applicartion Object Manager + * * @var \Magento\Framework\ObjectManagerInterface */ private $applicationObjectManager; + /** + * Set up + */ public function setUp() { if (!$this->_objectManager) { @@ -36,11 +46,17 @@ public function setUp() \Magento\Framework\App\ObjectManager::setInstance($this->_objectManager); } + /** + * Tear down + */ public function tearDown() { \Magento\Framework\App\ObjectManager::setInstance($this->applicationObjectManager); } + /** + * Set up Interception Config + */ public function setUpInterceptionConfig($pluginConfig) { $config = new \Magento\Framework\Interception\ObjectManager\Config\Developer(); From 2f5b730fa800c528e8f38da91154089f094090dc Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 11:54:35 -0600 Subject: [PATCH 1098/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed static test --- .../Framework/Interception/Config/CacheManagerTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php index 9d5abd1a8a6c6..6b0487d4afdae 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php @@ -40,7 +40,8 @@ protected function setUp() $this->serializer = $this->objectManager->get(\Magento\Framework\Serialize\SerializerInterface::class); $this->cache = $this->objectManager->get(\Magento\Framework\App\CacheInterface::class); - $this->configWriter = $this->objectManager->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); + $this->configWriter = + $this->objectManager->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); $this->initializeMetadataDirectory(); } @@ -125,7 +126,9 @@ private function getConfig() \Magento\Framework\Interception\Config\CacheManager::class, [ 'cacheId' => self::CACHE_ID, - 'compiledLoader' => $this->objectManager->create(\Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class), + 'compiledLoader' => $this->objectManager->create( + \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::class + ), ] ); } From 9135654c9f123ca8a22f0aa23677fa8222912e9a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 11:55:42 -0600 Subject: [PATCH 1099/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed docblock --- .../Magento/Framework/Interception/Config/CacheManager.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Interception/Config/CacheManager.php b/lib/internal/Magento/Framework/Interception/Config/CacheManager.php index cd16e2277d87a..a754215bbe743 100644 --- a/lib/internal/Magento/Framework/Interception/Config/CacheManager.php +++ b/lib/internal/Magento/Framework/Interception/Config/CacheManager.php @@ -9,8 +9,9 @@ namespace Magento\Framework\Interception\Config; /** - * Interception cache manager responsible for handling interaction with compiled and - * uncompiled interception data + * Interception cache manager. + * + * Responsible for handling interaction with compiled and uncompiled interception data */ class CacheManager { From 5db83d30c9ca29a0f6613932196c9b0f3bc89de8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 11:58:27 -0600 Subject: [PATCH 1100/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 Fixed dockblock --- .../Framework/Interception/Config/Config.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/Interception/Config/Config.php b/lib/internal/Magento/Framework/Interception/Config/Config.php index 4eeed4788a05e..7632970705fff 100644 --- a/lib/internal/Magento/Framework/Interception/Config/Config.php +++ b/lib/internal/Magento/Framework/Interception/Config/Config.php @@ -1,7 +1,5 @@ <?php /** - * Interception config. Responsible for providing list of plugins configured for instance - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -9,6 +7,11 @@ use Magento\Framework\Serialize\SerializerInterface; +/** + * Interception config. + * + * Responsible for providing list of plugins configured for instance + */ class Config implements \Magento\Framework\Interception\ConfigInterface { /** @@ -110,7 +113,8 @@ public function __construct( $this->_cacheId = $cacheId; $this->_reader = $reader; $this->_scopeList = $scopeList; - $this->cacheManager = $cacheManager ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CacheManager::class); + $this->cacheManager = + $cacheManager ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CacheManager::class); $intercepted = $this->cacheManager->load($cacheId); if ($intercepted !== null) { $this->_intercepted = $intercepted; @@ -166,7 +170,7 @@ protected function _inheritInterception($type) } /** - * {@inheritdoc} + * @inheritdoc */ public function hasPlugins($type) { @@ -193,7 +197,7 @@ private function initializeUncompiled($classDefinitions = []) /** * Generate intercepted array to store in compiled metadata or frontend cache * - * @param $classDefinitions + * @param array $classDefinitions */ private function generateIntercepted($classDefinitions) { From 40c58fc482c87a0840e2b1d05c3f951c30f140f2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 11:59:34 -0600 Subject: [PATCH 1101/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed docblock --- setup/src/Magento/Setup/Console/Command/DiCompileCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index ee26e71d94f30..014d699cb239d 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -103,7 +103,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { @@ -132,7 +132,7 @@ private function checkEnvironment() } /** - * {@inheritdoc} + * @inheritdoc */ protected function execute(InputInterface $input, OutputInterface $output) { From be71e3b26e103dbecffa1f9397b20f7e794e36f3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 12:01:00 -0600 Subject: [PATCH 1102/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed docblock --- .../src/Magento/Setup/Module/Di/App/Task/Operation/Area.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php index 7acc84e356c4d..edc2a485278a6 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php @@ -10,6 +10,9 @@ use Magento\Setup\Module\Di\Compiler\Config; use Magento\Setup\Module\Di\Definition\Collection as DefinitionsCollection; +/** + * Area configuration aggregation + */ class Area implements OperationInterface { /** @@ -67,7 +70,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function doOperation() { From b80d92d59882c4f686aa8e538ad167ef4630be43 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 12:02:10 -0600 Subject: [PATCH 1103/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed docblock --- .../Setup/Module/Di/Compiler/Config/Writer/Filesystem.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php index ee9321c5d4199..953dc04f4cd32 100644 --- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php +++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Writer/Filesystem.php @@ -11,6 +11,8 @@ use Magento\Setup\Module\Di\Compiler\Config\WriterInterface; /** + * Class for writing DI Compiler Configuration + * * @deprecated Moved to Framework to allow broader reuse * @see \Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem */ From 33435b7c4ac6ca2fdbaf07a393ba8d96f97de068 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 12:02:45 -0600 Subject: [PATCH 1104/1415] ENGCOM-3243: Write intercepted mapping to generated/metadata during compilation #18648 - Fixed static test --- .../Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php index 03b423bb32b0f..fbdbc951462e4 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php @@ -48,7 +48,8 @@ protected function setUp() $this->configReaderMock = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\Reader::class) ->disableOriginalConstructor() ->getMock(); - $this->configWriterMock = $this->getMockBuilder(\Magento\Framework\App\ObjectManager\ConfigWriterInterface::class) + $this->configWriterMock = + $this->getMockBuilder(\Magento\Framework\App\ObjectManager\ConfigWriterInterface::class) ->disableOriginalConstructor() ->getMock(); $this->configChain = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\ModificationChain::class) From 12d035d335e3d8903253cf00f155c35efb701df5 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 8 Nov 2018 13:29:50 -0600 Subject: [PATCH 1105/1415] MAGETWO-96192: Products with "Less Than", "Greater Than", "Less Than Or Equal", "Greater Than Or Equal" condition returns error on storefront - Updatd integration test --- .../Magento/Widget/Setup/LayoutUpdateConverterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php index 43c0bd202cc92..3d43fb5a44575 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php +++ b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php @@ -34,7 +34,7 @@ public function convertDataProvider() // @codingStandardsIgnoreStart $beginning = '<body><referenceContainer name="content"><block class="Magento\CatalogWidget\Block\Product\ProductsList" name="23e38bbfa7cc6474454570e51aeffcc3" template="Magento_CatalogWidget::product/widget/content/grid.phtml"><action method="setData"><argument name="name" xsi:type="string">show_pager</argument><argument name="value" xsi:type="string">0</argument></action><action method="setData"><argument name="name" xsi:type="string">products_count</argument><argument name="value" xsi:type="string">10</argument></action><action method="setData">'; $serializedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">a:3:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`()`;s:5:`value`;s:15:`simple, simple1`;]s:4:`1--2`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:5:`price`;s:8:`operator`;s:2:`<=`;s:5:`value`;s:2:`10`;]]</argument>'; - $jsonEncodedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple, simple1`^],`1--2`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`price`,`operator`:`<=`,`value`:`10`^]^]</argument>'; + $jsonEncodedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple, simple1`^],`1--2`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`price`,`operator`:`^(=`,`value`:`10`^]^]</argument>'; $ending = '</action><action method="setData"><argument name="name" xsi:type="string">page_var_name</argument><argument name="value" xsi:type="string">pobqks</argument></action></block></referenceContainer></body>'; // @codingStandardsIgnoreEnd return [ From 336f62c887b625cdec1a050a42aa19538eb51005 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 8 Nov 2018 19:07:56 -0600 Subject: [PATCH 1106/1415] MAGETWO-89232: Validation error appears if duplicate product twice - added functional test to cover the bug fix --- .../AdminProductGridActionGroup.xml | 7 ++++ .../Section/AdminProductFormActionSection.xml | 1 + .../AdminCreateProductDuplicateUrlkeyTest.xml | 42 +++++++++++++++++++ .../AdminSaveAndCloseActionGroup.xml | 6 +++ 4 files changed, 56 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml index 1bd9bb4a09c86..a077eced6d5d5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml @@ -164,6 +164,13 @@ <waitForElementVisible selector="{{AdminProductGridConfirmActionSection.title}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="confirmProductDelete"/> </actionGroup> + <!--Delete all products by filtering grid and using mass delete action--> + <actionGroup name="deleteAllDuplicateProductUsingProductGrid" extends="deleteProductUsingProductGrid"> + <arguments> + <argument name="product"/> + </arguments> + <remove keyForRemoval="seeProductSkuInGrid"/> + </actionGroup> <!--Delete a product by filtering grid and using delete action--> <actionGroup name="deleteProductBySku"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml index afbaba41a9bb7..c7d4cd16d788a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml @@ -15,5 +15,6 @@ <element name="saveAndClose" type="button" selector="span[title='Save & Close']" timeout="30"/> <element name="changeStoreButton" type="button" selector="#store-change-button" timeout="10"/> <element name="selectStoreView" type="button" selector="//ul[@data-role='stores-list']/li/a[normalize-space(.)='{{var1}}']" timeout="10" parameterized="true"/> + <element name="saveAndDuplicate" type="button" selector="span[id='save_and_duplicate']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml index 95d74b9653113..8dffc3d352a7b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -40,4 +40,46 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <see userInput="The value specified in the URL Key field would generate a URL that already exists" selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="assertErrorMessage"/> </test> + <test name="AdminCreateProductDuplicateProductTest"> + <annotations> + <features value="Catalog"/> + <stories value="Errors"/> + <title value="No validation errors when trying to duplicate product twice"/> + <description value="No validation errors when trying to duplicate product twice"/> + <severity value="MAJOR"/> + <testCaseId value="MC-5472"/> + <group value="product"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <!--Delete all products by filtering grid and using mass delete action--> + <actionGroup ref="deleteAllDuplicateProductUsingProductGrid" stepKey="deleteAllDuplicateProducts"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <deleteData createDataKey="createCategory" stepKey="deletePreReqCatalog" /> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct1"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct1"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <!--Save and duplicated the product once--> + <actionGroup ref="AdminFormSaveAndDuplicate" stepKey="saveAndDuplicateProductForm1"/> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct2"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct2"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <!--Save and duplicated the product second time--> + <actionGroup ref="AdminFormSaveAndDuplicate" stepKey="saveAndDuplicateProductForm2"/> + </test> </tests> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml index 9a9458ab34d2b..20c8927d49171 100644 --- a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml @@ -13,4 +13,10 @@ <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> </actionGroup> + <actionGroup name="AdminFormSaveAndDuplicate"> + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> + <click selector="{{AdminProductFormActionSection.saveAndDuplicate}}" stepKey="clickOnSaveAndDuplicate"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveSuccess" userInput="You saved the product."/> + <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertDuplicateSuccess" userInput="You duplicated the product."/> + </actionGroup> </actionGroups> From dc51f3e13799a46d8ea6204892c230d15e142b84 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Fri, 9 Nov 2018 04:25:16 +0200 Subject: [PATCH 1107/1415] Missed PHPDoc argument headers in method --- .../framework/Magento/TestFramework/TestCase/GraphQlAbstract.php | 1 + 1 file changed, 1 insertion(+) 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 cfcd5dd1b51dd..9754a340900e2 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -33,6 +33,7 @@ abstract class GraphQlAbstract extends WebapiAbstract * @param string $query * @param array $variables * @param string $operationName + * @param array $headers * @return array|int|string|float|bool GraphQL call results * @throws \Exception */ From 15668ac2018ebfae033bd0cc18ded3e8628549ec Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 12:30:37 +0300 Subject: [PATCH 1108/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 28553eaa41d12..1ec11797e311f 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -170,6 +170,7 @@ define([ }); this.reloadGridData(recordData); } + return false; }, From 10e64f25fc69c35010a74cb5628e67a64e6f9256 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Fri, 9 Nov 2018 12:16:37 +0200 Subject: [PATCH 1109/1415] Add save product with image integration test scenario --- .../Catalog/Model/ProductRepositoryTest.php | 48 +++++++++++++++++++ .../_files/product_simple_with_image.php | 45 +++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index 39752460a1cd7..d4016b2bfa8d4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -90,4 +90,52 @@ public function skuDataProvider(): array ['sku' => 'simple '], ]; } + + /** + * Test save product with gallery image + * + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php + * + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + public function testSaveProductWithGalleryImage(): void + { + /** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ + $mediaConfig = Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Media\Config::class); + + /** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ + $mediaDirectory = Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + + $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + $product->load(1); + + $path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg'; + $absolutePath = $mediaDirectory->getAbsolutePath() . $path; + $product->addImageToMediaGallery($absolutePath, [ + 'image', + 'small_image', + ], false, false); + + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $productRepository = Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository->save($product); + + $gallery = $product->getData('media_gallery'); + $this->assertArrayHasKey('images', $gallery); + $images = array_values($gallery['images']); + + $this->assertNotEmpty($gallery); + $this->assertTrue(isset($images[0]['file'])); + $this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']); + $this->assertArrayHasKey('media_type', $images[0]); + $this->assertEquals('image', $images[0]['media_type']); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('image')); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image')); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php new file mode 100644 index 0000000000000..252f99c97b787 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; +use Magento\Framework\App\Filesystem\DirectoryList; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED); + +/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ +$mediaConfig = $objectManager->get(\Magento\Catalog\Model\Product\Media\Config::class); + +/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ +$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(DirectoryList::MEDIA); + +$targetDirPath = $mediaConfig->getBaseMediaPath(); +$targetTmpDirPath = $mediaConfig->getBaseTmpMediaPath(); + +$mediaDirectory->create($targetDirPath); +$mediaDirectory->create($targetTmpDirPath); + +$dist = $mediaDirectory->getAbsolutePath($mediaConfig->getBaseMediaPath() . DIRECTORY_SEPARATOR . 'magento_image.jpg'); +copy(__DIR__ . '/magento_image.jpg', $dist); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$productRepository->save($product); From 88b3e279455ffbcb5e901ab747dbd052bb851465 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 13:33:57 +0300 Subject: [PATCH 1110/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 1ec11797e311f..0ac3b58d6e3a7 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -193,7 +193,7 @@ define([ * @return {Number} */ getCalculatedPosition: function (data) { - return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); + return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck('name').indexOf(data.name); }, /** From 2307e16105e031c0826d218cf81ffe7949191a0b Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Fri, 9 Nov 2018 09:17:57 +0200 Subject: [PATCH 1111/1415] MAGETWO-96218: [2.3] Track not saved during shipment creation through API - Refactored `getTracks` method - Fixed relation processor - Updated unit and integration tests --- .../Magento/Sales/Model/Order/Shipment.php | 38 +++-- .../ResourceModel/Order/Shipment/Relation.php | 4 +- .../Order/Shipment/RelationTest.php | 146 ++++++++---------- .../Sales/Model/Order/ShipmentTest.php | 7 +- 4 files changed, 93 insertions(+), 102 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index ebedc869e14bd..cecee4283648d 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -354,7 +354,15 @@ public function addItem(\Magento\Sales\Model\Order\Shipment\Item $item) public function getTracksCollection() { if ($this->tracksCollection === null) { - $this->tracksCollection = $this->_trackCollectionFactory->create()->setShipmentFilter($this->getId()); + $this->tracksCollection = $this->_trackCollectionFactory->create(); + + if ($this->getId()) { + $this->tracksCollection->setShipmentFilter($this->getId()); + + foreach ($this->tracksCollection as $item) { + $item->setShipment($this); + } + } } return $this->tracksCollection; @@ -400,19 +408,20 @@ public function getTrackById($trackId) */ public function addTrack(\Magento\Sales\Model\Order\Shipment\Track $track) { - $track->setShipment( - $this - )->setParentId( - $this->getId() - )->setOrderId( - $this->getOrderId() - )->setStoreId( - $this->getStoreId() - ); + $track->setShipment($this) + ->setParentId($this->getId()) + ->setOrderId($this->getOrderId()) + ->setStoreId($this->getStoreId()); + if (!$track->getId()) { $this->getTracksCollection()->addItem($track); } + $tracks = $this->getTracks(); + // as it's a new track entity, the collection doesn't contain it + $tracks[] = $track; + $this->setTracks($tracks); + /** * Track saving is implemented in _afterSave() * This enforces \Magento\Framework\Model\AbstractModel::save() not to skip _afterSave() @@ -582,14 +591,15 @@ public function setItems($items) /** * Returns tracks * - * @return \Magento\Sales\Api\Data\ShipmentTrackInterface[] + * @return \Magento\Sales\Api\Data\ShipmentTrackInterface[]|null */ public function getTracks() { + if (!$this->getId()) { + return $this->getData(ShipmentInterface::TRACKS); + } + if ($this->getData(ShipmentInterface::TRACKS) === null) { - foreach ($this->getTracksCollection() as $item) { - $item->setShipment($this); - } $this->setData(ShipmentInterface::TRACKS, $this->getTracksCollection()->getItems()); } return $this->getData(ShipmentInterface::TRACKS); diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Relation.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Relation.php index 9c8671d02c578..5851b2d936139 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Relation.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Relation.php @@ -62,8 +62,8 @@ public function processRelation(\Magento\Framework\Model\AbstractModel $object) $this->shipmentItemResource->save($item); } } - if (null !== $object->getTracksCollection()) { - foreach ($object->getTracksCollection() as $track) { + if (null !== $object->getTracks()) { + foreach ($object->getTracks() as $track) { $track->setParentId($object->getId()); $this->shipmentTrackResource->save($track); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Shipment/RelationTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Shipment/RelationTest.php index a7a615fb0f508..530306d77d3ed 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Shipment/RelationTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Shipment/RelationTest.php @@ -3,145 +3,125 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Sales\Test\Unit\Model\ResourceModel\Order\Shipment; +use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\Order\Shipment\Comment as CommentEntity; +use Magento\Sales\Model\Order\Shipment\Item as ItemEntity; +use Magento\Sales\Model\Order\Shipment\Track as TrackEntity; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Comment; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Item; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Relation; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Track; +use PHPUnit\Framework\MockObject\MockObject; + /** * Class RelationTest */ class RelationTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Relation + * @var Relation */ - protected $relationProcessor; + private $relationProcessor; /** - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Item|\PHPUnit_Framework_MockObject_MockObject + * @var Item|MockObject */ - protected $itemResourceMock; + private $itemResource; /** - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Track|\PHPUnit_Framework_MockObject_MockObject + * @var Track|MockObject */ - protected $trackResourceMock; + private $trackResource; /** - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Comment|\PHPUnit_Framework_MockObject_MockObject + * @var Comment|MockObject */ - protected $commentResourceMock; + private $commentResource; /** - * @var \Magento\Sales\Model\Order\Shipment\Comment|\PHPUnit_Framework_MockObject_MockObject + * @var CommentEntity|MockObject */ - protected $commentMock; + private $comment; /** - * @var \Magento\Sales\Model\Order\Shipment\Track|\PHPUnit_Framework_MockObject_MockObject + * @var TrackEntity|MockObject */ - protected $trackMock; + private $track; /** - * @var \Magento\Sales\Model\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject + * @var Shipment|MockObject */ - protected $shipmentMock; + private $shipment; /** - * @var \Magento\Sales\Model\Order\Shipment\Item|\PHPUnit_Framework_MockObject_MockObject + * @var ItemEntity|MockObject */ - protected $itemMock; + private $item; - protected function setUp() + /** + * @inheritdoc + */ + protected function setUp(): void { - $this->itemResourceMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Shipment\Item::class) + $this->itemResource = $this->getMockBuilder(Item::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'save' - ] - ) ->getMock(); - $this->commentResourceMock = $this->getMockBuilder( - \Magento\Sales\Model\ResourceModel\Order\Shipment\Comment::class - ) + $this->commentResource = $this->getMockBuilder(Comment::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'save' - ] - ) ->getMock(); - $this->trackResourceMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Shipment\Track::class) + $this->trackResource = $this->getMockBuilder(Track::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'save' - ] - ) ->getMock(); - $this->shipmentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipment::class) + $this->shipment = $this->getMockBuilder(Shipment::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getId', - 'getItems', - 'getTracks', - 'getComments', - 'getTracksCollection', - ] - ) ->getMock(); - $this->itemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) + $this->item = $this->getMockBuilder(ItemEntity::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'setParentId' - ] - ) ->getMock(); - $this->trackMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipment\Track::class) + $this->track = $this->getMockBuilder(TrackEntity::class) ->disableOriginalConstructor() ->getMock(); - $this->commentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipment::class) + $this->comment = $this->getMockBuilder(Shipment::class) ->disableOriginalConstructor() ->getMock(); - $this->relationProcessor = new \Magento\Sales\Model\ResourceModel\Order\Shipment\Relation( - $this->itemResourceMock, - $this->trackResourceMock, - $this->commentResourceMock + $this->relationProcessor = new Relation( + $this->itemResource, + $this->trackResource, + $this->commentResource ); } - public function testProcessRelations() + /** + * Checks saving shipment relations. + * + * @throws \Exception + */ + public function testProcessRelations(): void { - $this->shipmentMock->expects($this->exactly(3)) - ->method('getId') + $this->shipment->method('getId') ->willReturn('shipment-id-value'); - $this->shipmentMock->expects($this->exactly(2)) - ->method('getItems') - ->willReturn([$this->itemMock]); - $this->shipmentMock->expects($this->exactly(2)) - ->method('getComments') - ->willReturn([$this->commentMock]); - $this->shipmentMock->expects($this->exactly(2)) - ->method('getTracksCollection') - ->willReturn([$this->trackMock]); - $this->itemMock->expects($this->once()) - ->method('setParentId') + $this->shipment->method('getItems') + ->willReturn([$this->item]); + $this->shipment->method('getComments') + ->willReturn([$this->comment]); + $this->shipment->method('getTracks') + ->willReturn([$this->track]); + $this->item->method('setParentId') ->with('shipment-id-value') ->willReturnSelf(); - $this->itemResourceMock->expects($this->once()) - ->method('save') - ->with($this->itemMock) + $this->itemResource->method('save') + ->with($this->item) ->willReturnSelf(); - $this->commentResourceMock->expects($this->once()) - ->method('save') - ->with($this->commentMock) + $this->commentResource->method('save') + ->with($this->comment) ->willReturnSelf(); - $this->trackResourceMock->expects($this->once()) - ->method('save') - ->with($this->trackMock) + $this->trackResource->method('save') + ->with($this->track) ->willReturnSelf(); - $this->relationProcessor->processRelation($this->shipmentMock); + $this->relationProcessor->processRelation($this->shipment); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index 0679fc6ffe6cb..1d04a79ae3f84 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -90,10 +90,11 @@ public function testAddTrack() $items[$item->getId()] = $item->getQtyOrdered(); } /** @var \Magento\Sales\Model\Order\Shipment $shipment */ - $shipment = $this->objectManager->get(ShipmentFactory::class)->create($order, $items); + $shipment = $this->objectManager->get(ShipmentFactory::class) + ->create($order, $items); $shipment->addTrack($track); - $shipment->save(); - $saved = $this->shipmentRepository->save($shipment); + $this->shipmentRepository->save($shipment); + $saved = $this->shipmentRepository->get((int)$shipment->getEntityId()); self::assertNotEmpty($saved->getTracks()); } From fe7b9ac55097b64a023e607acacb1857f1926367 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 9 Nov 2018 13:48:17 +0200 Subject: [PATCH 1112/1415] magento/magento2:#19101 - API REST and Reserved Order Id - Fixed issue "Can not update cart with a reserved order number like 000000651" --- app/code/Magento/Quote/Api/Data/CartInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Api/Data/CartInterface.php b/app/code/Magento/Quote/Api/Data/CartInterface.php index 551833e3effb1..b87869de6b3df 100644 --- a/app/code/Magento/Quote/Api/Data/CartInterface.php +++ b/app/code/Magento/Quote/Api/Data/CartInterface.php @@ -223,14 +223,14 @@ public function setBillingAddress(\Magento\Quote\Api\Data\AddressInterface $bill /** * Returns the reserved order ID for the cart. * - * @return int|null Reserved order ID. Otherwise, null. + * @return string|null Reserved order ID. Otherwise, null. */ public function getReservedOrderId(); /** * Sets the reserved order ID for the cart. * - * @param int $reservedOrderId + * @param string $reservedOrderId * @return $this */ public function setReservedOrderId($reservedOrderId); From de8d0a9938ff771a09bb9be6bbf93430e462243c Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Fri, 9 Nov 2018 13:50:49 +0200 Subject: [PATCH 1113/1415] MAGETWO-91513: Password reset email cannot be sent if the customer does not have customer attribute set that is changed to required after original account creation - Skipping address validation for reset password flow --- .../Customer/Model/AccountManagement.php | 12 ++++ .../Customer/Model/ResourceModel/Customer.php | 4 +- .../Model/ResourceModel/Customer/Relation.php | 62 ++++++++++--------- .../ResourceModel/CustomerRepository.php | 17 ++++- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 9173307a7d270..553cfd2e37a06 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -1384,6 +1384,7 @@ public function changeResetPasswordLinkToken($customer, $passwordLinkToken) $customerSecure->setRpTokenCreatedAt( $this->dateTimeFactory->create()->format(DateTime::DATETIME_PHP_FORMAT) ); + $this->setIgnoreValidationFlag($customer); $this->customerRepository->save($customer); } return true; @@ -1537,4 +1538,15 @@ private function destroyCustomerSessions($customerId) $this->saveHandler->destroy($sessionId); } } + + /** + * Set ignore_validation_flag for reset password flow to skip unnecessary address and customer validation + * + * @param Customer $customer + * @return void + */ + private function setIgnoreValidationFlag($customer) + { + $customer->setData('ignore_validation_flag', true); + } } diff --git a/app/code/Magento/Customer/Model/ResourceModel/Customer.php b/app/code/Magento/Customer/Model/ResourceModel/Customer.php index f510201559687..2eb1ef897e70e 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/Customer.php +++ b/app/code/Magento/Customer/Model/ResourceModel/Customer.php @@ -151,7 +151,9 @@ protected function _beforeSave(\Magento\Framework\DataObject $customer) $customer->setConfirmation(null); } - $this->_validate($customer); + if (!$customer->getData('ignore_validation_flag')) { + $this->_validate($customer); + } return $this; } diff --git a/app/code/Magento/Customer/Model/ResourceModel/Customer/Relation.php b/app/code/Magento/Customer/Model/ResourceModel/Customer/Relation.php index e55c5d443c9d1..96f47154e874e 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/Customer/Relation.php +++ b/app/code/Magento/Customer/Model/ResourceModel/Customer/Relation.php @@ -23,41 +23,43 @@ public function processRelation(\Magento\Framework\Model\AbstractModel $customer $defaultBillingId = $customer->getData('default_billing'); $defaultShippingId = $customer->getData('default_shipping'); - /** @var \Magento\Customer\Model\Address $address */ - foreach ($customer->getAddresses() as $address) { - if ($address->getData('_deleted')) { - if ($address->getId() == $defaultBillingId) { - $customer->setData('default_billing', null); - } + if (!$customer->getData('ignore_validation_flag')) { + /** @var \Magento\Customer\Model\Address $address */ + foreach ($customer->getAddresses() as $address) { + if ($address->getData('_deleted')) { + if ($address->getId() == $defaultBillingId) { + $customer->setData('default_billing', null); + } - if ($address->getId() == $defaultShippingId) { - $customer->setData('default_shipping', null); - } + if ($address->getId() == $defaultShippingId) { + $customer->setData('default_shipping', null); + } - $removedAddressId = $address->getId(); - $address->delete(); + $removedAddressId = $address->getId(); + $address->delete(); - // Remove deleted address from customer address collection - $customer->getAddressesCollection()->removeItemByKey($removedAddressId); - } else { - $address->setParentId( - $customer->getId() - )->setStoreId( - $customer->getStoreId() - )->setIsCustomerSaveTransaction( - true - )->save(); + // Remove deleted address from customer address collection + $customer->getAddressesCollection()->removeItemByKey($removedAddressId); + } else { + $address->setParentId( + $customer->getId() + )->setStoreId( + $customer->getStoreId() + )->setIsCustomerSaveTransaction( + true + )->save(); - if (($address->getIsPrimaryBilling() || - $address->getIsDefaultBilling()) && $address->getId() != $defaultBillingId - ) { - $customer->setData('default_billing', $address->getId()); - } + if (($address->getIsPrimaryBilling() || + $address->getIsDefaultBilling()) && $address->getId() != $defaultBillingId + ) { + $customer->setData('default_billing', $address->getId()); + } - if (($address->getIsPrimaryShipping() || - $address->getIsDefaultShipping()) && $address->getId() != $defaultShippingId - ) { - $customer->setData('default_shipping', $address->getId()); + if (($address->getIsPrimaryShipping() || + $address->getIsDefaultShipping()) && $address->getId() != $defaultShippingId + ) { + $customer->setData('default_shipping', $address->getId()); + } } } } diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index 43ae2db0c2163..bfa473480335b 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -212,6 +212,7 @@ public function save(CustomerInterface $customer, $passwordHash = null) ) { $customerModel->setDefaultShipping($prevCustomerDataArr['default_shipping']); } + $this->setValidationFlag($customerArr, $customerModel); $customerModel->save(); $this->customerRegistry->push($customerModel); $customerId = $customerModel->getId(); @@ -221,7 +222,7 @@ public function save(CustomerInterface $customer, $passwordHash = null) ) { $customer->setAddresses($delegatedNewOperation->getCustomer()->getAddresses()); } - if ($customer->getAddresses() !== null) { + if ($customer->getAddresses() !== null && !$customerModel->getData('ignore_validation_flag')) { if ($customer->getId()) { $existingAddresses = $this->getById($customer->getId())->getAddresses(); $getIdFunc = function ($address) { @@ -389,4 +390,18 @@ protected function addFilterGroupToCollection( $collection->addFieldToFilter($fields); } } + + /** + * Set ignore_validation_flag to skip model validation + * + * @param array $customerArray + * @param Customer $customerModel + * @return void + */ + private function setValidationFlag($customerArray, $customerModel) + { + if (isset($customerArray['ignore_validation_flag'])) { + $customerModel->setData('ignore_validation_flag', true); + } + } } From e3940f0de98155da20329988d5dd96d010ca3e27 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 9 Nov 2018 15:43:37 +0300 Subject: [PATCH 1114/1415] MAGETWO-96125: Points not added with New Account Email Confirmation enabled - Change template functionality --- .../Api/AccountManagementInterface.php | 8 ++++-- .../Customer/Model/AccountManagement.php | 26 ++++++++++++++----- .../Customer/Model/EmailNotification.php | 25 ++++++++++++++++-- .../email/account_new_confirmation.html | 6 +++-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php index 10fc2349968ea..6c1a24d5029ac 100644 --- a/app/code/Magento/Customer/Api/AccountManagementInterface.php +++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php @@ -31,13 +31,15 @@ interface AccountManagementInterface * @param \Magento\Customer\Api\Data\CustomerInterface $customer * @param string $password * @param string $redirectUrl + * @param array $extensions * @return \Magento\Customer\Api\Data\CustomerInterface * @throws \Magento\Framework\Exception\LocalizedException */ public function createAccount( \Magento\Customer\Api\Data\CustomerInterface $customer, $password = null, - $redirectUrl = '' + $redirectUrl = '', + $extensions = [] ); /** @@ -48,6 +50,7 @@ public function createAccount( * @param string $hash Password hash that we can save directly * @param string $redirectUrl URL fed to welcome email templates. Can be used by templates to, for example, direct * the customer to a product they were looking at after pressing confirmation link. + * @param array $extensions * @return \Magento\Customer\Api\Data\CustomerInterface * @throws \Magento\Framework\Exception\InputException If bad input is provided * @throws \Magento\Framework\Exception\State\InputMismatchException If the provided email is already used @@ -56,7 +59,8 @@ public function createAccount( public function createAccountWithPasswordHash( \Magento\Customer\Api\Data\CustomerInterface $customer, $hash, - $redirectUrl = '' + $redirectUrl = '', + $extensions = [] ); /** diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 9173307a7d270..4b899fe486e5c 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -794,7 +794,7 @@ public function getConfirmationStatus($customerId) /** * @inheritdoc */ - public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '') + public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '', $extensions = []) { if ($password !== null) { $this->checkPasswordStrength($password); @@ -810,7 +810,7 @@ public function createAccount(CustomerInterface $customer, $password = null, $re } else { $hash = null; } - return $this->createAccountWithPasswordHash($customer, $hash, $redirectUrl); + return $this->createAccountWithPasswordHash($customer, $hash, $redirectUrl, $extensions); } /** @@ -818,8 +818,12 @@ public function createAccount(CustomerInterface $customer, $password = null, $re * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function createAccountWithPasswordHash(CustomerInterface $customer, $hash, $redirectUrl = '') - { + public function createAccountWithPasswordHash( + CustomerInterface $customer, + $hash, + $redirectUrl = '', + $extensions = [] + ) { // This logic allows an existing customer to be added to a different store. No new account is created. // The plan is to move this logic into a new method called something like 'registerAccountWithStore' if ($customer->getId()) { @@ -892,7 +896,7 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash $customer = $this->customerRepository->getById($customer->getId()); $newLinkToken = $this->mathRandom->getUniqueHash(); $this->changeResetPasswordLinkToken($customer, $newLinkToken); - $this->sendEmailConfirmation($customer, $redirectUrl); + $this->sendEmailConfirmation($customer, $redirectUrl, $extensions); return $customer; } @@ -920,9 +924,10 @@ public function getDefaultShippingAddress($customerId) * * @param CustomerInterface $customer * @param string $redirectUrl + * @param array $extensions * @return void */ - protected function sendEmailConfirmation(CustomerInterface $customer, $redirectUrl) + protected function sendEmailConfirmation(CustomerInterface $customer, $redirectUrl, $extensions = []) { try { $hash = $this->customerRegistry->retrieveSecureData($customer->getId())->getPasswordHash(); @@ -932,7 +937,14 @@ protected function sendEmailConfirmation(CustomerInterface $customer, $redirectU } elseif ($hash == '') { $templateType = self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD; } - $this->getEmailNotification()->newAccount($customer, $templateType, $redirectUrl, $customer->getStoreId()); + $this->getEmailNotification()->newAccount( + $customer, + $templateType, + $redirectUrl, + $customer->getStoreId(), + null, + $extensions + ); } catch (MailException $e) { // If we are not able to send a new account email, this should be ignored $this->logger->critical($e); diff --git a/app/code/Magento/Customer/Model/EmailNotification.php b/app/code/Magento/Customer/Model/EmailNotification.php index 4b65dcca0973f..30a9dbedde8d0 100644 --- a/app/code/Magento/Customer/Model/EmailNotification.php +++ b/app/code/Magento/Customer/Model/EmailNotification.php @@ -17,6 +17,8 @@ use Magento\Framework\Exception\LocalizedException; /** + * Class for notification customer. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class EmailNotification implements EmailNotificationInterface @@ -63,6 +65,8 @@ class EmailNotification implements EmailNotificationInterface self::NEW_ACCOUNT_EMAIL_CONFIRMATION => self::XML_PATH_CONFIRM_EMAIL_TEMPLATE, ]; + const CUSTOMER_CONFIRM_URL = 'customer/account/confirm/'; + /**#@-*/ /**#@-*/ @@ -362,6 +366,7 @@ public function passwordResetConfirmation(CustomerInterface $customer) * @param string $backUrl * @param string $storeId * @param string $sendemailStoreId + * @param array $extensions * @return void * @throws LocalizedException */ @@ -370,7 +375,8 @@ public function newAccount( $type = self::NEW_ACCOUNT_EMAIL_REGISTERED, $backUrl = '', $storeId = 0, - $sendemailStoreId = null + $sendemailStoreId = null, + $extensions = [] ) { $types = self::TEMPLATE_TYPES; @@ -388,11 +394,26 @@ public function newAccount( $customerEmailData = $this->getFullCustomerObject($customer); + $templateVars = [ + 'customer' => $customerEmailData, + 'back_url' => $backUrl, + 'store' => $store + ]; + if ($type == self::NEW_ACCOUNT_EMAIL_CONFIRMATION) { + if (empty($extensions)) { + $templateVars['url'] = self::CUSTOMER_CONFIRM_URL; + $templateVars['extensions'] = $extensions; + } else { + $templateVars['url'] = $extensions['url']; + $templateVars['extensions'] = $extensions['extension_info']; + } + } + $this->sendEmailTemplate( $customer, $types[$type], self::XML_PATH_REGISTER_EMAIL_IDENTITY, - ['customer' => $customerEmailData, 'back_url' => $backUrl, 'store' => $store], + $templateVars, $storeId ); } diff --git a/app/code/Magento/Customer/view/frontend/email/account_new_confirmation.html b/app/code/Magento/Customer/view/frontend/email/account_new_confirmation.html index 010087ace2d42..9b183d63471f3 100644 --- a/app/code/Magento/Customer/view/frontend/email/account_new_confirmation.html +++ b/app/code/Magento/Customer/view/frontend/email/account_new_confirmation.html @@ -9,7 +9,9 @@ "var this.getUrl($store, 'customer/account/confirm/', [_query:[id:$customer.id, key:$customer.confirmation, back_url:$back_url]])":"Account Confirmation URL", "var this.getUrl($store, 'customer/account/')":"Customer Account URL", "var customer.email":"Customer Email", -"var customer.name":"Customer Name" +"var customer.name":"Customer Name", +"var extensions":"Extensions", +"var url":"Url" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +25,7 @@ <table class="inner-wrapper" border="0" cellspacing="0" cellpadding="0" align="center"> <tr> <td align="center"> - <a href="{{var this.getUrl($store,'customer/account/confirm/',[_query:[id:$customer.id,key:$customer.confirmation,back_url:$back_url],_nosid:1])}}" target="_blank">{{trans "Confirm Your Account"}}</a> + <a href="{{var this.getUrl($store,$url,[_query:[id:$customer.id,key:$customer.confirmation,extensions:$extensions,back_url:$back_url],_nosid:1])}}" target="_blank">{{trans "Confirm Your Account"}}</a> </td> </tr> </table> From e767121cab5385e1ea5f36b237622eb258333566 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 15:54:57 +0300 Subject: [PATCH 1115/1415] MAGETWO-91650: Translation not working for product alerts - Add store id for product alert --- .../ProductAlert/etc/db_schema_whitelist.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json index 234e3d14876e5..94c9d07c85015 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json +++ b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json @@ -1,6 +1,7 @@ { "product_alert_price": { "column": { + "store_id": true, "alert_price_id": true, "customer_id": true, "product_id": true, @@ -9,26 +10,26 @@ "add_date": true, "last_send_date": true, "send_count": true, - "status": true, - "store_id": true + "status": true }, "index": { + "PRODUCT_ALERT_PRICE_STORE_ID": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID": true, - "PRODUCT_ALERT_PRICE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_STORE_ID": true + "PRODUCT_ALERT_PRICE_WEBSITE_ID": true }, "constraint": { + "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true, "PRIMARY": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, - "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true + "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true } }, "product_alert_stock": { "column": { + "store_id": true, "alert_stock_id": true, "customer_id": true, "product_id": true, @@ -36,22 +37,21 @@ "add_date": true, "send_date": true, "send_count": true, - "status": true, - "store_id": true + "status": true }, "index": { + "PRODUCT_ALERT_STOCK_STORE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID": true, - "PRODUCT_ALERT_STOCK_WEBSITE_ID": true, - "PRODUCT_ALERT_STOCK_STORE_ID": true + "PRODUCT_ALERT_STOCK_WEBSITE_ID": true }, "constraint": { + "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true, "PRIMARY": true, "PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, - "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true + "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true } } } From 842324af44d362b3533a4559e7d4c8ab35b2e2be Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 9 Nov 2018 15:02:27 +0200 Subject: [PATCH 1116/1415] magento-engcom/magento2ce#2324: Fixed Code Style Issues --- app/code/Magento/Backup/Controller/Adminhtml/Index.php | 5 ++++- .../Magento/Reports/Model/Product/Index/AbstractIndex.php | 7 ++++--- app/code/Magento/Weee/Model/Sales/Pdf/Weee.php | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index 142211fe90a44..94dca327195f3 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -5,6 +5,9 @@ */ namespace Magento\Backup\Controller\Adminhtml; +use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface; + /** * Backup admin controller * @@ -12,7 +15,7 @@ * @api * @since 100.0.2 */ -abstract class Index extends \Magento\Backend\App\Action +abstract class Index extends Action implements HttpGetActionInterface { /** * Authorization level of a basic admin session diff --git a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php index 56991e290dec6..7337286149cc3 100644 --- a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php +++ b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php @@ -113,7 +113,7 @@ public function beforeSave() /** * Retrieve visitor id * - * if don't exists return current visitor id + * If don't exists return current visitor id * * @return int */ @@ -128,7 +128,7 @@ public function getVisitorId() /** * Retrieve customer id * - * if customer don't logged in return null + * If customer don't logged in return null * * @return int */ @@ -143,7 +143,7 @@ public function getCustomerId() /** * Retrieve store id * - * default return current store id + * Default return current store id * * @return int */ @@ -246,6 +246,7 @@ public function clean() /** * Add product ids to current visitor/customer log + * * @param string[] $productIds * @return $this */ diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php index 65480047f2f05..2b8c74581d973 100644 --- a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php +++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php @@ -36,6 +36,7 @@ public function __construct( /** * Check if weee total amount should be included * + * Example: * array( * $index => array( * 'amount' => $amount, @@ -43,6 +44,7 @@ public function __construct( * 'font_size'=> $font_size * ) * ) + * * @return array */ public function getTotalsForDisplay() From 023a39177eb8889f291f92f3651c22c4c28c2908 Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Fri, 9 Nov 2018 15:18:52 +0200 Subject: [PATCH 1117/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - fix issue with enabled Braintree and shipping tax class --- ...thOnlinePaymentIncludingTaxAndDiscount.xml | 5 +++- .../Mftf/ActionGroup/AdminTaxActionGroup.xml | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml index a7c0e8f62544e..7c0a503e7bb4b 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -48,6 +48,9 @@ <!--Delete Cart Price Rule--> <actionGroup ref="AdminDeleteCartPriceRuleForRetailerActionGroup" stepKey="deleteSalesRule"/> + <!--Set to default configuration Tax Shipping Class--> + <actionGroup ref="setDefaultShippingTaxClass" stepKey="setdefaultClass"/> + <!--Delete Simple Sub Category--> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -58,7 +61,7 @@ <deleteData createDataKey="createTaxRule" stepKey="deleteTaxRule"/> <!-- Rollback Braintree to Default --> - <createData entity="DefaultBraintreeConfig" stepKey="DefaultBraintreeConfig"/> + <createData entity="RollBackCustomBraintreeConfigurationData" stepKey="rollbackBraintreeConfig"/> <!--Delete Customer--> <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml index 3009fa1fc8a25..4f724fb0047e6 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml @@ -145,6 +145,32 @@ <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the configuration."/> </actionGroup> + <actionGroup name="setDefaultShippingTaxClass"> + <!--Select Configuration menu from Store--> + <click selector="{{AdminMenuSection.stores}}" stepKey="clickOnSTORES" /> + <waitForPageLoad stepKey="waitForConfiguration" time="5"/> + <click selector="{{StoresSubmenuSection.configuration}}" stepKey="clickOnConfigurations"/> + <waitForPageLoad stepKey="waitForSales" time="5"/> + <!--Double click the same to fix flaky issue with redirection to Dashboard--> + <click selector="{{AdminMenuSection.stores}}" stepKey="clickOnSTORES1" /> + <waitForPageLoad stepKey="waitForConfiguration1" time="5"/> + <click selector="{{StoresSubmenuSection.configuration}}" stepKey="clickOnConfigurations1"/> + <waitForPageLoad stepKey="waitForSales1" time="5"/> + <!--Change default tax class for Shipping on Taxable Goods--> + <click selector="{{ConfigurationListSection.sales}}" stepKey="clickOnSales" /> + <waitForPageLoad stepKey="waitForPaymentMethods" time="5"/> + <click selector="{{AdminConfigureTaxSection.salesTax}}" stepKey="clickOnTax"/> + <waitForPageLoad stepKey="waitForTax" time="5"/> + <seeElement selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="taxClassSectionC"/> + <click selector="{{AdminConfigureTaxSection.taxShippingClassSystem}}" stepKey="checkSystemDefaultValue"/> + <click selector="{{AdminConfigureTaxSection.taxClasses}}" stepKey="closeTaxClassSection"/> + <!-- Save the settings --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="saveTaxOptions" selector="{{AdminCategoryMainActionsSection.SaveButton}}"/> + <waitForPageLoad stepKey="waitForTaxSaved"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the configuration."/> + </actionGroup> + <!--Add Product Tax Class--> <actionGroup name="addProductTaxClass"> <arguments> From 40b2ebb83674897d81a2e98d309403ca7d5e75f1 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Fri, 9 Nov 2018 18:15:52 +0400 Subject: [PATCH 1118/1415] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Updated element locator for test --- .../Mftf/Section/AdminProductFormGroupedProductsSection.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index f5549f26bfd56..547c856d144c8 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,9 +11,9 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> - <element name="nextActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-next"/> - <element name="previousActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-previous"/> + <element name="nextActionButton" type="button" selector="//*[@data-index='grouped']//*[@class='action-next']"/> + <element name="previousActionButton" type="button" selector="//*[@data-index='grouped']//*[@class='action-previous']"/> <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> -</sections> \ No newline at end of file +</sections> From e9f2b802a6127811867e193e3b792f7f8a0d1051 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 9 Nov 2018 09:44:47 -0600 Subject: [PATCH 1119/1415] MAGETWO-96231: All pages in magento are broken on Nginx (MAGE_DIRS errors) - Added check for array existence --- pub/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub/index.php b/pub/index.php index 90b4778265447..612e190719053 100644 --- a/pub/index.php +++ b/pub/index.php @@ -26,7 +26,7 @@ $params = $_SERVER; $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( - $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], + $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? [], [ DirectoryList::PUB => [DirectoryList::URL_PATH => ''], DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], From 6a20b98dd369a64ddfa6a08ea5e4f71ba94d8a50 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 9 Nov 2018 18:01:13 +0200 Subject: [PATCH 1120/1415] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- setup/performance-toolkit/benchmark.jmx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 37e07d1319572..a13fe47a86532 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -40763,7 +40763,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40820,7 +40820,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40896,7 +40896,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40965,7 +40965,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41025,7 +41025,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41085,7 +41085,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41145,7 +41145,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41214,7 +41214,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41301,7 +41301,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41368,7 +41368,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> From a9e86656de5a821497db3f046f127d3ca83dffa8 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 9 Nov 2018 10:11:19 -0600 Subject: [PATCH 1121/1415] MQE-1339: Bump MFTF version in Magento - Repulled origin lock file, updated MFTF in lock --- composer.lock | 156 +++++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/composer.lock b/composer.lock index 7a23eee0e178b..3565ab2420e05 100644 --- a/composer.lock +++ b/composer.lock @@ -257,16 +257,16 @@ }, { "name": "composer/composer", - "version": "1.7.3", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", "shasum": "" }, "require": { @@ -333,7 +333,7 @@ "dependency", "package" ], - "time": "2018-11-01T09:05:06+00:00" + "time": "2018-08-16T14:57:12+00:00" }, { "name": "composer/semver", @@ -399,16 +399,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", "shasum": "" }, "require": { @@ -456,7 +456,7 @@ "spdx", "validator" ], - "time": "2018-11-01T09:45:54+00:00" + "time": "2018-04-30T10:33:04+00:00" }, { "name": "composer/xdebug-handler", @@ -919,16 +919,16 @@ }, { "name": "monolog/monolog", - "version": "1.24.0", + "version": "1.23.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", "shasum": "" }, "require": { @@ -993,7 +993,7 @@ "logging", "psr-3" ], - "time": "2018-11-05T09:00:11+00:00" + "time": "2017-06-19T01:22:40+00:00" }, { "name": "oyejorge/less.php", @@ -1375,16 +1375,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.12", + "version": "2.0.11", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", "shasum": "" }, "require": { @@ -1463,7 +1463,7 @@ "x.509", "x509" ], - "time": "2018-11-04T05:45:48+00:00" + "time": "2018-04-15T16:55:05+00:00" }, { "name": "psr/container", @@ -1834,16 +1834,16 @@ }, { "name": "symfony/console", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595" + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595", + "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", "shasum": "" }, "require": { @@ -1898,20 +1898,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:30:44+00:00" + "time": "2018-10-03T08:15:46+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "552541dad078c85d9414b09c041ede488b456cd5" + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", - "reference": "552541dad078c85d9414b09c041ede488b456cd5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", "shasum": "" }, "require": { @@ -1961,20 +1961,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-10-10T13:52:42+00:00" + "time": "2018-07-26T09:10:45+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", "shasum": "" }, "require": { @@ -2011,11 +2011,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-30T13:18:25+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "symfony/finder", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2064,7 +2064,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2122,16 +2122,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", "shasum": "" }, "require": { @@ -2177,20 +2177,20 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/process", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" + "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", + "url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529", + "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529", "shasum": "" }, "require": { @@ -2226,7 +2226,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-14T20:48:13+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "tedivm/jshrink", @@ -8228,7 +8228,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -8285,16 +8285,16 @@ }, { "name": "symfony/config", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96", "shasum": "" }, "require": { @@ -8344,11 +8344,11 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-09-08T13:24:10+00:00" }, { "name": "symfony/css-selector", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -8401,16 +8401,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483" + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30", "shasum": "" }, "require": { @@ -8468,11 +8468,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-10-31T10:54:16+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -8529,16 +8529,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" + "reference": "d528136617ff24f530e70df9605acc1b788b08d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4", + "reference": "d528136617ff24f530e70df9605acc1b788b08d4", "shasum": "" }, "require": { @@ -8579,11 +8579,11 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-10-03T08:48:45+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -8637,16 +8637,16 @@ }, { "name": "symfony/polyfill-php70", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", "shasum": "" }, "require": { @@ -8692,20 +8692,20 @@ "portable", "shim" ], - "time": "2018-09-21T06:26:08+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", "shasum": "" }, "require": { @@ -8747,11 +8747,11 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -8800,7 +8800,7 @@ }, { "name": "symfony/yaml", - "version": "v3.4.18", + "version": "v3.4.17", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", From 45d3742f7a7a3104dc756350c854da18e02a6189 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 9 Nov 2018 18:50:33 +0200 Subject: [PATCH 1122/1415] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- .../Magento/GraphQl/Catalog/UrlRewritesTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php index c39b32e4bfa4f..43796d780646c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php @@ -33,8 +33,10 @@ public function testProductWithNoCategoriesAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name, @@ -87,8 +89,10 @@ public function testProductWithOneCategoryAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name, From 493e5b6f7448b0eb42829db2dcd424acf180cdf8 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 9 Nov 2018 11:06:12 -0600 Subject: [PATCH 1123/1415] MAGETWO-95212: Dynamic block call to getCurrentUrl method is returning ajax request value - Fixed product compare link --- app/code/Magento/Catalog/Helper/Product/Compare.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Helper/Product/Compare.php b/app/code/Magento/Catalog/Helper/Product/Compare.php index 90d98874e00cb..d6d35c5c76dd8 100644 --- a/app/code/Magento/Catalog/Helper/Product/Compare.php +++ b/app/code/Magento/Catalog/Helper/Product/Compare.php @@ -166,7 +166,15 @@ public function getListUrl() */ public function getPostDataParams($product) { - return $this->postHelper->getPostData($this->getAddUrl(), ['product' => $product->getId()]); + $params = ['product' => $product->getId()]; + $requestingPageUrl = $this->_getRequest()->getParam('requesting_page_url'); + + if (!empty($requestingPageUrl)) { + $encodedUrl = $this->urlEncoder->encode($requestingPageUrl); + $params[\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED] = $encodedUrl; + } + + return $this->postHelper->getPostData($this->getAddUrl(), $params); } /** From 6c8dfe2c4f2556a2c182f9042fab93ff0d5cc75d Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 9 Nov 2018 11:06:40 -0600 Subject: [PATCH 1124/1415] MAGETWO-89232: Validation error appears if duplicate product twice - CR comment --- .../Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml index 8dffc3d352a7b..6658ad36d7150 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -43,7 +43,7 @@ <test name="AdminCreateProductDuplicateProductTest"> <annotations> <features value="Catalog"/> - <stories value="Errors"/> + <stories value="Validation Errors"/> <title value="No validation errors when trying to duplicate product twice"/> <description value="No validation errors when trying to duplicate product twice"/> <severity value="MAJOR"/> From 2283662f6a0a3b2c0d9d7a27c1a440f60b562c27 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 9 Nov 2018 11:40:32 -0600 Subject: [PATCH 1125/1415] MAGETWO-95212: Dynamic block call to getCurrentUrl method is returning ajax request value - Added selector --- .../CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml index 4e79334a94cd3..03bef8ffa3b7d 100644 --- a/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Section/ProductListWidgetSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="ProductListWidgetSection"> <element name="AddToCartByName" type="button" selector="//*[contains(@class,'product-item-info')][descendant::a[contains(text(), '{{arg1}}')]]//button[contains(@class,'tocart')]" parameterized="true"/> + <element name="AddToCompareByName" type="button" selector="//*[contains(@class,'product-item-info')][descendant::a[contains(text(), '{{arg1}}')]]//button[contains(@class,'tocompare')]" parameterized="true"/> </section> </sections> From bfcf6249bb0e26d835e8bace4764c8cadfe1568b Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 9 Nov 2018 13:55:29 -0600 Subject: [PATCH 1126/1415] MQE-1339: Bump MFTF version in Magento - Fix flaky actionGroup --- .../ChangeStatusProductUsingProductGridActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml index 9698f9cef4219..1961b1002df70 100644 --- a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -27,6 +27,7 @@ <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled"/> <waitForPageLoad stepKey="waitForDisable"/> <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> + <waitForLoadingMaskToDisappear stepKey="waitForMaskToDisappear"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> </actionGroup> </actionGroups> From 4879fae86d13f421a8dbdb95fb47c784c1f50e41 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 9 Nov 2018 15:59:15 -0600 Subject: [PATCH 1127/1415] MAGETWO-95892: Selecting Gift Options for items redirects on 404 Page --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index 9f0dcc6d9c18f..be84dcd76bb88 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -8,8 +8,9 @@ use Magento\Checkout\Model\Cart\RequestQuantityProcessor; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; -class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface +class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface, HttpGetActionInterface { /** * @var RequestQuantityProcessor From 15dc79bea4a604a22a68e3a14fbd643336b3a400 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 9 Nov 2018 16:04:29 -0600 Subject: [PATCH 1128/1415] ENGCOM-3421: Magento 2.3 Fix Notice and Exception while adding image to product programmatically #18952 - Fixed docblocks --- .../Magento/Catalog/Model/Product/Gallery/Processor.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 9cd5073f4357c..0912324745360 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -88,6 +88,8 @@ public function __construct( } /** + * Return media_gallery attribute + * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ @@ -383,7 +385,8 @@ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $medi } /** - * get media attribute codes + * Get media attribute codes + * * @return array * @since 101.0.0 */ @@ -393,6 +396,8 @@ public function getMediaAttributeCodes() } /** + * Trim .tmp ending from filename + * * @param string $file * @return string * @since 101.0.0 @@ -514,7 +519,6 @@ public function getAffectedFields($object) /** * Attribute value is not to be saved in a conventional way, separate table is used to store the complex value * - * {@inheritdoc} * @since 101.0.0 */ public function isScalar() From 5c04cf909f94d8a5afa1cb74dbaed5b0ccf8b955 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 9 Nov 2018 16:21:04 -0600 Subject: [PATCH 1129/1415] #2324: Skipping flaky test --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index b87ab626d3970..0b2809dfc3543 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -251,6 +251,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-297"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96266"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From e827b3220c12cc8e793e0486cd9425e4ca4c2853 Mon Sep 17 00:00:00 2001 From: Vova Yatsyuk <vova.yatsyuk@gmail.com> Date: Sat, 10 Nov 2018 11:43:05 +0200 Subject: [PATCH 1130/1415] Allow to read HTTP/2 response header. The issue is HTTP/2 sends the following headers `HTTP/2 200`, `HTTP/2 401` and so on. It doesn't have third parameter like HTTP/1.1 has: `HTTP/2 200 OK` --- lib/internal/Magento/Framework/HTTP/Client/Curl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index d1dfafdeb2adb..0ac65a420ddcf 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -438,7 +438,7 @@ protected function parseHeaders($ch, $data) { if ($this->_headerCount == 0) { $line = explode(" ", trim($data), 3); - if (count($line) != 3) { + if (count($line) < 2) { $this->doError("Invalid response line returned from server: " . $data); } $this->_responseStatus = (int)$line[1]; From 57fcc1b24c4c582a96930ff7465e5f74417f2bcc Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 10 Nov 2018 11:46:07 +0200 Subject: [PATCH 1131/1415] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20forward=20port=20unit=20tests=20from=202.2-devel?= =?UTF-8?q?op=20branch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/Test/Unit/TranslateTest.php | 371 ++++++++++++++++++ lib/internal/Magento/Framework/Translate.php | 4 +- 2 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 lib/internal/Magento/Framework/Test/Unit/TranslateTest.php diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php new file mode 100644 index 0000000000000..6a6407c97a95f --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -0,0 +1,371 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit; + +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Translate; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class TranslateTest extends \PHPUnit\Framework\TestCase +{ + /** @var Translate */ + protected $translate; + + /** @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewDesign; + + /** @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $cache; + + /** @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewFileSystem; + + /** @var \Magento\Framework\Module\ModuleList|\PHPUnit_Framework_MockObject_MockObject */ + protected $moduleList; + + /** @var \Magento\Framework\Module\Dir\Reader|\PHPUnit_Framework_MockObject_MockObject */ + protected $modulesReader; + + /** @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeResolver; + + /** @var \Magento\Framework\Translate\ResourceInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $resource; + + /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $locale; + + /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */ + protected $appState; + + /** @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $filesystem; + + /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $request; + + /** @var \Magento\Framework\File\Csv|\PHPUnit_Framework_MockObject_MockObject */ + protected $csvParser; + + /** @var \Magento\Framework\App\Language\Dictionary|\PHPUnit_Framework_MockObject_MockObject */ + protected $packDictionary; + + /** @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $directory; + + /** @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileDriver; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->viewDesign = $this->createMock(\Magento\Framework\View\DesignInterface::class); + $this->cache = $this->createMock(\Magento\Framework\Cache\FrontendInterface::class); + $this->viewFileSystem = $this->createMock(\Magento\Framework\View\FileSystem::class); + $this->moduleList = $this->createMock(\Magento\Framework\Module\ModuleList::class); + $this->modulesReader = $this->createMock(\Magento\Framework\Module\Dir\Reader::class); + $this->scopeResolver = $this->createMock(\Magento\Framework\App\ScopeResolverInterface::class); + $this->resource = $this->createMock(\Magento\Framework\Translate\ResourceInterface::class); + $this->locale = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class); + $this->appState = $this->createMock(\Magento\Framework\App\State::class); + $this->request = $this->getMockForAbstractClass( + \Magento\Framework\App\RequestInterface::class, + [], + '', + false, + false, + true, + ['getParam', 'getControllerModule'] + ); + $this->csvParser = $this->createMock(\Magento\Framework\File\Csv::class); + $this->packDictionary = $this->createMock(\Magento\Framework\App\Language\Dictionary::class); + $this->directory = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadInterface::class); + $filesystem = $this->createMock(\Magento\Framework\Filesystem::class); + $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->directory)); + $this->fileDriver = $this->createMock(\Magento\Framework\Filesystem\DriverInterface::class); + + $this->translate = new Translate( + $this->viewDesign, + $this->cache, + $this->viewFileSystem, + $this->moduleList, + $this->modulesReader, + $this->scopeResolver, + $this->resource, + $this->locale, + $this->appState, + $filesystem, + $this->request, + $this->csvParser, + $this->packDictionary, + $this->fileDriver + ); + + $serializerMock = $this->createMock(SerializerInterface::class); + $serializerMock->method('serialize') + ->willReturnCallback(function ($data) { + return json_encode($data); + }); + $serializerMock->method('unserialize') + ->willReturnCallback(function ($string) { + return json_decode($string, true); + }); + $objectManager->setBackwardCompatibleProperty( + $this->translate, + 'serializer', + $serializerMock + ); + } + + /** + * @param string $area + * @param bool $forceReload + * @param array $cachedData + * @dataProvider dataProviderLoadDataCachedTranslation + */ + public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) + { + $this->expectsSetConfig('Magento/luma'); + + $this->cache->expects($this->once()) + ->method('load') + ->will($this->returnValue(json_encode($cachedData))); + + $this->appState->expects($this->exactly($area ? 0 : 1)) + ->method('getAreaCode') + ->will($this->returnValue('frontend')); + + $this->translate->loadData($area, $forceReload); + $this->assertEquals($cachedData, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderLoadDataCachedTranslation() + { + $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2']; + return [ + ['adminhtml', false, $cachedData], + ['frontend', false, $cachedData], + [null, false, $cachedData], + ]; + } + + /** + * @param string $area + * @param bool $forceReload + * @dataProvider dataProviderForTestLoadData + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function testLoadData($area, $forceReload) + { + $this->expectsSetConfig('Magento/luma'); + + $this->appState->expects($this->exactly($area ? 0 : 1)) + ->method('getAreaCode') + ->will($this->returnValue('frontend')); + + $this->cache->expects($this->exactly($forceReload ? 0 : 1)) + ->method('load') + ->will($this->returnValue(false)); + + $this->directory->expects($this->any())->method('isExist')->will($this->returnValue(true)); + + // _loadModuleTranslation() + $modules = ['some_module', 'other_module', 'another_module', 'current_module']; + $this->request->expects($this->any()) + ->method('getControllerModule') + ->willReturn('current_module'); + $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue($modules)); + $moduleData = [ + 'module original' => 'module translated', + 'module theme' => 'module-theme original translated', + 'module pack' => 'module-pack original translated', + 'module db' => 'module-db original translated', + ]; + $this->modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module')); + $themeData = [ + 'theme original' => 'theme translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'theme-pack translated overwrite', + 'module db' => 'theme-db translated overwrite', + ]; + $this->csvParser->expects($this->any()) + ->method('getDataPairs') + ->will( + $this->returnValueMap( + [ + ['/app/module/en_US.csv', 0, 1, $moduleData], + ['/app/module/en_GB.csv', 0, 1, $moduleData], + ['/theme.csv', 0, 1, $themeData], + ] + ) + ); + $this->fileDriver->expects($this->any()) + ->method('isExists') + ->will( + $this->returnValueMap( + [ + ['/app/module/en_US.csv', true], + ['/app/module/en_GB.csv', true], + ['/theme.csv', true], + ] + ) + ); + + // _loadPackTranslation + $packData = [ + 'pack original' => 'pack translated', + 'module pack' => 'pack translated overwrite', + 'module db' => 'pack-db translated overwrite', + ]; + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue($packData)); + + // _loadThemeTranslation() + $this->viewFileSystem->expects($this->any()) + ->method('getLocaleFileName') + ->will($this->returnValue('/theme.csv')); + + // _loadDbTranslation() + $dbData = [ + 'db original' => 'db translated', + 'module db' => 'db translated overwrite', + ]; + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue($dbData)); + + $this->cache->expects($this->exactly($forceReload ? 0 : 1))->method('save'); + + $this->translate->loadData($area, $forceReload); + + $expected = [ + 'module original' => 'module translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'theme-pack translated overwrite', + 'module db' => 'db translated overwrite', + 'theme original' => 'theme translated', + 'pack original' => 'pack translated', + 'db original' => 'db translated', + ]; + $this->assertEquals($expected, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderForTestLoadData() + { + return [ + ['adminhtml', true], + ['adminhtml', false], + ['frontend', true], + ['frontend', false], + [null, true], + [null, false] + ]; + } + + /** + * @param $data + * @param $result + * @dataProvider dataProviderForTestGetData + */ + public function testGetData($data, $result) + { + $this->cache->expects($this->once()) + ->method('load') + ->will($this->returnValue(json_encode($data))); + $this->expectsSetConfig('themeId'); + $this->translate->loadData('frontend'); + $this->assertEquals($result, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderForTestGetData() + { + $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2']; + return [ + [$data, $data], + [null, []] + ]; + } + + public function testGetLocale() + { + $this->locale->expects($this->once())->method('getLocale')->will($this->returnValue('en_US')); + $this->assertEquals('en_US', $this->translate->getLocale()); + + $this->locale->expects($this->never())->method('getLocale'); + $this->assertEquals('en_US', $this->translate->getLocale()); + + $this->locale->expects($this->never())->method('getLocale'); + $this->translate->setLocale('en_GB'); + $this->assertEquals('en_GB', $this->translate->getLocale()); + } + + public function testSetLocale() + { + $this->translate->setLocale('en_GB'); + $this->locale->expects($this->never())->method('getLocale'); + $this->assertEquals('en_GB', $this->translate->getLocale()); + } + + public function testGetTheme() + { + $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); + + $requestTheme = ['theme_title' => 'Theme Title']; + $this->request->expects($this->at(1))->method('getParam')->with('theme') + ->will($this->returnValue($requestTheme)); + + $this->assertEquals('theme', $this->translate->getTheme()); + $this->assertEquals('themeTheme Title', $this->translate->getTheme()); + } + + public function testLoadDataNoTheme() + { + $forceReload = true; + $this->expectsSetConfig(null, null); + $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue([])); + $this->appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend')); + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue([])); + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([])); + $this->assertEquals($this->translate, $this->translate->loadData(null, $forceReload)); + } + + /** + * Declare calls expectation for setConfig() method + */ + protected function expectsSetConfig($themeId, $localeCode = 'en_US') + { + $this->locale->expects($this->any())->method('getLocale')->will($this->returnValue($localeCode)); + $scope = new \Magento\Framework\DataObject(['code' => 'frontendCode', 'id' => 1]); + $scopeAdmin = new \Magento\Framework\DataObject(['code' => 'adminCode', 'id' => 0]); + $this->scopeResolver->expects($this->any()) + ->method('getScope') + ->will( + $this->returnValueMap( + [ + [null, $scope], + ['admin', $scopeAdmin], + ] + ) + ); + $designTheme = $this->getMockBuilder(\Magento\Theme\Model\Theme::class) + ->disableOriginalConstructor() + ->getMock(); + + $designTheme->expects($this->once()) + ->method('getThemePath') + ->willReturn($themeId); + + $this->viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme)); + } +} diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ff1bf99162a8a..ce73338eee292 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -398,11 +398,11 @@ protected function _getModuleTranslationFile($moduleName, $locale) /** * Get theme translation locale file name * - * @param string $locale + * @param string|null $locale * @param array $config * @return string|null */ - private function getThemeTranslationFileName(string $locale, array $config): ?string + private function getThemeTranslationFileName(?string $locale, array $config): ?string { $fileName = $this->_viewFileSystem->getLocaleFileName( 'i18n' . '/' . $locale . '.csv', From fe73cf00549475b0ffc5a470e10ba4f1f3893b78 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 10 Nov 2018 11:57:22 +0200 Subject: [PATCH 1132/1415] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20forward=20port=20unit=20tests=20from=202.2-devel?= =?UTF-8?q?op=20branch=20-=20declare=20strict=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/Test/Unit/TranslateTest.php | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php index 6a6407c97a95f..885be8557fa10 100644 --- a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Test\Unit; use Magento\Framework\Serialize\SerializerInterface; @@ -61,7 +63,7 @@ class TranslateTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $fileDriver; - protected function setUp() + protected function setUp(): void { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->viewDesign = $this->createMock(\Magento\Framework\View\DesignInterface::class); @@ -128,7 +130,7 @@ protected function setUp() * @param array $cachedData * @dataProvider dataProviderLoadDataCachedTranslation */ - public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) + public function testLoadDataCachedTranslation($area, $forceReload, $cachedData): void { $this->expectsSetConfig('Magento/luma'); @@ -147,7 +149,7 @@ public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) /** * @return array */ - public function dataProviderLoadDataCachedTranslation() + public function dataProviderLoadDataCachedTranslation(): array { $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2']; return [ @@ -163,7 +165,7 @@ public function dataProviderLoadDataCachedTranslation() * @dataProvider dataProviderForTestLoadData * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function testLoadData($area, $forceReload) + public function testLoadData($area, $forceReload): void { $this->expectsSetConfig('Magento/luma'); @@ -258,7 +260,7 @@ public function testLoadData($area, $forceReload) /** * @return array */ - public function dataProviderForTestLoadData() + public function dataProviderForTestLoadData(): array { return [ ['adminhtml', true], @@ -275,7 +277,7 @@ public function dataProviderForTestLoadData() * @param $result * @dataProvider dataProviderForTestGetData */ - public function testGetData($data, $result) + public function testGetData($data, $result): void { $this->cache->expects($this->once()) ->method('load') @@ -288,7 +290,7 @@ public function testGetData($data, $result) /** * @return array */ - public function dataProviderForTestGetData() + public function dataProviderForTestGetData(): array { $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2']; return [ @@ -297,7 +299,7 @@ public function dataProviderForTestGetData() ]; } - public function testGetLocale() + public function testGetLocale(): void { $this->locale->expects($this->once())->method('getLocale')->will($this->returnValue('en_US')); $this->assertEquals('en_US', $this->translate->getLocale()); @@ -310,14 +312,14 @@ public function testGetLocale() $this->assertEquals('en_GB', $this->translate->getLocale()); } - public function testSetLocale() + public function testSetLocale(): void { $this->translate->setLocale('en_GB'); $this->locale->expects($this->never())->method('getLocale'); $this->assertEquals('en_GB', $this->translate->getLocale()); } - public function testGetTheme() + public function testGetTheme(): void { $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); @@ -329,7 +331,7 @@ public function testGetTheme() $this->assertEquals('themeTheme Title', $this->translate->getTheme()); } - public function testLoadDataNoTheme() + public function testLoadDataNoTheme(): void { $forceReload = true; $this->expectsSetConfig(null, null); @@ -343,7 +345,7 @@ public function testLoadDataNoTheme() /** * Declare calls expectation for setConfig() method */ - protected function expectsSetConfig($themeId, $localeCode = 'en_US') + protected function expectsSetConfig($themeId, $localeCode = 'en_US'): void { $this->locale->expects($this->any())->method('getLocale')->will($this->returnValue($localeCode)); $scope = new \Magento\Framework\DataObject(['code' => 'frontendCode', 'id' => 1]); From 16f2e0dd0b83e2d4135a384d3fb19a9e2db5c32c Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Sat, 10 Nov 2018 11:44:19 +0200 Subject: [PATCH 1133/1415] Add availability to leave empty config for events.xml --- lib/internal/Magento/Framework/Event/etc/events.xsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Event/etc/events.xsd b/lib/internal/Magento/Framework/Event/etc/events.xsd index d656b7fdb6ed6..cac62af356760 100644 --- a/lib/internal/Magento/Framework/Event/etc/events.xsd +++ b/lib/internal/Magento/Framework/Event/etc/events.xsd @@ -9,7 +9,7 @@ <xs:element name="config"> <xs:complexType> <xs:sequence> - <xs:element name="event" type="eventDeclaration" minOccurs="1" maxOccurs="unbounded"> + <xs:element name="event" type="eventDeclaration" minOccurs="0" maxOccurs="unbounded"> <xs:unique name="uniqueObserverName"> <xs:annotation> <xs:documentation> From 2d45eb37e2ee1b40eb59fbb0f60cc66c38198438 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Sat, 10 Nov 2018 10:51:04 -0400 Subject: [PATCH 1134/1415] Added _customerCollection property as public --- .../Model/ResourceModel/Import/Customer/Storage.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php index c5d28240c3068..1046afeebbf9b 100644 --- a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php +++ b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php @@ -48,6 +48,11 @@ class Storage */ private $customerCollectionFactory; + /** + * @var CustomerCollection + */ + public $_customerCollection; + /** * @param CustomerCollectionFactory $collectionFactory * @param CollectionByPagesIteratorFactory $colIteratorFactory @@ -58,6 +63,9 @@ public function __construct( CollectionByPagesIteratorFactory $colIteratorFactory, array $data = [] ) { + $this->_customerCollection = isset( + $data['customer_collection'] + ) ? $data['customer_collection'] : $collectionFactory->create(); $this->_pageSize = isset($data['page_size']) ? $data['page_size'] : 0; $this->_byPagesIterator = isset( $data['collection_by_pages_iterator'] From 7f3808cd5821355ec6193ae1d7785f0f522c889d Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Sat, 10 Nov 2018 11:04:47 -0400 Subject: [PATCH 1135/1415] Added public connection property --- .../Magento/DownloadableImportExport/Helper/Uploader.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php index 5fc4df1d03c49..de10bcea5d61e 100644 --- a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php +++ b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php @@ -38,6 +38,11 @@ class Uploader extends \Magento\Framework\App\Helper\AbstractHelper */ protected $parameters = []; + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface + */ + public $connection; + /** * Construct * @@ -62,6 +67,7 @@ public function __construct( $this->fileUploader->init(); $this->fileUploader->setAllowedExtensions($this->getAllowedExtensions()); $this->fileUploader->removeValidateCallback('catalog_product_image'); + $this->connection = $resource->getConnection('write'); $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); } From 1f1ec545f4a9e6d39dfd1ad186ecf2bafae36496 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Sat, 10 Nov 2018 20:01:19 +0200 Subject: [PATCH 1136/1415] Cleanup with static test --- app/code/Magento/Backend/Block/Widget/Grid.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Backend/Block/Widget/Grid.php b/app/code/Magento/Backend/Block/Widget/Grid.php index e9394be9e60bd..66298d23389fb 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid.php +++ b/app/code/Magento/Backend/Block/Widget/Grid.php @@ -150,7 +150,10 @@ public function __construct( } /** + * Internal constructor, that is called from real constructor + * * @return void + * * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _construct() @@ -709,6 +712,7 @@ public function getGridUrl() /** * Grid url getter + * * Version of getGridUrl() but with parameters * * @param array $params url parameters From ae61da5e5351745664672d17ad77059273d0af00 Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin <a.gorbulin@ism-ukraine.com> Date: Sat, 10 Nov 2018 20:06:15 +0200 Subject: [PATCH 1137/1415] 19082-Fatal-error-Uncaught-Error-Cannot-call-abstract-method-Magento-Framework-App-ActionInterface-execute add method to prevent fatal error when go to catalog/product/compare/ --- app/code/Magento/Catalog/Controller/Product/Compare.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php index 1ee146e5aaa70..63478080bce1a 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare.php @@ -139,4 +139,13 @@ public function setCustomerId($customerId) $this->_customerId = $customerId; return $this; } + + /** + * {@inheritdoc} + */ + public function execute() + { + return $this->_redirect('catalog/product_compare'); + } + } From 7ae271e7768c713e7ad83e8631e7308ac5b22193 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Sun, 11 Nov 2018 12:17:24 +0200 Subject: [PATCH 1138/1415] Fix unit test of Framework/Event module --- .../Event/Test/Unit/Config/_files/invalidEventsXmlArray.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/invalidEventsXmlArray.php b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/invalidEventsXmlArray.php index 33007b7295bca..e0dc7494cca19 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/invalidEventsXmlArray.php +++ b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/invalidEventsXmlArray.php @@ -4,10 +4,6 @@ * See COPYING.txt for license details. */ return [ - 'without_event_handle' => [ - '<?xml version="1.0"?><config></config>', - ["Element 'config': Missing child element(s). Expected is ( event ).\nLine: 1\n"], - ], 'event_without_required_name_attribute' => [ '<?xml version="1.0"?><config><event name="some_name"></event></config>', ["Element 'event': Missing child element(s). Expected is ( observer ).\nLine: 1\n"], From 284daec007cc9cc5bacc736e3d6ce00ebdf751ef Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 12 Nov 2018 15:00:28 +0200 Subject: [PATCH 1139/1415] magento/magento2#5929: [Forwardport] Saving Product does not update URL rewrite. --- ...ProductProcessUrlRewriteSavingObserver.php | 21 +++++++++++++++++-- ...uctProcessUrlRewriteSavingObserverTest.php | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php index c4d67f447e2cf..6eda8dd0b61ee 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php @@ -6,11 +6,15 @@ namespace Magento\CatalogUrlRewrite\Observer; use Magento\Catalog\Model\Product; +use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Framework\App\ObjectManager; use Magento\UrlRewrite\Model\UrlPersistInterface; -use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; use Magento\Framework\Event\ObserverInterface; +/** + * Class ProductProcessUrlRewriteSavingObserver + */ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface { /** @@ -23,22 +27,33 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface */ private $urlPersist; + /** + * @var ProductUrlPathGenerator + */ + private $productUrlPathGenerator; + /** * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator * @param UrlPersistInterface $urlPersist + * @param ProductUrlPathGenerator|null $productUrlPathGenerator */ public function __construct( ProductUrlRewriteGenerator $productUrlRewriteGenerator, - UrlPersistInterface $urlPersist + UrlPersistInterface $urlPersist, + ProductUrlPathGenerator $productUrlPathGenerator = null ) { $this->productUrlRewriteGenerator = $productUrlRewriteGenerator; $this->urlPersist = $urlPersist; + $this->productUrlPathGenerator = $productUrlPathGenerator ?: ObjectManager::getInstance() + ->get(ProductUrlPathGenerator::class); } /** * Generate urls for UrlRewrite and save it in storage + * * @param \Magento\Framework\Event\Observer $observer * @return void + * @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException */ public function execute(\Magento\Framework\Event\Observer $observer) { @@ -51,6 +66,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) || $product->dataHasChangedFor('visibility') ) { if ($product->isVisibleInSiteVisibility()) { + $product->unsUrlPath(); + $product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product)); $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php index 9de0588356c43..c72a58197b1fd 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php @@ -90,6 +90,7 @@ public function testUrlKeyHasChangedInGlobalContext() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ @@ -152,6 +153,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ @@ -207,6 +209,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirectio $product->setData('save_rewrites_history', false); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ From 63922949f0a1a2d018900672968cd8714a901db7 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 15:01:50 +0200 Subject: [PATCH 1140/1415] GraphQl-28: Implement query complexity limiting --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 622888f697b84..914dcc78e49e1 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,7 +100,7 @@ <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> <argument name="queryDepth" xsi:type="number">20</argument> - <argument name="queryComplexity" xsi:type="number">160</argument> + <argument name="queryComplexity" xsi:type="number">250</argument> </arguments> </type> </config> diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 3936da21fc56a..5730156ca5b34 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -38,8 +38,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 20, - int $queryComplexity = 160 + int $queryDepth, + int $queryComplexity ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From 29a86a3907115d0f186d9937a5f90d45626f6566 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 12 Nov 2018 15:35:16 +0200 Subject: [PATCH 1141/1415] magento/magento2#16887: [Forwardport] Fix blocked a frame with origin. --- .../view/frontend/web/js/page-cache.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index fccc8510ffc70..11707ea491fb5 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -6,9 +6,10 @@ define([ 'jquery', 'domReady', + 'consoleLogger', 'jquery/ui', 'mage/cookies' -], function ($, domReady) { +], function ($, domReady, consoleLogger) { 'use strict'; /** @@ -46,14 +47,30 @@ define([ // prevent cross origin iframe content reading if ($(element).prop('tagName') === 'IFRAME') { iframeHostName = $('<a>').prop('href', $(element).prop('src')) - .prop('hostname'); + .prop('hostname'); if (window.location.hostname !== iframeHostName) { return []; } } - $(element).contents().each(function (index, el) { + // rewrite jQuery contents() + var contents = function (element) { + return $.map(element, function (elem) { + try { + return $.nodeName(elem, "iframe") ? + elem.contentDocument || (elem.contentWindow ? elem.contentWindow.document : []) : + $.merge([], elem.childNodes); + } catch (e) { + consoleLogger.error(e); + return []; + } + }); + }; + + var elementContents = contents($(element)); + + $.each(elementContents, function (index, el) { switch (el.nodeType) { case 1: // ELEMENT_NODE lookup(el); From f0dedde4c6fa32c84579928d48d613cf65684eca Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 15:59:02 +0200 Subject: [PATCH 1142/1415] GraphQl-41: [Query] My Account > My Orders --- .../SalesGraphQl/Model/Resolver/Orders.php | 98 ++++++------ app/code/Magento/SalesGraphQl/composer.json | 3 + .../Magento/GraphQl/Sales/OrdersTest.php | 133 ++++++++-------- .../Sales/_files/orders_with_customer.php | 148 +++++++++--------- 4 files changed, 188 insertions(+), 194 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index 05af6829de454..f058ce9ae3bdd 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -7,70 +7,66 @@ namespace Magento\SalesGraphQl\Model\Resolver; -use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface; -use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; /** - * Class Orders + * Orders data reslover */ class Orders implements ResolverInterface { - /** - * @var CollectionFactoryInterface - */ - private $collectionFactory; + /** + * @var CollectionFactoryInterface + */ + private $collectionFactory; - /** - * @var CheckCustomerAccountInterface - */ - private $checkCustomerAccount; + /** + * @var CheckCustomerAccount + */ + private $checkCustomerAccount; - /** - * Orders constructor. - * @param CollectionFactoryInterface $collectionFactory - * @param CheckCustomerAccountInterface $checkCustomerAccount - */ - public function __construct( - CollectionFactoryInterface $collectionFactory, - CheckCustomerAccountInterface $checkCustomerAccount - ) { - $this->collectionFactory = $collectionFactory; - $this->checkCustomerAccount = $checkCustomerAccount; + /** + * @param CollectionFactoryInterface $collectionFactory + * @param CheckCustomerAccount $checkCustomerAccount + */ + public function __construct( + CollectionFactoryInterface $collectionFactory, + CheckCustomerAccount $checkCustomerAccount + ) { + $this->collectionFactory = $collectionFactory; + $this->checkCustomerAccount = $checkCustomerAccount; - } + } - /** - * {@inheritdoc} - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - $customerId = $context->getUserId(); + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $customerId = $context->getUserId(); + $this->checkCustomerAccount->execute($customerId, $context->getUserType()); - $this->checkCustomerAccount->execute($customerId, $context->getUserType()); + $items = []; + $orders = $this->collectionFactory->create($customerId); - $items = []; - $orders = $this->collectionFactory->create($customerId); - - /** @var \Magento\Sales\Model\Order $order */ - foreach ($orders as $order) { - $items[] = [ - 'id' => $order->getId(), - 'increment_id' => $order->getIncrementId(), - 'created_at' => $order->getCreatedAt(), - 'grand_total' => $order->getGrandTotal(), - 'status' => $order->getStatus() - ]; - } - - return ['items' => $items]; - } + /** @var \Magento\Sales\Model\Order $order */ + foreach ($orders as $order) { + $items[] = [ + 'id' => $order->getId(), + 'increment_id' => $order->getIncrementId(), + 'created_at' => $order->getCreatedAt(), + 'grand_total' => $order->getGrandTotal(), + 'status' => $order->getStatus(), + ]; + } + return ['items' => $items]; + } } diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index b75e18c7b7a97..3e29adbe7009e 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -5,8 +5,11 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", + "magento/module-authorization": "*", "magento/module-customer": "*", + "magento/module-customer-graph-ql": "*", "magento/module-catalog": "*", + "magento/module-sales": "*", "magento/module-store": "*" }, "suggest": { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index 33620f6e55386..589b0bc7746f8 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -16,93 +16,88 @@ */ class OrdersTest extends GraphQlAbstract { - /** - * @var CustomerTokenServiceInterface - */ - private $customerTokenService; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; - /** - * {@inheritdoc} - */ protected function setUp() { parent::setUp(); - $objectManager = Bootstrap::getObjectManager(); - $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); } - /** - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php - */ + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php + */ public function testOrdersQuery() { - $query = - <<<QUERY + $query = + <<<QUERY query { customerOrders { items { - id - increment_id - created_at - grand_total - status - } + id + increment_id + created_at + grand_total + status + } } } QUERY; - $currentEmail = 'customer@example.com'; - $currentPassword = 'password'; - - $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); + $currentEmail = 'customer@example.com'; + $currentPassword = 'password'; + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); - $expectedData = [ - [ - 'increment_id' => '100000002', - 'status' => 'processing', - 'grand_total' => 120.00 - ], - [ - 'increment_id' => '100000003', - 'status' => 'processing', - 'grand_total' => 130.00 - ], - [ - 'increment_id' => '100000004', - 'status' => 'closed', - 'grand_total' => 140.00 - ], - [ - 'increment_id' => '100000005', - 'status' => 'complete', - 'grand_total' => 150.00 - ], - [ - 'increment_id' => '100000006', - 'status' => 'complete', - 'grand_total' => 160.00 - ] - ]; + $expectedData = [ + [ + 'increment_id' => '100000002', + 'status' => 'processing', + 'grand_total' => 120.00 + ], + [ + 'increment_id' => '100000003', + 'status' => 'processing', + 'grand_total' => 130.00 + ], + [ + 'increment_id' => '100000004', + 'status' => 'closed', + 'grand_total' => 140.00 + ], + [ + 'increment_id' => '100000005', + 'status' => 'complete', + 'grand_total' => 150.00 + ], + [ + 'increment_id' => '100000006', + 'status' => 'complete', + 'grand_total' => 160.00 + ] + ]; - $actualData = $response['customerOrders']['items']; + $actualData = $response['customerOrders']['items']; - foreach ($expectedData as $key => $data) { - $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); - $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); - $this->assertEquals($data['status'], $actualData[$key]['status']); - } + foreach ($expectedData as $key => $data) { + $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); + $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); + $this->assertEquals($data['status'], $actualData[$key]['status']); + } } - /** - * @param string $email - * @param string $password - * @return array - * @throws \Magento\Framework\Exception\AuthenticationException - */ - private function getCustomerAuthHeaders(string $email, string $password): array - { - $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); - return ['Authorization' => 'Bearer ' . $customerToken]; - } + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php index e649396391ca9..6906166f7cbe5 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -14,88 +14,88 @@ /** @var Order\Item $orderItem */ /** @var array $addressData Data for creating addresses for the orders. */ $orders = [ - [ - 'increment_id' => '100000002', - 'state' => \Magento\Sales\Model\Order::STATE_NEW, - 'status' => 'processing', - 'grand_total' => 120.00, - 'subtotal' => 120.00, - 'base_grand_total' => 120.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000003', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, - 'status' => 'processing', - 'grand_total' => 130.00, - 'base_grand_total' => 130.00, - 'subtotal' => 130.00, - 'store_id' => 0, - 'website_id' => 0, - 'payment' => $payment - ], - [ - 'increment_id' => '100000004', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, - 'status' => 'closed', - 'grand_total' => 140.00, - 'base_grand_total' => 140.00, - 'subtotal' => 140.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000005', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, - 'status' => 'complete', - 'grand_total' => 150.00, - 'base_grand_total' => 150.00, - 'subtotal' => 150.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000006', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, - 'status' => 'complete', - 'grand_total' => 160.00, - 'base_grand_total' => 160.00, - 'subtotal' => 160.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'base_grand_total' => 120.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 130.00, + 'base_grand_total' => 130.00, + 'subtotal' => 130.00, + 'store_id' => 0, + 'website_id' => 0, + 'payment' => $payment + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 150.00, + 'base_grand_total' => 150.00, + 'subtotal' => 150.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 160.00, + 'base_grand_total' => 160.00, + 'subtotal' => 160.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], ]; /** @var OrderRepositoryInterface $orderRepository */ $orderRepository = $objectManager->create(OrderRepositoryInterface::class); /** @var array $orderData */ foreach ($orders as $orderData) { - /** @var $order \Magento\Sales\Model\Order */ - $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\Order::class - ); + /** @var $order \Magento\Sales\Model\Order */ + $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order::class + ); - // Reset addresses - /** @var Order\Address $billingAddress */ - $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); - $billingAddress->setAddressType('billing'); + // Reset addresses + /** @var Order\Address $billingAddress */ + $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); + $billingAddress->setAddressType('billing'); - $shippingAddress = clone $billingAddress; - $shippingAddress->setId(null)->setAddressType('shipping'); + $shippingAddress = clone $billingAddress; + $shippingAddress->setId(null)->setAddressType('shipping'); - $order - ->setData($orderData) - ->addItem($orderItem) - ->setCustomerIsGuest(false) - ->setCustomerId(1) - ->setCustomerEmail('customer@example.com') - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress); + $order + ->setData($orderData) + ->addItem($orderItem) + ->setCustomerIsGuest(false) + ->setCustomerId(1) + ->setCustomerEmail('customer@example.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress); - $orderRepository->save($order); + $orderRepository->save($order); } From 198fc61326ad0c575997649e649753d946ac3b70 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:08:57 +0200 Subject: [PATCH 1143/1415] GraphQl-41: [Query] My Account > My Orders --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index d4ac4fc091bbc..7fc23572cbb34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "78153b5c8150c0d145b3372a534a45eb", + "content-hash": "7986e75e7ec3308bfd361f2076544eb7", "packages": [ { "name": "braintree/braintree_php", From a04317746efcaa2aa00c04930a5de428e2753ac1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:11:11 +0200 Subject: [PATCH 1144/1415] GraphQl-41: [Query] My Account > My Orders --- app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index f058ce9ae3bdd..5802115d44b5e 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -38,7 +38,6 @@ public function __construct( ) { $this->collectionFactory = $collectionFactory; $this->checkCustomerAccount = $checkCustomerAccount; - } /** From 34af04fc6f288e217129ed32a82a60a51bdce5b9 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 12 Nov 2018 17:11:25 +0300 Subject: [PATCH 1145/1415] MAGETWO-91784: On Payment screen up and down arrow key allow to add -ve numbers - Fixed static test. --- .../view/base/web/js/model/credit-card-validation/validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js index f9af514a6d4da..c41be40cba144 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js @@ -23,7 +23,7 @@ }(function ($, cvvValidator, creditCardNumberValidator, yearValidator, monthValidator, creditCardData) { 'use strict'; - $('.payment-method-content input[type="number"]').on('keyup', function() { + $('.payment-method-content input[type="number"]').on('keyup', function () { if ($(this).val() < 0) { $(this).val($(this).val().replace(/^-/, '')); } From 7e5be32f56ac80bde8dbd6d8e55da12c3923dbb4 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 12 Nov 2018 17:18:10 +0300 Subject: [PATCH 1146/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Fixed static test. --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index c1cccae85971c..7578774fabc2c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -22,7 +22,7 @@ $allowedQty = $block->getMinMaxQty(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" + <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From abc43aca2b420e0b4baebab6c414e2f20a63a3c1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:49:40 +0200 Subject: [PATCH 1147/1415] GraphQl-41: [Query] My Account > My Orders --- app/code/Magento/SalesGraphQl/composer.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index 3e29adbe7009e..0549d31d59a24 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -5,12 +5,8 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-customer": "*", "magento/module-customer-graph-ql": "*", - "magento/module-catalog": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/module-sales": "*" }, "suggest": { "magento/module-graph-ql": "*" From 0aad3fb3eeea271eed53f923d0464147666135a5 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 17:02:06 +0200 Subject: [PATCH 1148/1415] GraphQl-41: [Query] My Account > My Orders --- .../testsuite/Magento/Sales/_files/orders_with_customer.php | 1 + .../Magento/Sales/_files/orders_with_customer_rollback.php | 1 + 2 files changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php index 6906166f7cbe5..753adb1f38596 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Sales\Model\Order; use Magento\Sales\Api\OrderRepositoryInterface; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php index 6e24cee501f51..1fb4b4636ab29 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php @@ -3,5 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require 'default_rollback.php'; From 0566957554fa964f79518b7b93920fe12db39c8a Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 12 Nov 2018 17:03:30 +0200 Subject: [PATCH 1149/1415] magento/magento2#18939: [Forwardport] fixed js translation. --- app/code/Magento/Tax/i18n/en_US.csv | 1 + .../Tax/view/frontend/web/js/view/checkout/summary/tax.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Tax/i18n/en_US.csv b/app/code/Magento/Tax/i18n/en_US.csv index e6d89deb7696c..836221e2ec974 100644 --- a/app/code/Magento/Tax/i18n/en_US.csv +++ b/app/code/Magento/Tax/i18n/en_US.csv @@ -178,3 +178,4 @@ Rate,Rate "Your credit card will be charged for","Your credit card will be charged for" "An error occurred while loading tax rates.","An error occurred while loading tax rates." "You will be charged for","You will be charged for" +"Not yet calculated", "Not yet calculated" diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js index c86c3b4d1ab06..b21be98531ba9 100644 --- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js +++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js @@ -11,8 +11,9 @@ define([ 'ko', 'Magento_Checkout/js/view/summary/abstract-total', 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/model/totals' -], function (ko, Component, quote, totals) { + 'Magento_Checkout/js/model/totals', + 'mage/translate' +], function (ko, Component, quote, totals, $t) { 'use strict'; var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal, @@ -22,7 +23,7 @@ define([ return Component.extend({ defaults: { isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal, - notCalculatedMessage: 'Not yet calculated', + notCalculatedMessage: $t('Not yet calculated'), template: 'Magento_Tax/checkout/summary/tax' }, totals: quote.getTotals(), From daf7bcbefd8bddeab0043229883700f04de59f65 Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Mon, 12 Nov 2018 18:08:28 +0200 Subject: [PATCH 1150/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - delete several waits, add minor changes according to code review comments --- ...rderWithOnlinePaymentIncludingTaxAndDiscount.xml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml index 7c0a503e7bb4b..4feb47ae78e15 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -10,20 +10,20 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="CreateAdminOrderPayedWithOnlinePaymentIncludingTaxAndDiscount"> <annotations> - <features value="Sales"/> + <features value="Braintree"/> <stories value="Get access to a New Credit Memo Page from Invocie for Order payed with online payment via Admin"/> <title value="Admin should be able to open a New Credit Memo Page from Invoice Page for Order with tax and discount and payed using online payment method"/> <description value="Admin should be able to open a New Credit Memo Page from Invoice Page for Order with tax and discount and payed using online payment method"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-94472"/> - <group value="sales"/> + <group value="braintree"/> </annotations> <before> <!--Create Default Category--> <createData entity="SimpleSubCategory" stepKey="createCategory"/> - <!--Create Simple product with Special Price--> + <!--Create Simple product--> <createData entity="_defaultProduct" stepKey="simpleProduct"> <requiredEntity createDataKey="createCategory"/> </createData> @@ -99,8 +99,9 @@ <!--Submit Order--> <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> - <waitForPageLoad stepKey="waitForSaveConfig" time="10"/> - <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="5"/> + <waitForPageLoad stepKey="waitForSubmitOrder" time="5"/> + <see selector="{{NewOrderSection.successMessage}}" userInput="You created the order." stepKey="seeNewOrder" after="waitForSubmitOrder"/> + <!-- Create New invoice--> <actionGroup ref="adminFastCreateInvoice" stepKey="createInvoice"/> @@ -108,6 +109,6 @@ <!--Get access to Credit Memo page from Invocie page--> <click selector="{{AdminInvoiceMainActionsSection.openNewCreditMemoFromInvoice}}" stepKey="clickCreateNewCreditMemo"/> <waitForPageLoad stepKey="waitForLoadNewCreditMemoPage" time="5"/> - <waitForElementVisible selector="{{AdminCreditMemoOrderInformationSection.orderId}}" stepKey="waitForOrderIdOnCreditMemoPage"/> + <see selector="{{AdminCreditMemoOrderInformationSection.orderId}}" userInput="New Memo" stepKey="seeNewCreditMemo" after="waitForLoadNewCreditMemoPage"/> </test> </tests> \ No newline at end of file From 84a3cd8f9c7aa58fccf8f71e527e26295529268a Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 12 Nov 2018 18:55:56 +0200 Subject: [PATCH 1151/1415] Covering the CheckUserLoginBackendObserver by Unit Test --- .../CheckUserLoginBackendObserverTest.php | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php new file mode 100644 index 0000000000000..b7b11a56fd5ce --- /dev/null +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -0,0 +1,174 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Captcha\Test\Unit\Observer; + +use Magento\Captcha\Helper\Data; +use Magento\Captcha\Model\DefaultModel; +use Magento\Captcha\Observer\CaptchaStringResolver; +use Magento\Captcha\Observer\CheckUserLoginBackendObserver; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\Exception\Plugin\AuthenticationException; +use Magento\Framework\Message\ManagerInterface; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class CheckUserLoginBackendObserverTest + */ +class CheckUserLoginBackendObserverTest extends TestCase +{ + /** + * @var CheckUserLoginBackendObserver + */ + private $observer; + + /** + * @var ManagerInterface|MockObject + */ + private $messageManagerMock; + + /** + * @var CaptchaStringResolver|MockObject + */ + private $captchaStringResolverMock; + + /** + * @var RequestInterface|MockObject + */ + private $requestMock; + + /** + * @var Data|MockObject + */ + private $helperMock; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->helperMock = $this->createMock(Data::class); + $this->messageManagerMock = $this->createMock(ManagerInterface::class); + $this->captchaStringResolverMock = $this->createMock(CaptchaStringResolver::class); + $this->requestMock = $this->createMock(RequestInterface::class); + + $this->observer = new CheckUserLoginBackendObserver( + $this->helperMock, + $this->captchaStringResolverMock, + $this->requestMock + ); + } + + /** + * Test check user login in backend with correct captcha + * + * @dataProvider captchaCorrectnessCheckDataProvider + * @param bool $isRequired + * @param bool $isCorrect + * @param int $invokedTimes + * @return void + * @throws AuthenticationException + */ + public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrect, $invokedTimes) + { + $formId = 'backend_login'; + $login = 'admin'; + $captchaValue = 'captcha-value'; + + $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); + $eventMock = $this->createPartialMock(Event::class, ['getUsername']); + $captcha = $this->createMock(DefaultModel::class); + + $eventMock->expects($this->any()) + ->method('getUsername') + ->willReturn('admin'); + $observerMock->expects($this->any()) + ->method('getEvent') + ->willReturn($eventMock); + $captcha->expects($this->once())->method('isRequired') + ->with($login) + ->willReturn($isRequired); + $captcha->expects($this->exactly($invokedTimes)) + ->method('isCorrect') + ->with($captchaValue) + ->willReturn($isCorrect); + $this->helperMock->expects($this->once()) + ->method('getCaptcha') + ->with($formId) + ->willReturn($captcha); + + $this->captchaStringResolverMock->expects($this->exactly($invokedTimes)) + ->method('resolve') + ->with($this->requestMock, $formId) + ->willReturn($captchaValue); + + $this->messageManagerMock->expects($this->exactly(0)) + ->method('addError') + ->with(__('Incorrect CAPTCHA')); + + $this->observer->execute($observerMock); + } + + /** + * @return array + */ + public function captchaCorrectnessCheckDataProvider() + { + return [ + [true, true, 1], + [false, true, 0] + ]; + } + + + /** + * Test check user login in backend with wrong captcha + * + * @return void + * @throws AuthenticationException + */ + public function testCheckOnBackendLoginWithWrongCaptcha() + { + $formId = 'backend_login'; + $login = 'admin'; + $captchaValue = 'captcha-value'; + + $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); + $eventMock = $this->createPartialMock(Event::class, ['getUsername']); + $captcha = $this->createMock(DefaultModel::class); + + $eventMock->expects($this->any()) + ->method('getUsername') + ->willReturn('admin'); + $observerMock->expects($this->any()) + ->method('getEvent') + ->willReturn($eventMock); + $captcha->expects($this->once())->method('isRequired') + ->with($login) + ->willReturn(true); + $captcha->expects($this->exactly(1)) + ->method('isCorrect') + ->with($captchaValue) + ->willReturn(false); + $this->helperMock->expects($this->once()) + ->method('getCaptcha') + ->with($formId) + ->willReturn($captcha); + + $this->captchaStringResolverMock->expects($this->exactly(1)) + ->method('resolve') + ->with($this->requestMock, $formId) + ->willReturn($captchaValue); + + $this->expectException(AuthenticationException::class, 'Incorrect CAPTCHA.'); + + $this->observer->execute($observerMock); + } +} From 246eb673397e7358bc1ee295bec59ef66b6cfba2 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 12 Nov 2018 19:02:12 +0200 Subject: [PATCH 1152/1415] Adding strict types --- .../Observer/CheckUserLoginBackendObserverTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index b7b11a56fd5ce..02f6bed520acd 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Captcha\Test\Unit\Observer; use Magento\Captcha\Helper\Data; @@ -76,12 +78,13 @@ protected function setUp() * @return void * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrect, $invokedTimes) + public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $isCorrect, int $invokedTimes): void { $formId = 'backend_login'; $login = 'admin'; $captchaValue = 'captcha-value'; + /** @var Observer|MockObject $observerMock */ $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); @@ -119,7 +122,7 @@ public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrec /** * @return array */ - public function captchaCorrectnessCheckDataProvider() + public function captchaCorrectnessCheckDataProvider(): array { return [ [true, true, 1], @@ -134,12 +137,13 @@ public function captchaCorrectnessCheckDataProvider() * @return void * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithWrongCaptcha() + public function testCheckOnBackendLoginWithWrongCaptcha(): void { $formId = 'backend_login'; $login = 'admin'; $captchaValue = 'captcha-value'; + /** @var Observer|MockObject $observerMock */ $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); @@ -167,7 +171,7 @@ public function testCheckOnBackendLoginWithWrongCaptcha() ->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->expectException(AuthenticationException::class, 'Incorrect CAPTCHA.'); + $this->expectException(AuthenticationException::class); $this->observer->execute($observerMock); } From 548ca3c97565e99ebe8bcfa42e1f421de23c4898 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Mon, 12 Nov 2018 19:11:54 +0200 Subject: [PATCH 1153/1415] Added option_id in response for product with customizable options. --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 1 + .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5efe37d8f91f6..5c15d1f4a07e7 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -358,6 +358,7 @@ interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGrap title: String @doc(description: "The display name for this option") required: Boolean @doc(description: "Indicates whether the option is required") sort_order: Int @doc(description: "The order in which the option is displayed") + option_id: Int @doc(description: "Option ID") } interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "CustomizableProductInterface contains information about customizable product options.") { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 791696b2fa29e..77384165db97f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -91,6 +91,7 @@ public function testQueryAllFieldsSimpleProduct() title required sort_order + option_id ... on CustomizableFieldOption { product_sku field_option: value { @@ -337,6 +338,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() title required sort_order + option_id ... on CustomizableFieldOption { product_sku field_option: value { @@ -753,7 +755,8 @@ private function assertOptions($product, $actualResponse) $assertionMap = [ ['response_field' => 'sort_order', 'expected_value' => $option->getSortOrder()], ['response_field' => 'title', 'expected_value' => $option->getTitle()], - ['response_field' => 'required', 'expected_value' => $option->getIsRequire()] + ['response_field' => 'required', 'expected_value' => $option->getIsRequire()], + ['response_field' => 'option_id', 'expected_value' => $option->getOptionId()] ]; if (!empty($option->getValues())) { @@ -777,7 +780,7 @@ private function assertOptions($product, $actualResponse) ['response_field' => 'product_sku', 'expected_value' => $option->getProductSku()], ] ); - $valueKeyName = ""; + if ($option->getType() === 'file') { $valueKeyName = 'file_option'; $valueAssertionMap = [ From 815f013d2a04212f69ae84871eb2d22ea60efcad Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 12 Nov 2018 16:17:38 -0600 Subject: [PATCH 1154/1415] #2331: Fixing static tests --- app/code/Magento/Customer/Controller/Section/Load.php | 2 +- app/code/Magento/Customer/CustomerData/Section/Identifier.php | 2 +- app/code/Magento/Customer/CustomerData/SectionPool.php | 2 +- .../Magento/Customer/Controller/Section/LoadTest.php | 4 +++- lib/internal/Magento/Framework/Test/Unit/TranslateTest.php | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php index 89d4417c79c19..37cd071b13623 100644 --- a/app/code/Magento/Customer/Controller/Section/Load.php +++ b/app/code/Magento/Customer/Controller/Section/Load.php @@ -59,7 +59,7 @@ public function __construct( } /** - * @return \Magento\Framework\Controller\Result\Json + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/Customer/CustomerData/Section/Identifier.php b/app/code/Magento/Customer/CustomerData/Section/Identifier.php index 54d7cee2d90bd..a8bc2c8abc11a 100644 --- a/app/code/Magento/Customer/CustomerData/Section/Identifier.php +++ b/app/code/Magento/Customer/CustomerData/Section/Identifier.php @@ -67,7 +67,7 @@ public function initMark($forceNewTimestamp) * Mark sections with data id * * @param array $sectionsData - * @param null $sectionNames + * @param array|null $sectionNames * @param bool $forceNewTimestamp * @return array */ diff --git a/app/code/Magento/Customer/CustomerData/SectionPool.php b/app/code/Magento/Customer/CustomerData/SectionPool.php index 618d52079973d..efea1762d9de6 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPool.php +++ b/app/code/Magento/Customer/CustomerData/SectionPool.php @@ -53,7 +53,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false) { diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php index 3563087d3722b..3db22b8379850 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php @@ -13,7 +13,9 @@ public function testLoadInvalidSection() $expected = [ 'message' => 'The "section<invalid" section source isn't supported.', ]; - $this->dispatch('/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394'); + $this->dispatch( + '/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394' + ); self::assertEquals(json_encode($expected), $this->getResponse()->getBody()); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php index 885be8557fa10..0ec27d6d053c3 100644 --- a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -11,6 +11,7 @@ use Magento\Framework\Translate; /** + * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TranslateTest extends \PHPUnit\Framework\TestCase From 0e59e8c244463d74e7949bbb1710d13f1990537d Mon Sep 17 00:00:00 2001 From: saphal <saphal.jha@krishtechnolabs.com> Date: Tue, 13 Nov 2018 10:36:08 +0530 Subject: [PATCH 1155/1415] code updated as per instructions --- app/code/Magento/Review/Model/ResourceModel/Rating.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 77a9727bd849e..04dce420ae522 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -425,11 +425,11 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); - $currentStore = ($this->_storeManager->isSingleStoreMode()) ? $this->_storeManager->getStore()->getId() : NULL ; + $currentStore = ($this->_storeManager->isSingleStoreMode()) ? $this->_storeManager->getStore()->getId() : null ; if ($onlyForCurrentStore) { foreach ($data as $row) { - if (!$row['store_id'] == $currentStore) { + if ($row['store_id'] !== $currentStore) { $object->addData($row); } } From 993ba971580958cdcdb779c80c193bd86183776c Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 09:47:20 +0200 Subject: [PATCH 1156/1415] Adjusting the Unit Test strictness --- .../CheckUserLoginBackendObserverTest.php | 76 +++++-------------- 1 file changed, 18 insertions(+), 58 deletions(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index 02f6bed520acd..2d0a2a7e1c99a 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -14,7 +14,6 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\Event; use Magento\Framework\Event\Observer; -use Magento\Framework\Exception\Plugin\AuthenticationException; use Magento\Framework\Message\ManagerInterface; use PHPUnit\Framework\TestCase; use PHPUnit_Framework_MockObject_MockObject as MockObject; @@ -71,14 +70,11 @@ protected function setUp() /** * Test check user login in backend with correct captcha * - * @dataProvider captchaCorrectnessCheckDataProvider + * @dataProvider requiredCaptchaDataProvider * @param bool $isRequired - * @param bool $isCorrect - * @param int $invokedTimes * @return void - * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $isCorrect, int $invokedTimes): void + public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired): void { $formId = 'backend_login'; $login = 'admin'; @@ -89,44 +85,25 @@ public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); - $eventMock->expects($this->any()) - ->method('getUsername') - ->willReturn('admin'); - $observerMock->expects($this->any()) - ->method('getEvent') - ->willReturn($eventMock); - $captcha->expects($this->once())->method('isRequired') - ->with($login) - ->willReturn($isRequired); - $captcha->expects($this->exactly($invokedTimes)) - ->method('isCorrect') - ->with($captchaValue) - ->willReturn($isCorrect); - $this->helperMock->expects($this->once()) - ->method('getCaptcha') - ->with($formId) - ->willReturn($captcha); - - $this->captchaStringResolverMock->expects($this->exactly($invokedTimes)) - ->method('resolve') - ->with($this->requestMock, $formId) + $eventMock->method('getUsername')->willReturn('admin'); + $observerMock->method('getEvent')->willReturn($eventMock); + $captcha->method('isRequired')->with($login)->willReturn($isRequired); + $captcha->method('isCorrect')->with($captchaValue)->willReturn(true); + $this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha); + $this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->messageManagerMock->expects($this->exactly(0)) - ->method('addError') - ->with(__('Incorrect CAPTCHA')); - $this->observer->execute($observerMock); } /** * @return array */ - public function captchaCorrectnessCheckDataProvider(): array + public function requiredCaptchaDataProvider(): array { return [ - [true, true, 1], - [false, true, 0] + [true], + [false] ]; } @@ -135,7 +112,7 @@ public function captchaCorrectnessCheckDataProvider(): array * Test check user login in backend with wrong captcha * * @return void - * @throws AuthenticationException + * @expectedException \Magento\Framework\Exception\Plugin\AuthenticationException */ public function testCheckOnBackendLoginWithWrongCaptcha(): void { @@ -148,31 +125,14 @@ public function testCheckOnBackendLoginWithWrongCaptcha(): void $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); - $eventMock->expects($this->any()) - ->method('getUsername') - ->willReturn('admin'); - $observerMock->expects($this->any()) - ->method('getEvent') - ->willReturn($eventMock); - $captcha->expects($this->once())->method('isRequired') - ->with($login) - ->willReturn(true); - $captcha->expects($this->exactly(1)) - ->method('isCorrect') - ->with($captchaValue) - ->willReturn(false); - $this->helperMock->expects($this->once()) - ->method('getCaptcha') - ->with($formId) - ->willReturn($captcha); - - $this->captchaStringResolverMock->expects($this->exactly(1)) - ->method('resolve') - ->with($this->requestMock, $formId) + $eventMock->method('getUsername')->willReturn($login); + $observerMock->method('getEvent')->willReturn($eventMock); + $captcha->method('isRequired')->with($login)->willReturn(true); + $captcha->method('isCorrect')->with($captchaValue)->willReturn(false); + $this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha); + $this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->expectException(AuthenticationException::class); - $this->observer->execute($observerMock); } } From 8f463db4808afc9f8f4908a4dee65f3abe981eba Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Mon, 22 Oct 2018 18:23:19 +0530 Subject: [PATCH 1157/1415] Added tier price logic for special price --- .../Model/Product/Attribute/Backend/Tierprice.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 92b9a2e4239b2..55b5c6c925b05 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -159,8 +159,22 @@ protected function validatePrice(array $priceRow) */ protected function modifyPriceData($object, $data) { + /** @var \Magento\Catalog\Model\Product $object */ $data = parent::modifyPriceData($object, $data); $price = $object->getPrice(); + + $specialPrice = $object->getSpecialPrice(); + $specialPriceFromDate = $object->getSpecialFromDate(); + $specialPriceToDate = $object->getSpecialToDate(); + $today = time(); + + if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())){ + if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $price = $specialPrice; + } + } + foreach ($data as $key => $tierPrice) { $percentageValue = $this->getPercentage($tierPrice); if ($percentageValue) { From 63c9ea46673e58f2712da5a768d0840ece184152 Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 08:19:55 +0530 Subject: [PATCH 1158/1415] Fixed code standard error --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 55b5c6c925b05..88d8198d0249e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -168,9 +168,9 @@ protected function modifyPriceData($object, $data) $specialPriceToDate = $object->getSpecialToDate(); $today = time(); - if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())){ + if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate) === TRUE) { $price = $specialPrice; } } From 77492c1c08695753b3a274b02552fab7be9c64c0 Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 16:27:07 +0530 Subject: [PATCH 1159/1415] Update Tierprice.php --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 88d8198d0249e..b74be1372a3c0 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -170,7 +170,7 @@ protected function modifyPriceData($object, $data) if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate) === TRUE) { + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { $price = $specialPrice; } } From d0ba9973dffac27560364906b22786d70410d69d Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Thu, 1 Nov 2018 17:59:10 +0530 Subject: [PATCH 1160/1415] Update Tierprice.php --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index b74be1372a3c0..23b2dfa01bfbd 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -170,7 +170,7 @@ protected function modifyPriceData($object, $data) if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $today >= strtotime($specialPriceFromDate) && $specialPriceToDate === null) { $price = $specialPrice; } } From e697698a5be421e215f6bab5454d706eed97fb6e Mon Sep 17 00:00:00 2001 From: Magently <hello@magently.com> Date: Fri, 24 Aug 2018 16:58:02 +0200 Subject: [PATCH 1161/1415] Fix addExpressionFieldToSelect method generated columns get overwriten by addFieldToSelect() --- .../Model/ResourceModel/Db/Collection/AbstractCollection.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php index b57755ed7eafa..a88e013f5d2fe 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php @@ -346,7 +346,9 @@ public function addExpressionFieldToSelect($alias, $expression, $fields) $fullExpression = str_replace('{{' . $fieldKey . '}}', $fieldItem, $fullExpression); } - $this->getSelect()->columns([$alias => $fullExpression]); + $fullExpression = new \Zend_Db_Expr($fullExpression); + $this->_fieldsToSelect[$alias] = $fullExpression; + $this->_fieldsToSelectChanged = true; return $this; } From 3050d2367c284bded10815e7cd559b7bc3937546 Mon Sep 17 00:00:00 2001 From: Magently <hello@magently.com> Date: Tue, 4 Sep 2018 13:53:08 +0200 Subject: [PATCH 1162/1415] Fix integration test Changed test method to fit the new implementation of the class method --- .../ResourceModel/Db/Collection/AbstractCollectionTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php index 4f27f083509d7..7989a265e0db1 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php @@ -267,10 +267,11 @@ public function addFieldToSelectDataProvider() /** * @dataProvider addExpressionFieldToSelectDataProvider */ - public function testAddExpressionFieldToSelect($alias, $expression, $fields, $expected) + public function testAddExpressionFieldToSelect($alias, $expression, $fields, $expectedFieldsToSelect) { - $this->selectMock->expects($this->once())->method('columns')->with($expected); $this->assertTrue($this->uut->addExpressionFieldToSelect($alias, $expression, $fields) instanceof Uut); + $this->assertEquals($expectedFieldsToSelect, $this->uut->getFieldsToSelect()); + $this->assertTrue($this->uut->wereFieldsToSelectChanged()); } /** From 99ea1956fd75f7aeef809c90a3ec45f2cdbbd619 Mon Sep 17 00:00:00 2001 From: Magently <hello@magently.com> Date: Tue, 4 Sep 2018 15:24:11 +0200 Subject: [PATCH 1163/1415] Fix variable name in test class too long --- .../ResourceModel/Db/Collection/AbstractCollectionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php index 7989a265e0db1..0eae94dabbbe8 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php @@ -267,10 +267,10 @@ public function addFieldToSelectDataProvider() /** * @dataProvider addExpressionFieldToSelectDataProvider */ - public function testAddExpressionFieldToSelect($alias, $expression, $fields, $expectedFieldsToSelect) + public function testAddExpressionFieldToSelect($alias, $expression, $fields, $expected) { $this->assertTrue($this->uut->addExpressionFieldToSelect($alias, $expression, $fields) instanceof Uut); - $this->assertEquals($expectedFieldsToSelect, $this->uut->getFieldsToSelect()); + $this->assertEquals($expected, $this->uut->getFieldsToSelect()); $this->assertTrue($this->uut->wereFieldsToSelectChanged()); } From b1bf89323d5bd6a84f45dd3c7788b2c60312b345 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 10:23:41 +0200 Subject: [PATCH 1164/1415] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Gallery/ReadHandler.php | 41 +++------------- .../Model/ResourceModel/Product/Gallery.php | 13 +++-- .../ResourceModel/Product/GalleryTest.php | 48 +++++++++++++++---- app/code/Magento/Catalog/etc/db_schema.xml | 5 ++ .../Catalog/etc/db_schema_whitelist.json | 5 +- .../Model/Product/Type/Configurable.php | 44 +++++++++++++---- .../Product/Type/Configurable.php | 11 +++-- .../Pricing/Renderer/SalableResolver.php | 4 +- .../Plugin/ExternalVideoResourceBackend.php | 40 ++++++++-------- 9 files changed, 127 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php index c785d08e64b7f..4ad275bc70f90 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php @@ -55,9 +55,6 @@ public function __construct( */ public function execute($entity, $arguments = []) { - $value = []; - $value['images'] = []; - $mediaEntries = $this->resourceModel->loadProductGalleryByAttributeId( $entity, $this->getAttribute()->getAttributeId() @@ -79,37 +76,13 @@ public function execute($entity, $arguments = []) */ public function addMediaDataToProduct(Product $product, array $mediaEntries) { - $attrCode = $this->getAttribute()->getAttributeCode(); - $value = []; - $value['images'] = []; - $value['values'] = []; - - foreach ($mediaEntries as $mediaEntry) { - $mediaEntry = $this->substituteNullsWithDefaultValues($mediaEntry); - $value['images'][$mediaEntry['value_id']] = $mediaEntry; - } - $product->setData($attrCode, $value); - } - - /** - * @param array $rawData - * @return array - */ - private function substituteNullsWithDefaultValues(array $rawData) - { - $processedData = []; - foreach ($rawData as $key => $rawValue) { - if (null !== $rawValue) { - $processedValue = $rawValue; - } elseif (isset($rawData[$key . '_default'])) { - $processedValue = $rawData[$key . '_default']; - } else { - $processedValue = null; - } - $processedData[$key] = $processedValue; - } - - return $processedData; + $product->setData( + $this->getAttribute()->getAttributeCode(), + [ + 'images' => array_column($mediaEntries, null, 'value_id'), + 'values' => [] + ] + ); } /** diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php index 2868392f85280..b68c43e40ff2f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php @@ -190,7 +190,7 @@ public function createBatchBaseSelect($storeId, $attributeId) 'value.' . $linkField . ' = entity.' . $linkField, ] ), - ['label', 'position', 'disabled'] + [] )->joinLeft( ['default_value' => $this->getTable(self::GALLERY_VALUE_TABLE)], implode( @@ -201,8 +201,15 @@ public function createBatchBaseSelect($storeId, $attributeId) 'default_value.' . $linkField . ' = entity.' . $linkField, ] ), - ['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled'] - )->where( + [] + )->columns([ + 'label' => $this->getConnection()->getIfNullSql('`value`.`label`', '`default_value`.`label`'), + 'position' => $this->getConnection()->getIfNullSql('`value`.`position`', '`default_value`.`position`'), + 'disabled' => $this->getConnection()->getIfNullSql('`value`.`disabled`', '`default_value`.`disabled`'), + 'label_default' => 'default_value.label', + 'position_default' => 'default_value.position', + 'disabled_default' => 'default_value.disabled' + ])->where( $mainTableAlias . '.attribute_id = ?', $attributeId )->where( diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php index dfed4e4f37385..47ef3c999125f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php @@ -281,6 +281,9 @@ public function testBindValueToEntityRecordExists() $this->resource->bindValueToEntity($valueId, $entityId); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testLoadGallery() { $productId = 5; @@ -329,7 +332,8 @@ public function testLoadGallery() 'main.value_id = entity.value_id', ['entity_id'] )->willReturnSelf(); - $this->product->expects($this->at(0))->method('getData')->with('entity_id')->willReturn($productId); + $this->product->expects($this->at(0))->method('getData') + ->with('entity_id')->willReturn($productId); $this->product->expects($this->at(1))->method('getStoreId')->will($this->returnValue($storeId)); $this->connection->expects($this->exactly(2))->method('quoteInto')->withConsecutive( ['value.store_id = ?'], @@ -338,26 +342,50 @@ public function testLoadGallery() 'value.store_id = ' . $storeId, 'default_value.store_id = ' . 0 ); + $this->connection->expects($this->any())->method('getIfNullSql')->will( + $this->returnValueMap([ + [ + '`value`.`label`', + '`default_value`.`label`', + 'IFNULL(`value`.`label`, `default_value`.`label`)' + ], + [ + '`value`.`position`', + '`default_value`.`position`', + 'IFNULL(`value`.`position`, `default_value`.`position`)' + ], + [ + '`value`.`disabled`', + '`default_value`.`disabled`', + 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)' + ] + ]) + ); $this->select->expects($this->at(2))->method('joinLeft')->with( ['value' => $getTableReturnValue], $quoteInfoReturnValue, - [ - 'label', - 'position', - 'disabled' - ] + [] )->willReturnSelf(); $this->select->expects($this->at(3))->method('joinLeft')->with( ['default_value' => $getTableReturnValue], $quoteDefaultInfoReturnValue, - ['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled'] + [] )->willReturnSelf(); - $this->select->expects($this->at(4))->method('where')->with( + $this->select->expects($this->at(4))->method('columns')->with([ + 'label' => 'IFNULL(`value`.`label`, `default_value`.`label`)', + 'position' => 'IFNULL(`value`.`position`, `default_value`.`position`)', + 'disabled' => 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)', + 'label_default' => 'default_value.label', + 'position_default' => 'default_value.position', + 'disabled_default' => 'default_value.disabled' + ])->willReturnSelf(); + $this->select->expects($this->at(5))->method('where')->with( 'main.attribute_id = ?', $attributeId )->willReturnSelf(); - $this->select->expects($this->at(5))->method('where')->with('main.disabled = 0')->willReturnSelf(); - $this->select->expects($this->at(7))->method('where') + $this->select->expects($this->at(6))->method('where') + ->with('main.disabled = 0')->willReturnSelf(); + $this->select->expects($this->at(8))->method('where') ->with('entity.entity_id = ?', $productId) ->willReturnSelf(); $this->select->expects($this->once())->method('order') diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index a366065c89e76..8dcc623dd64dd 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -835,6 +835,11 @@ <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID" indexType="btree"> + <column name="entity_id"/> + <column name="value_id"/> + <column name="store_id"/> + </index> </table> <table name="catalog_product_option" resource="default" engine="innodb" comment="Catalog Product Option Table"> <column xsi:type="int" name="option_id" padding="10" unsigned="true" nullable="false" identity="true" diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index b1543a6a007f9..31620e4e920f4 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -484,7 +484,8 @@ "index": { "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID": true, - "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true + "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true, + "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID": true }, "constraint": { "PRIMARY": true, @@ -1121,4 +1122,4 @@ "CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 19de63b7a976c..f98075f2294cc 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -453,6 +453,10 @@ public function getConfigurableAttributes($product) ['group' => 'CONFIGURABLE', 'method' => __METHOD__] ); if (!$product->hasData($this->_configurableAttributes)) { + // for new product do not load configurable attributes + if (!$product->getId()) { + return []; + } $configurableAttributes = $this->getConfigurableAttributeCollection($product); $this->extensionAttributesJoinProcessor->process($configurableAttributes); $configurableAttributes->orderByPosition()->load(); @@ -1398,23 +1402,47 @@ private function getConfiguredUsedProductCollection( $skipStockFilter = true ) { $collection = $this->getUsedProductCollection($product); + if ($skipStockFilter) { $collection->setFlag('has_stock_status_filter', true); } + $collection - ->addAttributeToSelect($this->getCatalogConfig()->getProductAttributes()) + ->addAttributeToSelect($this->getAttributesForCollection($product)) ->addFilterByRequiredOptions() ->setStoreId($product->getStoreId()); - $requiredAttributes = ['name', 'price', 'weight', 'image', 'thumbnail', 'status', 'media_gallery']; - foreach ($requiredAttributes as $attributeCode) { - $collection->addAttributeToSelect($attributeCode); - } - foreach ($this->getUsedProductAttributes($product) as $usedProductAttribute) { - $collection->addAttributeToSelect($usedProductAttribute->getAttributeCode()); - } $collection->addMediaGalleryData(); $collection->addTierPriceData(); + return $collection; } + + /** + * @return array + */ + private function getAttributesForCollection(\Magento\Catalog\Model\Product $product) + { + $productAttributes = $this->getCatalogConfig()->getProductAttributes(); + + $requiredAttributes = [ + 'name', + 'price', + 'weight', + 'image', + 'thumbnail', + 'status', + 'visibility', + 'media_gallery' + ]; + + $usedAttributes = array_map( + function($attr) { + return $attr->getAttributeCode(); + }, + $this->getUsedProductAttributes($product) + ); + + return array_unique(array_merge($productAttributes, $requiredAttributes, $usedAttributes)); + } } diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php index ccff85dd9717f..3611d95f0c6ac 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php @@ -173,10 +173,13 @@ public function getChildrenIds($parentId, $required = true) $parentId ); - $childrenIds = [0 => []]; - foreach ($this->getConnection()->fetchAll($select) as $row) { - $childrenIds[0][$row['product_id']] = $row['product_id']; - } + $childrenIds = [ + 0 => array_column( + $this->getConnection()->fetchAll($select), + 'product_id', + 'product_id' + ) + ]; return $childrenIds; } diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php index efddb278df36c..8a7e846c0e9f1 100644 --- a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php +++ b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php @@ -44,9 +44,7 @@ public function afterIsSalable( \Magento\Framework\Pricing\SaleableInterface $salableItem ) { if ($salableItem->getTypeId() == 'configurable' && $result) { - if (!$this->lowestPriceOptionsProvider->getProducts($salableItem)) { - $result = false; - } + $result = $salableItem->isSalable(); } return $result; diff --git a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php index dc64f03a42d19..b27c7c8976b4c 100644 --- a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php +++ b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php @@ -60,19 +60,9 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec 'value.store_id = value_video.store_id', ] ), - [ - 'video_provider' => 'provider', - 'video_url' => 'url', - 'video_title' => 'title', - 'video_description' => 'description', - 'video_metadata' => 'metadata' - ] + [] )->joinLeft( - [ - 'default_value_video' => $originalResourceModel->getTable( - 'catalog_product_entity_media_gallery_value_video' - ) - ], + ['default_value_video' => $originalResourceModel->getTable('catalog_product_entity_media_gallery_value_video')], implode( ' AND ', [ @@ -80,14 +70,24 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec 'default_value.store_id = default_value_video.store_id', ] ), - [ - 'video_provider_default' => 'provider', - 'video_url_default' => 'url', - 'video_title_default' => 'title', - 'video_description_default' => 'description', - 'video_metadata_default' => 'metadata', - ] - ); + [] + )->columns([ + 'video_provider' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`provider`', '`default_value_video`.`provider`'), + 'video_url' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`url`', '`default_value_video`.`url`'), + 'video_title' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`title`', '`default_value_video`.`title`'), + 'video_description' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`description`', '`default_value_video`.`description`'), + 'video_metadata' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`metadata`', '`default_value_video`.`metadata`'), + 'video_provider_default' => 'default_value_video.provider', + 'video_url_default' => 'default_value_video.url', + 'video_title_default' => 'default_value_video.title', + 'video_description_default' => 'default_value_video.description', + 'video_metadata_default' => 'default_value_video.metadata', + ]); return $select; } From 6d6380f272824619cfcfafd8a3fa142e354d311c Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Tue, 13 Nov 2018 10:28:33 +0200 Subject: [PATCH 1165/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - change step on Credit memo page --- ...retateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml index 4feb47ae78e15..fe1ed76e77f70 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -109,6 +109,6 @@ <!--Get access to Credit Memo page from Invocie page--> <click selector="{{AdminInvoiceMainActionsSection.openNewCreditMemoFromInvoice}}" stepKey="clickCreateNewCreditMemo"/> <waitForPageLoad stepKey="waitForLoadNewCreditMemoPage" time="5"/> - <see selector="{{AdminCreditMemoOrderInformationSection.orderId}}" userInput="New Memo" stepKey="seeNewCreditMemo" after="waitForLoadNewCreditMemoPage"/> + <see selector="{{AdminCreditMemoOrderInformationSection.orderId}}" userInput="New Memo for" stepKey="seeNewCreditMemo" after="waitForLoadNewCreditMemoPage"/> </test> </tests> \ No newline at end of file From b1c944b69b3a7504fa3cda663694481debac362a Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 10:44:18 +0200 Subject: [PATCH 1166/1415] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Gallery/ReadHandler.php | 8 ++++++++ .../Model/ResourceModel/Product/Gallery.php | 20 +++++++++++++++++-- .../Product/Type/Configurable.php | 3 +++ .../Pricing/Renderer/SalableResolver.php | 3 +-- .../Plugin/ExternalVideoResourceBackend.php | 10 +++++++++- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php index 4ad275bc70f90..a3726207b3024 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php @@ -47,6 +47,8 @@ public function __construct( } /** + * Execute read handler for catalog product gallery + * * @param Product $entity * @param array $arguments * @return object @@ -69,6 +71,8 @@ public function execute($entity, $arguments = []) } /** + * Add media data to product + * * @param Product $product * @param array $mediaEntries * @return void @@ -86,6 +90,8 @@ public function addMediaDataToProduct(Product $product, array $mediaEntries) } /** + * Get attribute + * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ @@ -99,6 +105,8 @@ public function getAttribute() } /** + * Find default value + * * @param string $key * @param string[] &$image * @return string diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php index b68c43e40ff2f..635715a60742f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php @@ -49,7 +49,8 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ protected function _construct() @@ -58,7 +59,8 @@ protected function _construct() } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ public function getConnection() @@ -67,6 +69,8 @@ public function getConnection() } /** + * Load data from table by valueId + * * @param string $tableNameAlias * @param array $ids * @param int|null $storeId @@ -111,6 +115,8 @@ public function loadDataFromTableByValueId( } /** + * Load product gallery by attributeId + * * @param \Magento\Catalog\Model\Product $product * @param int $attributeId * @return array @@ -132,6 +138,8 @@ public function loadProductGalleryByAttributeId($product, $attributeId) } /** + * Create base load select + * * @param int $entityId * @param int $storeId * @param int $attributeId @@ -151,6 +159,8 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId) } /** + * Create batch base select + * * @param int $storeId * @param int $attributeId * @return \Magento\Framework\DB\Select @@ -247,6 +257,8 @@ protected function removeDuplicates(&$result) } /** + * Get main table alias + * * @return string * @since 101.0.0 */ @@ -256,6 +268,8 @@ public function getMainTableAlias() } /** + * Bind value to entity + * * @param int $valueId * @param int $entityId * @return int @@ -273,6 +287,8 @@ public function bindValueToEntity($valueId, $entityId) } /** + * Save data row + * * @param string $table * @param array $data * @param array $fields diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php index 3611d95f0c6ac..feffd22a0fb3d 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php @@ -19,6 +19,9 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\DB\Adapter\AdapterInterface; +/** + * Configurable product resource model. + */ class Configurable extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { /** diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php index 8a7e846c0e9f1..df8782ae422b4 100644 --- a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php +++ b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php @@ -27,8 +27,7 @@ public function __construct( } /** - * Performs an additional check whether given configurable product has - * at least one configuration in-stock. + * Performs an additional check whether given configurable product has at least one configuration in-stock. * * @param \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver $subject * @param bool $result diff --git a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php index b27c7c8976b4c..04a3d868d14a6 100644 --- a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php +++ b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php @@ -27,6 +27,8 @@ public function __construct(\Magento\ProductVideo\Model\ResourceModel\Video $vid } /** + * Plugin for after duplicate action + * * @param Gallery $originalResourceModel * @param array $valueIdMap * @return array @@ -45,6 +47,8 @@ public function afterDuplicate(Gallery $originalResourceModel, array $valueIdMap } /** + * Plugin for after create batch base select action + * * @param Gallery $originalResourceModel * @param Select $select * @return Select @@ -62,7 +66,11 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec ), [] )->joinLeft( - ['default_value_video' => $originalResourceModel->getTable('catalog_product_entity_media_gallery_value_video')], + [ + 'default_value_video' => $originalResourceModel->getTable( + 'catalog_product_entity_media_gallery_value_video' + ) + ], implode( ' AND ', [ From 4328497e27f38c9317b4a2731b08fbd61243a5ae Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 10:37:02 +0100 Subject: [PATCH 1167/1415] Adjusted API-functional tests for new limits --- .../Framework/QueryComplexityLimiterTest.php | 132 ++++++++++++++++-- 1 file changed, 121 insertions(+), 11 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 3304d9e6198f4..9bf223068e226 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -24,7 +24,7 @@ public function testQueryComplexityIsLimited() $query = <<<QUERY { -category(id: 2) { + category(id: 2) { products { items { name @@ -52,9 +52,15 @@ public function testQueryComplexityIsLimited() new_from_date tier_price manufacturer - thumbnail + thumbnail { + url + label + } sku - image + image { + url + label + } canonical_url updated_at created_at @@ -76,12 +82,18 @@ public function testQueryComplexityIsLimited() special_from_date special_to_date new_to_date - thumbnail + thumbnail { + url + label + } new_from_date tier_price manufacturer sku - image + image { + url + label + } canonical_url updated_at created_at @@ -111,9 +123,15 @@ public function testQueryComplexityIsLimited() new_from_date tier_price manufacturer - thumbnail + thumbnail { + url + label + } sku - image + image { + url + label + } canonical_url updated_at created_at @@ -139,7 +157,10 @@ public function testQueryComplexityIsLimited() tier_price manufacturer sku - image + image { + url + label + } canonical_url updated_at created_at @@ -160,13 +181,101 @@ public function testQueryComplexityIsLimited() name special_from_date special_to_date + price { + minimalPrice { + amount { + value + currency + } + } + maximalPrice { + amount { + value + currency + } + } + regularPrice { + amount { + value + currency + } + } + } + tier_price + special_price + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } new_to_date new_from_date tier_price manufacturer sku - image - thumbnail + image { + url + label + } + thumbnail { + url + label + } canonical_url updated_at created_at @@ -221,9 +330,10 @@ public function testQueryComplexityIsLimited() } } } + QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 160 but got 169/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 250 but got 252/'); $this->graphQlQuery($query); } From 436e3d3a6bf8179220747bef5cbdaeaaab4b730f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 13 Nov 2018 12:58:32 +0300 Subject: [PATCH 1168/1415] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Fix webapi test --- .../Customer/Api/CustomerMetadataTest.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php index f2632aa1481e4..3b1d431342988 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Api\Data\CustomerInterface as Customer; use Magento\Customer\Model\Data\AttributeMetadata; use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\TestFramework\Helper\Bootstrap; /** * Class CustomerMetadataTest @@ -19,6 +20,19 @@ class CustomerMetadataTest extends WebapiAbstract const SERVICE_VERSION = "V1"; const RESOURCE_PATH = "/V1/attributeMetadata/customer"; + /** + * @var CustomerMetadataInterface + */ + private $customerMetadata; + + /** + * Execute per test initialization. + */ + public function setUp() + { + $this->customerMetadata = Bootstrap::getObjectManager()->create(CustomerMetadataInterface::class); + } + /** * Test retrieval of attribute metadata for the customer entity type. * @@ -200,8 +214,7 @@ public function testGetCustomAttributesMetadata() $attributeMetadata = $this->_webApiCall($serviceInfo); - // There are no default custom attributes. - $this->assertCount(0, $attributeMetadata); + $this->assertCount(count($this->customerMetadata->getCustomAttributesMetadata()), $attributeMetadata); } /** From 1050136cd115936306c12176a281114f2dbe4d3a Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 12:10:56 +0200 Subject: [PATCH 1169/1415] Adding integration tests for wrong captcha on login and forgotpassword pages --- ...successfulMessageWhenCaptchaFailedTest.php | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php diff --git a/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php b/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php new file mode 100644 index 0000000000000..cb2a98409bc24 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Captcha\Observer; + +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\Request; +use Magento\TestFramework\TestCase\AbstractController; + +/** + * Test captcha observer behavior + * + * @magentoAppArea frontend + */ +class CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest extends AbstractController +{ + /** + * Test incorrect captcha on customer login page + * + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + * @magentoConfigFixture default_store customer/captcha/enable 1 + * @magentoConfigFixture default_store customer/captcha/forms user_login + * @magentoConfigFixture default_store customer/captcha/mode always + */ + public function testLoginCheckUnsuccessfulMessageWhenCaptchaFailed() + { + /** @var \Magento\Framework\Data\Form\FormKey $formKey */ + $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class); + $post = [ + 'login' => [ + 'username' => 'dummy@dummy.com', + 'password' => 'dummy_password1', + ], + 'captcha' => ['user_login' => 'wrong_captcha'], + 'form_key' => $formKey->getFormKey(), + ]; + + $this->getRequest()->setMethod(Request::METHOD_POST); + $this->getRequest()->setPostValue($post); + + $this->dispatch('customer/account/loginPost'); + + $this->assertRedirect($this->stringContains('customer/account/login')); + $this->assertSessionMessages( + $this->equalTo(['Incorrect CAPTCHA']), + MessageInterface::TYPE_ERROR + ); + } + + /** + * Test incorrect captcha on customer forgot password page + * + * @codingStandardsIgnoreStart + * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0 + * @magentoConfigFixture default_store customer/captcha/enable 1 + * @magentoConfigFixture default_store customer/captcha/forms user_forgotpassword + * @magentoConfigFixture default_store customer/captcha/mode always + */ + public function testForgotPasswordCheckUnsuccessfulMessageWhenCaptchaFailed() + { + $email = 'dummy@dummy.com'; + + $this->getRequest()->setPostValue(['email' => $email]); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + + $this->dispatch('customer/account/forgotPasswordPost'); + + $this->assertRedirect($this->stringContains('customer/account/forgotpassword')); + $this->assertSessionMessages( + $this->equalTo(['Incorrect CAPTCHA']), + MessageInterface::TYPE_ERROR + ); + } +} From 19c1f871b6bb1853ad960edfc3f6c8372c8a3e4f Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 11:40:06 +0100 Subject: [PATCH 1170/1415] API-functional tests coverage --- .../Catalog/CategoryProductsCountTest.php | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php new file mode 100644 index 0000000000000..eddd456a7b866 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Model\Product\Attribute\Source\Status as productStatus; + +/** + * Class CategoryProductsCountTest + * + * Test for Magento\CatalogGraphQl\Model\Resolver\Category\ProductsCount resolver + */ +class CategoryProductsCountTest extends GraphQlAbstract +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $objectManager->create(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testCategoryWithSaleableProduct() + { + $categoryId = 2; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithInvisibleProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php + */ + public function testCategoryWithOutOfStockProductManageStockEnabled() + { + $categoryId = 2; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithOutOfStockProductManageStockDisabled() + { + $categoryId = 333; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithDisabledProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setStatus(ProductStatus::STATUS_DISABLED); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } +} From cbe6a4492e8b3d9ec8d75169c353d67685b99d55 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 12:45:21 +0200 Subject: [PATCH 1171/1415] Adding integration tests for wrong captcha on customer create page --- ...successfulMessageWhenCaptchaFailedTest.php | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php b/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php index cb2a98409bc24..8355d81fdf5d9 100644 --- a/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php +++ b/dev/tests/integration/testsuite/Magento/Captcha/Observer/CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Captcha\Observer; -use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Message\MessageInterface; use Magento\TestFramework\Request; use Magento\TestFramework\TestCase\AbstractController; @@ -28,8 +28,8 @@ class CaseCheckOnFrontendUnsuccessfulMessageWhenCaptchaFailedTest extends Abstra */ public function testLoginCheckUnsuccessfulMessageWhenCaptchaFailed() { - /** @var \Magento\Framework\Data\Form\FormKey $formKey */ - $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class); + /** @var FormKey $formKey */ + $formKey = $this->_objectManager->get(FormKey::class); $post = [ 'login' => [ 'username' => 'dummy@dummy.com', @@ -39,8 +39,7 @@ public function testLoginCheckUnsuccessfulMessageWhenCaptchaFailed() 'form_key' => $formKey->getFormKey(), ]; - $this->getRequest()->setMethod(Request::METHOD_POST); - $this->getRequest()->setPostValue($post); + $this->prepareRequestData($post); $this->dispatch('customer/account/loginPost'); @@ -62,10 +61,8 @@ public function testLoginCheckUnsuccessfulMessageWhenCaptchaFailed() */ public function testForgotPasswordCheckUnsuccessfulMessageWhenCaptchaFailed() { - $email = 'dummy@dummy.com'; - - $this->getRequest()->setPostValue(['email' => $email]); - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $post = ['email' => 'dummy@dummy.com']; + $this->prepareRequestData($post); $this->dispatch('customer/account/forgotPasswordPost'); @@ -75,4 +72,47 @@ public function testForgotPasswordCheckUnsuccessfulMessageWhenCaptchaFailed() MessageInterface::TYPE_ERROR ); } + + /** + * Test incorrect captcha on customer create account page + * + * @codingStandardsIgnoreStart + * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0 + * @magentoConfigFixture default_store customer/captcha/enable 1 + * @magentoConfigFixture default_store customer/captcha/forms user_create + * @magentoConfigFixture default_store customer/captcha/mode always + */ + public function testCreateAccountCheckUnsuccessfulMessageWhenCaptchaFailed() + { + /** @var FormKey $formKey */ + $formKey = $this->_objectManager->get(FormKey::class); + $post = [ + 'firstname' => 'Firstname', + 'lastname' => 'Lastname', + 'email' => 'dummy@dummy.com', + 'password' => 'TestPassword123', + 'password_confirmation' => 'TestPassword123', + 'captcha' => ['user_create' => 'wrong_captcha'], + 'form_key' => $formKey->getFormKey(), + ]; + $this->prepareRequestData($post); + + $this->dispatch('customer/account/createPost'); + + $this->assertRedirect($this->stringContains('customer/account/create')); + $this->assertSessionMessages( + $this->equalTo(['Incorrect CAPTCHA']), + MessageInterface::TYPE_ERROR + ); + } + + /** + * @param array $postData + * @return void + */ + private function prepareRequestData($postData) + { + $this->getRequest()->setMethod(Request::METHOD_POST); + $this->getRequest()->setPostValue($postData); + } } From c683dde7e44b30c81f55593c9275eb1f31dc7cb1 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:09:09 +0200 Subject: [PATCH 1172/1415] MAGETWO-96118: Few optimizations on category & product pages --- app/code/Magento/Catalog/etc/db_schema.xml | 2 +- app/code/Magento/Catalog/etc/db_schema_whitelist.json | 2 +- .../Model/Product/Type/ConfigurableTest.php | 9 +++++++-- .../Framework/Interception/PluginList/PluginList.php | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 8dcc623dd64dd..17e3dddc41c3b 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -835,7 +835,7 @@ <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> - <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID" indexType="btree"> + <index referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_VAL_ID_STORE_ID" indexType="btree"> <column name="entity_id"/> <column name="value_id"/> <column name="store_id"/> diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index 31620e4e920f4..d4bd6927d4345 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -485,7 +485,7 @@ "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true, - "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID": true + "CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_VAL_ID_STORE_ID": true }, "constraint": { "PRIMARY": true, diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index bdb36b93af21c..78fa4733a2562 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +// @codingStandardsIgnoreFile + namespace Magento\ConfigurableProduct\Model\Product\Type; use Magento\Catalog\Api\Data\ProductInterface; @@ -128,6 +130,10 @@ public function testGetUsedProductAttributes() $this->assertEquals($testConfigurable->getData(), $attributes[$attributeId]->getData()); } + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ public function testGetConfigurableAttributes() { $collection = $this->model->getConfigurableAttributes($this->product); @@ -332,8 +338,7 @@ public function testGetSelectedAttributesInfo() $attribute = reset($attributes); $optionValueId = $attribute['values'][0]['value_index']; - $product->addCustomOption( - 'attributes', + $product->addCustomOption('attributes', $serializer->serialize([$attribute['attribute_id'] => $optionValueId]) ); diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index e21841b48bc13..d20cd57f4e43f 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -264,7 +264,7 @@ public function getPlugin($type, $code) public function getNext($type, $method, $code = '__self') { $this->_loadScopedData(); - if (!isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { + if ($this->_inherited !== null && !isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { $this->_inheritPlugins($type); } $key = $type . '_' . lcfirst($method) . '_' . $code; From f4a0e6a6e0f484c6a5d4c469fdd84f027aa4aac8 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 13 Nov 2018 14:29:42 +0300 Subject: [PATCH 1173/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Fixed static test; --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index 7578774fabc2c..848c6a76393f8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -22,7 +22,7 @@ $allowedQty = $block->getMinMaxQty(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" + <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= /* @noEscape */ $allowedQty['minAllowed'] ?>,'maxAllowed':<?= /* @noEscape */ $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From c4b394a43f6e2690c3706eb5c5768a69185584d5 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:56:45 +0200 Subject: [PATCH 1174/1415] MAGETWO-96118: Few optimizations on category & product pages --- .../Magento/Framework/Interception/PluginList/PluginList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index d20cd57f4e43f..e21841b48bc13 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -264,7 +264,7 @@ public function getPlugin($type, $code) public function getNext($type, $method, $code = '__self') { $this->_loadScopedData(); - if ($this->_inherited !== null && !isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { + if (!isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { $this->_inheritPlugins($type); } $key = $type . '_' . lcfirst($method) . '_' . $code; From 91157807e4e9bbb055b61d0f949535a816c172b6 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:59:36 +0200 Subject: [PATCH 1175/1415] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Type/ConfigurableTest.php | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php index 5e9399ddd3d65..d1cf77f03a7bd 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php @@ -27,6 +27,7 @@ * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) + * @codingStandardsIgnoreFile */ class ConfigurableTest extends \PHPUnit\Framework\TestCase { @@ -154,8 +155,7 @@ protected function setUp() ->setMethods(['create']) ->getMock(); $this->productCollectionFactory = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory::class - ) + \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); @@ -197,11 +197,6 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->productFactory = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterfaceFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->salableProcessor = $this->createMock(SalableProcessor::class); $this->model = $this->objectHelper->getObject( @@ -287,8 +282,7 @@ public function testSave() ->method('getData') ->willReturnMap($dataMap); $attribute = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->setMethods(['addData', 'setStoreId', 'setProductId', 'save', '__wakeup', '__sleep']) ->getMock(); @@ -385,7 +379,7 @@ public function testGetUsedProducts() ['_cache_instance_used_product_attributes', null, []] ] ); - + $this->catalogConfig->expects($this->any())->method('getProductAttributes')->willReturn([]); $productCollection->expects($this->atLeastOnce())->method('addAttributeToSelect')->willReturnSelf(); $productCollection->expects($this->once())->method('setProductFilter')->willReturnSelf(); $productCollection->expects($this->atLeastOnce())->method('setFlag')->willReturnSelf(); @@ -471,8 +465,7 @@ public function testGetConfigurableAttributesAsArray($productStore) $eavAttribute->expects($this->atLeastOnce())->method('getStoreLabel')->willReturn('Store Label'); $attribute = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->setMethods(['getProductAttribute', '__wakeup', '__sleep']) ->getMock(); @@ -515,17 +508,34 @@ public function getConfigurableAttributesAsArrayDataProvider() ]; } - public function testGetConfigurableAttributes() + public function testGetConfigurableAttributesNewProduct() { $configurableAttributes = '_cache_instance_configurable_attributes'; /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->setMethods(['getData', 'hasData', 'setData']) + ->setMethods(['hasData', 'getId']) ->disableOriginalConstructor() ->getMock(); $product->expects($this->once())->method('hasData')->with($configurableAttributes)->willReturn(false); + $product->expects($this->once())->method('getId')->willReturn(null); + + $this->assertEquals([], $this->model->getConfigurableAttributes($product)); + } + + public function testGetConfigurableAttributes() + { + $configurableAttributes = '_cache_instance_configurable_attributes'; + + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->setMethods(['getData', 'hasData', 'setData', 'getId']) + ->disableOriginalConstructor() + ->getMock(); + + $product->expects($this->once())->method('hasData')->with($configurableAttributes)->willReturn(false); + $product->expects($this->once())->method('getId')->willReturn(1); $attributeCollection = $this->getMockBuilder(Collection::class) ->setMethods(['setProductFilter', 'orderByPosition', 'load']) @@ -582,8 +592,7 @@ public function testHasOptionsConfigurableAttribute() ->disableOriginalConstructor() ->getMock(); $attributeMock = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->getMock(); From cbd6203d6505c5e366928dea5249b926a6a8bbb3 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 14:27:31 +0200 Subject: [PATCH 1176/1415] GraphQl-222: Apply changes from CR for PR 162 Fix static tests --- .../GraphQl/Exception/GraphQlAuthorizationException.php | 4 ++-- .../Framework/GraphQl/Exception/GraphQlInputException.php | 4 ++-- .../GraphQl/Exception/GraphQlNoSuchEntityException.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php index f71652edc63b3..f1232ebd4d14b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php index 6f97f06261358..429b7c04b7475 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php index 4bd24d6cfd4a7..2a0b9d3bc2eaa 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { From 6062a1eae3d1ced249379daf4c77de711410b349 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 14:34:53 +0200 Subject: [PATCH 1177/1415] GraphQl: Missed PHPDoc argument headers in method graphQlQuery --- .../Magento/TestFramework/TestCase/GraphQlAbstract.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 9754a340900e2..790581c476da1 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -52,11 +52,14 @@ public function graphQlQuery( } /** + * Compose headers + * + * @param array $headers * @return string[] */ - private function composeHeaders($headers) + private function composeHeaders(array $headers): array { - $headersArray =[]; + $headersArray = []; foreach ($headers as $key => $value) { $headersArray[] = sprintf('%s: %s', $key, $value); } From 74fce4acb449bb2f3b31e4e93d876654c5f0f0ea Mon Sep 17 00:00:00 2001 From: Vlad Veselov <vlad.veselov@gmail.com> Date: Tue, 13 Nov 2018 14:50:30 +0200 Subject: [PATCH 1178/1415] Fix PHP Notice due to magento/magento2#18727 --- pub/index.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pub/index.php b/pub/index.php index 90b4778265447..d363951691d58 100644 --- a/pub/index.php +++ b/pub/index.php @@ -25,15 +25,14 @@ } $params = $_SERVER; -$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( - $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], - [ +$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = + ($params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? []) + + [ DirectoryList::PUB => [DirectoryList::URL_PATH => ''], DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], - ] -); + ]; $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params); /** @var \Magento\Framework\App\Http $app */ $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); From 1378ed33cad3ab8fb4d121b700bfe53d8733c408 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:11:50 +0200 Subject: [PATCH 1179/1415] GraphQl-11: Alphabetize Schema Fields -- Fix static tests --- .../Magento/Framework/GraphQl/Config/GraphQlReaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php index 3d3372429123a..7f8996daa6e97 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -194,7 +194,7 @@ enumValues(includeDeprecated: true) { $sortFields = ['inputFields', 'fields']; foreach ($sortFields as $sortField) { isset($searchTerm[$sortField]) && is_array($searchTerm[$sortField]) - ? usort($searchTerm[$sortField], function($a, $b) { + ? usort($searchTerm[$sortField], function ($a, $b) { $cmpField = 'name'; return isset($a[$cmpField]) && isset($b[$cmpField]) ? strcmp($a[$cmpField], $b[$cmpField]) : 0; From 7f61b6f9d20565d0338cd1f0a39afde7b9edaabd Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:39:59 +0200 Subject: [PATCH 1180/1415] GraphQl-222: Apply changes from CR for PR 162 - Fix API-functional tests --- .../GraphQl/Customer/AccountInformationTest.php | 2 +- .../GraphQl/Customer/RevokeCustomerTokenTest.php | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php index 2caee84ba6f00..942e321a78718 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php @@ -238,7 +238,7 @@ public function testUpdateAccountInformationIfCustomerIsLocked() /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @expectedException \Exception - * @expectedExceptionMessage For changing "email" you should provide current "password". + * @expectedExceptionMessage Provide the current "password" to change "email". */ public function testUpdateEmailIfPasswordIsMissed() { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php index 415a81f8cf45a..9bdbf3059eeaf 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php @@ -23,7 +23,9 @@ public function testRevokeCustomerTokenValidCredentials() { $query = <<<QUERY mutation { - revokeCustomerToken + revokeCustomerToken { + result + } } QUERY; @@ -35,7 +37,7 @@ public function testRevokeCustomerTokenValidCredentials() $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; $response = $this->graphQlQuery($query, [], '', $headerMap); - $this->assertTrue($response['revokeCustomerToken']); + $this->assertTrue($response['revokeCustomerToken']['result']); } /** @@ -46,7 +48,9 @@ public function testRevokeCustomerTokenForGuestCustomer() { $query = <<<QUERY mutation { - revokeCustomerToken + revokeCustomerToken { + result + } } QUERY; $this->graphQlQuery($query, [], ''); From ee582ece43fada77f434f14c542e508ba5e7e68a Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Tue, 13 Nov 2018 15:53:41 +0200 Subject: [PATCH 1181/1415] MAGETWO-96291: Cannot proceed to Braintree PayPal from iPhone - Fixed `Place Order` action to prevent pop-up blocking --- .../js/view/payment/method-renderer/paypal.js | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js index abf434bc6da26..eaebd8492b0a1 100644 --- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js +++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js @@ -7,7 +7,6 @@ define([ 'jquery', 'underscore', - 'mage/utils/wrapper', 'Magento_Checkout/js/view/payment/default', 'Magento_Braintree/js/view/payment/adapter', 'Magento_Checkout/js/model/quote', @@ -19,7 +18,6 @@ define([ ], function ( $, _, - wrapper, Component, Braintree, quote, @@ -105,6 +103,12 @@ define([ } }); + quote.shippingAddress.subscribe(function () { + if (self.isActive()) { + self.reInitPayPal(); + } + }); + // for each component initialization need update property this.isReviewRequired(false); this.initClientConfig(); @@ -222,9 +226,8 @@ define([ /** * Re-init PayPal Auth Flow - * @param {Function} callback - Optional callback */ - reInitPayPal: function (callback) { + reInitPayPal: function () { if (Braintree.checkout) { Braintree.checkout.teardown(function () { Braintree.checkout = null; @@ -235,17 +238,6 @@ define([ this.clientConfig.paypal.amount = this.grandTotalAmount; this.clientConfig.paypal.shippingAddressOverride = this.getShippingAddress(); - if (callback) { - this.clientConfig.onReady = wrapper.wrap( - this.clientConfig.onReady, - function (original, checkout) { - this.clientConfig.onReady = original; - original(checkout); - callback(); - }.bind(this) - ); - } - Braintree.setConfig(this.clientConfig); Braintree.setup(); }, @@ -428,19 +420,17 @@ define([ * Triggers when customer click "Continue to PayPal" button */ payWithPayPal: function () { - this.reInitPayPal(function () { - if (!additionalValidators.validate()) { - return; - } + if (!additionalValidators.validate()) { + return; + } - try { - Braintree.checkout.paypal.initAuthFlow(); - } catch (e) { - this.messageContainer.addErrorMessage({ - message: $t('Payment ' + this.getTitle() + ' can\'t be initialized.') - }); - } - }.bind(this)); + try { + Braintree.checkout.paypal.initAuthFlow(); + } catch (e) { + this.messageContainer.addErrorMessage({ + message: $t('Payment ' + this.getTitle() + ' can\'t be initialized.') + }); + } }, /** From 7dba16ba0d61af22b241d58d99f026d0a140222f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:55:47 +0200 Subject: [PATCH 1182/1415] GraphQl-39: Manage Shipping methods on Cart --- .../Address/AddressDataProvider.php | 2 +- .../{CartAddress.php => CartAddresses.php} | 24 ++----------------- .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 4 insertions(+), 24 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver => Cart}/Address/AddressDataProvider.php (98%) rename app/code/Magento/QuoteGraphQl/Model/Resolver/{CartAddress.php => CartAddresses.php} (59%) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php similarity index 98% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php index 80fe973c4e449..fb742477ec99b 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\Address; +namespace Magento\QuoteGraphQl\Model\Cart\Address; use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Quote\Api\Data\AddressInterface; diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php similarity index 59% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php rename to app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php index 54bd8fa2a5717..69544672bf12e 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php @@ -11,14 +11,12 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Model\MaskedQuoteIdToQuoteId; -use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; +use Magento\QuoteGraphQl\Model\Cart\Address\AddressDataProvider; /** * @inheritdoc */ -class CartAddress implements ResolverInterface +class CartAddresses implements ResolverInterface { /** * @var AddressDataProvider @@ -26,29 +24,11 @@ class CartAddress implements ResolverInterface private $addressDataProvider; /** - * @var CartRepositoryInterface - */ - private $cartRepository; - - /** - * @var MaskedQuoteIdToQuoteId - */ - private $maskedQuoteIdToQuoteId; - - /** - * CartAddress constructor. - * - * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId - * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider */ public function __construct( - MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, - CartRepositoryInterface $cartRepository, AddressDataProvider $addressDataProvider ) { - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index ce982952f1aee..a6c56318d7a9a 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -95,7 +95,7 @@ type Cart { cart_id: String items: [CartItemInterface] applied_coupon: AppliedCoupon - addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddress") + addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddresses") } type CartAddress { From 4a8720485da929caa4301fdac430f91a3628d42d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 16:18:08 +0200 Subject: [PATCH 1183/1415] GraphQl-39: Manage Shipping methods on Cart - Fix static tests --- .../Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php index 7f945dca2fd76..a630b2d07c7df 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php @@ -98,4 +98,4 @@ public function execute(Quote $cart, int $cartAddressId, string $carrierCode, st throw new GraphQlInputException(__($exception->getMessage())); } } -} \ No newline at end of file +} From 889824ea3bedd2295678d4bd631473a82105ae68 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 15:31:05 +0100 Subject: [PATCH 1184/1415] Increased allowed query complexity to 300 --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/QueryComplexityLimiterTest.php | 63 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 914dcc78e49e1..b2083ea758e56 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,7 +100,7 @@ <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> <argument name="queryDepth" xsi:type="number">20</argument> - <argument name="queryComplexity" xsi:type="number">250</argument> + <argument name="queryComplexity" xsi:type="number">300</argument> </arguments> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 9bf223068e226..352947714360a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -263,6 +263,66 @@ public function testQueryComplexityIsLimited() percentage_value website_id } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } new_to_date new_from_date tier_price @@ -330,10 +390,9 @@ public function testQueryComplexityIsLimited() } } } - QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 250 but got 252/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 300 but got 302/'); $this->graphQlQuery($query); } From d84929a4241776521322ba3fc9521544639bd59c Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 13 Nov 2018 17:10:23 +0200 Subject: [PATCH 1185/1415] Fixed code style issue --- .../Test/Unit/Observer/CheckUserLoginBackendObserverTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index 2d0a2a7e1c99a..415f022a7364d 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -107,7 +107,6 @@ public function requiredCaptchaDataProvider(): array ]; } - /** * Test check user login in backend with wrong captcha * From 770e0f84c8ef2965f71b732bd2d38c529a4ff442 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 13 Nov 2018 18:23:00 +0300 Subject: [PATCH 1186/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Fexed DOC section for add-to-wishlist.js file; --- .../Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index db5f77348b2c0..8a20d2925849a 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -188,7 +188,7 @@ define([ /** * Bind form submit. * - @param {boolean} isFileUploaded + * @param {boolean} isFileUploaded */ bindFormSubmit: function (isFileUploaded) { var self = this; From 9c9581306d7c92751f643101e482ab4e9e4a02fd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 16:40:54 +0100 Subject: [PATCH 1187/1415] Fixed travis test running condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 78b088c9d848d..bd2b94865cafd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,6 +64,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "graphql-api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi - if [ $TEST_SUITE == "graphql-api-functional" ]; then phpunit -c dev/tests/api-functional; fi From 1b21f6fd18a1ef3afe9f8a17949131b5b606b5eb Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Tue, 13 Nov 2018 18:08:30 +0200 Subject: [PATCH 1188/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - change test according to specific of B2B elements --- ...thOnlinePaymentIncludingTaxAndDiscount.xml | 24 ++++++++++++++----- .../AdminCreateCartPriceRuleActionGroup.xml | 18 -------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml index fe1ed76e77f70..d1d685effd133 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscount.xml @@ -70,8 +70,21 @@ <actionGroup ref="logout" stepKey="logout"/> </after> - <!-- Create a cart price rule for Fixed amount discount for whole cart --> - <actionGroup ref="AdminCreateCartPriceRuleForRetailerActionGroup" stepKey="createCartPriceRule"/> + <!-- Create a cart price rule with 10% discount for whole cart --> + <click selector="{{AdminMenuSection.marketing}}" stepKey="clickOnMarketing" /> + <waitForPageLoad stepKey="waitForMarketing" time="3"/> + <click selector="{{CartPriceRulesSubmenuSection.cartPriceRules}}" stepKey="clickOnCartPriceRules"/> + <waitForPageLoad stepKey="waitForCartPriceRules" time="3"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectRetailerCustomerGroup" stepKey="selectRetailerCustomerGroup"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <waitForPageLoad stepKey="waitForCartRuleLoad" time="3"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> <!--Set Taxable Goods for Shipping Tax Class--> <actionGroup ref="changeShippingTaxClass" stepKey="changeShippingTaxClass"/> @@ -100,15 +113,14 @@ <!--Submit Order--> <click stepKey="submitOrder" selector="{{NewOrderSection.submitOrder}}"/> <waitForPageLoad stepKey="waitForSubmitOrder" time="5"/> - <see selector="{{NewOrderSection.successMessage}}" userInput="You created the order." stepKey="seeNewOrder" after="waitForSubmitOrder"/> - + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeOrderSuccessMessage" after="waitForSubmitOrder"/> <!-- Create New invoice--> <actionGroup ref="adminFastCreateInvoice" stepKey="createInvoice"/> - <!--Get access to Credit Memo page from Invocie page--> + <!--Get access to Credit Memo page from Invoice page--> <click selector="{{AdminInvoiceMainActionsSection.openNewCreditMemoFromInvoice}}" stepKey="clickCreateNewCreditMemo"/> <waitForPageLoad stepKey="waitForLoadNewCreditMemoPage" time="5"/> - <see selector="{{AdminCreditMemoOrderInformationSection.orderId}}" userInput="New Memo for" stepKey="seeNewCreditMemo" after="waitForLoadNewCreditMemoPage"/> + <see selector="{{AdminCreditMemoOrderInformationSection.orderStatus}}" userInput="Processing" stepKey="seeNewCreditMemo"/> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index 6a837577ece3d..6ee7b556beb7d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -24,24 +24,6 @@ <see selector="{{AdminCartPriceRulesFormSection.successMessage}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> </actionGroup> - <!--Create Cart price Rule for Retailer customer--> - <actionGroup name="AdminCreateCartPriceRuleForRetailerActionGroup"> - <click selector="{{AdminMenuSection.marketing}}" stepKey="clickOnMarketing" /> - <waitForPageLoad stepKey="waitForMarketing" time="3"/> - <click selector="{{CartPriceRulesSubmenuSection.cartPriceRules}}" stepKey="clickOnCartPriceRules"/> - <waitForPageLoad stepKey="waitForCartPriceRules" time="5"/> - <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> - <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectCustomerGroup"/> - <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> - <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> - <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> - <waitForPageLoad stepKey="waitForCartRuleLoad" time="5"/> - <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> - </actionGroup> - <!--Delete Cart price Rule for Retailer customer--> <actionGroup name="AdminDeleteCartPriceRuleForRetailerActionGroup"> <click selector="{{AdminMenuSection.marketing}}" stepKey="clickOnMarketing" /> From 702353a0f32bc0b5d7cca708c90ec1839c983a8e Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 13 Nov 2018 10:12:17 -0600 Subject: [PATCH 1189/1415] MAGETWO-95589: [FT][Temando] Tests fail with enabled Temando extension --- .../Test/Mftf/Section/CheckoutShippingMethodsSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml index 56ed42fbfbbea..ab4b59fd67d03 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml @@ -13,6 +13,7 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="shippingMethodRow" type="text" selector=".form.methods-shipping table tbody tr"/> <element name="checkShippingMethodByName" type="radio" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/..//input" parameterized="true"/> + <element name="shippingMethodFlatRate" type="radio" selector="#checkout-shipping-method-load input[value='flatrate_flatrate']"/> <element name="shippingMethodRowByName" type="text" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/.." parameterized="true"/> <element name="shipHereButton" type="button" selector="//div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> <element name="shippingMethodLoader" type="button" selector="//div[contains(@class, 'checkout-shipping-method')]/following-sibling::div[contains(@class, 'loading-mask')]"/> From 534da46ce569e8fd4c079bc5978c1959cb45f06c Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Tue, 13 Nov 2018 18:18:29 +0200 Subject: [PATCH 1190/1415] Travis integration tests timeout fix --- dev/travis/before_script.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index dbd9d1cd4fec1..20bc59d718f13 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -13,9 +13,9 @@ case $TEST_SUITE in test_set_list=$(find testsuite/* -maxdepth 1 -mindepth 1 -type d | sort) test_set_count=$(printf "$test_set_list" | wc -l) - test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.17" | bc)) #17% - test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.27" | bc)) #27% - test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #56% + test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.13" | bc)) #13% + test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.30" | bc)) #30% + test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #55% echo "Total = ${test_set_count}; Batch #1 = ${test_set_size[1]}; Batch #2 = ${test_set_size[2]}; Batch #3 = ${test_set_size[3]};"; echo "==> preparing integration testsuite on index $INTEGRATION_INDEX with set size of ${test_set_size[$INTEGRATION_INDEX]}" From afd128e53d475092d8fbdf0c2a65d9654fbef9a6 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 13 Nov 2018 18:27:09 +0200 Subject: [PATCH 1191/1415] graphQl: removed redundant multishipping references --- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index e7417d657a0ea..86bc954ae4ac4 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -8,21 +8,4 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart" /> - <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> - <arguments> - <argument name="specifications" xsi:type="array"> - <item name="enabled" xsi:type="string">Magento\Multishipping\Model\Payment\Method\Specification\Enabled</item> - </argument> - </arguments> - </virtualType> - <type name="Magento\Multishipping\Block\Checkout\Billing"> - <arguments> - <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> - </arguments> - </type> - <type name="Magento\Multishipping\Model\Checkout\Type\Multishipping"> - <arguments> - <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> - </arguments> - </type> </config> From c9b52500a52067b8ccfc3329b7456512b6520526 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 18:37:09 +0200 Subject: [PATCH 1192/1415] Fixing the customer subscribing from different stores --- .../Model/Plugin/CustomerPlugin.php | 18 ++++++++++--- .../Unit/Model/Plugin/CustomerPluginTest.php | 25 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index 22b31575debbc..f7467ef07aadb 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -6,11 +6,13 @@ namespace Magento\Newsletter\Model\Plugin; use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository; +use Magento\Customer\Api\Data\CustomerExtensionInterface; use Magento\Customer\Api\Data\CustomerInterface; -use Magento\Newsletter\Model\SubscriberFactory; use Magento\Framework\Api\ExtensionAttributesFactory; +use Magento\Framework\App\ObjectManager; use Magento\Newsletter\Model\ResourceModel\Subscriber; -use Magento\Customer\Api\Data\CustomerExtensionInterface; +use Magento\Newsletter\Model\SubscriberFactory; +use Magento\Store\Model\StoreManagerInterface; class CustomerPlugin { @@ -36,21 +38,29 @@ class CustomerPlugin */ private $customerSubscriptionStatus = []; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * Initialize dependencies. * * @param SubscriberFactory $subscriberFactory * @param ExtensionAttributesFactory $extensionFactory * @param Subscriber $subscriberResource + * @param StoreManagerInterface|null $storeManager */ public function __construct( SubscriberFactory $subscriberFactory, ExtensionAttributesFactory $extensionFactory, - Subscriber $subscriberResource + Subscriber $subscriberResource, + StoreManagerInterface $storeManager = null ) { $this->subscriberFactory = $subscriberFactory; $this->extensionFactory = $extensionFactory; $this->subscriberResource = $subscriberResource; + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); } /** @@ -155,6 +165,8 @@ public function afterGetById(CustomerRepository $subject, CustomerInterface $cus if ($extensionAttributes === null) { /** @var CustomerExtensionInterface $extensionAttributes */ $extensionAttributes = $this->extensionFactory->create(CustomerInterface::class); + $storeId = $this->storeManager->getStore()->getId(); + $customer->setStoreId($storeId); $customer->setExtensionAttributes($extensionAttributes); } if ($extensionAttributes->getIsSubscribed() === null) { diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php index e809b7e37a432..3be28cacc93e0 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php @@ -10,6 +10,8 @@ use Magento\Customer\Api\Data\CustomerExtensionInterface; use Magento\Framework\Api\ExtensionAttributesFactory; use Magento\Newsletter\Model\ResourceModel\Subscriber; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; class CustomerPluginTest extends \PHPUnit\Framework\TestCase { @@ -53,6 +55,11 @@ class CustomerPluginTest extends \PHPUnit\Framework\TestCase */ private $customerMock; + /** + * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + protected function setUp() { $this->subscriberFactory = $this->getMockBuilder(\Magento\Newsletter\Model\SubscriberFactory::class) @@ -87,6 +94,8 @@ protected function setUp() ->setMethods(['getExtensionAttributes']) ->disableOriginalConstructor() ->getMockForAbstractClass(); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + $this->subscriberFactory->expects($this->any())->method('create')->willReturn($this->subscriber); $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -96,6 +105,7 @@ protected function setUp() 'subscriberFactory' => $this->subscriberFactory, 'extensionFactory' => $this->extensionFactoryMock, 'subscriberResource' => $this->subscriberResourceMock, + 'storeManager' => $this->storeManagerMock, ] ); } @@ -206,6 +216,7 @@ public function testAfterGetByIdCreatesExtensionAttributesIfItIsNotSet( ) { $subject = $this->createMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $subscriber = [$subscriberStatusKey => $subscriberStatusValue]; + $this->prepareStoreData(); $this->extensionFactoryMock->expects($this->any()) ->method('create') @@ -233,6 +244,7 @@ public function testAfterGetByIdSetsIsSubscribedFlagIfItIsNotSet() { $subject = $this->createMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $subscriber = ['subscriber_id' => 1, 'subscriber_status' => 1]; + $this->prepareStoreData(); $this->customerMock->expects($this->any()) ->method('getExtensionAttributes') @@ -267,4 +279,17 @@ public function afterGetByIdDataProvider() [null, null, false], ]; } + + /** + * Prepare store information + * + * @return void + */ + private function prepareStoreData() + { + $storeId = 1; + $storeMock = $this->createMock(Store::class); + $storeMock->expects($this->any())->method('getId')->willReturn($storeId); + $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock); + } } From 54139e30a538312077526f44052abe85b3b17c49 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 12 Nov 2018 16:43:02 -0600 Subject: [PATCH 1193/1415] MAGETWO-96262: Order with simple product after partial cancellation and credit memo has status 'Processing' --- app/code/Magento/Sales/Model/Order.php | 7 +- app/code/Magento/Sales/Model/Order/Item.php | 2 +- .../ActionGroup/AdminOrderActionGroup.xml | 18 -- ...inAbleToShipPartiallyInvoicedItemsTest.xml | 168 ------------------ .../Sales/Test/Unit/Model/Order/ItemTest.php | 8 +- .../Sales/Test/Unit/Model/OrderTest.php | 165 ----------------- .../Section/AdminShipmentItemsSection.xml | 1 - .../Service/V1/CreditMemoCreateRefundTest.php | 3 +- .../Sales/Service/V1/RefundOrderTest.php | 5 +- .../Test/TestCase/MassOrdersUpdateTest.xml | 2 +- .../Magento/Paypal/Model/IpnTest.php | 6 +- 11 files changed, 12 insertions(+), 373 deletions(-) delete mode 100644 app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index ca8063aa57884..6fed435773eaa 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -547,12 +547,7 @@ public function canCancel() } } - $allRefunded = true; - foreach ($this->getAllItems() as $orderItem) { - $allRefunded = $allRefunded && ((float)$orderItem->getQtyRefunded() == (float)$orderItem->getQtyInvoiced()); - } - - if ($allInvoiced && !$allRefunded) { + if ($allInvoiced) { return false; } diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php index cc8bb7aae780c..4bd856e85433d 100644 --- a/app/code/Magento/Sales/Model/Order/Item.php +++ b/app/code/Magento/Sales/Model/Order/Item.php @@ -232,7 +232,7 @@ public function getQtyToShip() */ public function getSimpleQtyToShip() { - $qty = $this->getQtyOrdered() - $this->getQtyShipped() - $this->getQtyCanceled(); + $qty = $this->getQtyOrdered() - $this->getQtyShipped() - $this->getQtyRefunded() - $this->getQtyCanceled(); return max(round($qty, 8), 0); } diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index a26fd6bc1c3a7..c82623632d782 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -94,24 +94,6 @@ <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickAddSelectedProducts"/> </actionGroup> - <!--Add a simple product to order with user defined quantity--> - <actionGroup name="addSimpleProductToOrderWithCustomQuantity"> - <arguments> - <argument name="product" defaultValue="_defaultProduct"/> - <argument name="quantity" type="string"/> - </arguments> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMastToDisappear"/> - <waitForElementVisible selector="{{AdminOrderFormItemsSection.addProducts}}" stepKey="waitForAddProductButton"/> - <click selector="{{AdminOrderFormItemsSection.addProducts}}" stepKey="clickAddProducts"/> - <fillField selector="{{AdminOrderFormItemsSection.skuFilter}}" userInput="{{product.sku}}" stepKey="fillSkuFilter"/> - <click selector="{{AdminOrderFormItemsSection.search}}" stepKey="clickSearch"/> - <scrollTo selector="{{AdminOrderFormItemsSection.rowCheck('1')}}" x="0" y="-100" stepKey="scrollToCheckColumn"/> - <checkOption selector="{{AdminOrderFormItemsSection.rowCheck('1')}}" stepKey="selectProduct"/> - <fillField selector="{{AdminOrderFormItemsSection.rowQty('1')}}" userInput="{{quantity}}" stepKey="fillProductQty"/> - <scrollTo selector="{{AdminOrderFormItemsSection.addSelected}}" x="0" y="-100" stepKey="scrollToAddSelectedButton"/> - <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="clickAddSelectedProducts"/> - </actionGroup> - <!--Add configurable product to order --> <actionGroup name="addConfigurableProductToOrder"> <arguments> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml deleted file mode 100644 index e4fd894f608c5..0000000000000 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ /dev/null @@ -1,168 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminAbleToShipPartiallyInvoicedItemsTest"> - <annotations> - <title value="Ship Action is available for remaining of the partially invoiced items "/> - <description value="Admin should be able to ship remaining ordered items if some of them are already refunded"/> - <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-93030"/> - <group value="sales"/> - - </annotations> - <before> - <createData entity="_defaultCategory" stepKey="createCategory"/> - <createData entity="_defaultProduct" stepKey="createSimpleProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - </before> - <after> - <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> - </after> - - <!--login to Admin--> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <comment userInput="Admin creates order" stepKey="adminCreateOrderComment"/> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderIndexPage"/> - <waitForPageLoad stepKey="waitForIndexPageLoad"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Orders" stepKey="seeIndexPageTitle"/> - - <!--Create new order--> - <click selector="{{AdminOrdersGridSection.createNewOrder}}" stepKey="clickCreateNewOrder"/> - <click selector="{{AdminOrderFormActionSection.CreateNewCustomer}}" stepKey="clickCreateCustomer"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Create New Order" stepKey="seeNewOrderPageTitle"/> - <actionGroup ref="addSimpleProductToOrderWithCustomQuantity" stepKey="addSimpleProductToOrderWithUserDefinedQty"> - <argument name="product" value="_defaultProduct"/> - <argument name="quantity" value="10"/> - </actionGroup> - - <!--Fill customer group and customer email which both are now required fields--> - <selectOption selector="{{AdminOrderFormAccountSection.group}}" userInput="{{GeneralCustomerGroup.code}}" stepKey="selectCustomerGroup" after="addSimpleProductToOrderWithUserDefinedQty"/> - <fillField selector="{{AdminOrderFormAccountSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail" after="selectCustomerGroup"/> - - <!--Fill customer address information--> - <actionGroup ref="fillOrderCustomerInformation" stepKey="fillCustomerAddress" after="fillCustomerEmail"> - <argument name="customer" value="Simple_US_Customer"/> - <argument name="address" value="US_Address_TX"/> - </actionGroup> - <!-- Select shipping --> - <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping" after="fillCustomerAddress"/> - - <!--Verify totals on Order page--> - <see selector="{{AdminOrderFormTotalSection.total('Subtotal')}}" userInput="$1,230.00" stepKey="seeOrderSubTotal" after="selectFlatRateShipping"/> - <see selector="{{AdminOrderFormTotalSection.total('Shipping')}}" userInput="$50.00" stepKey="seeOrderShipping" after="seeOrderSubTotal"/> - <scrollTo selector="{{AdminOrderFormTotalSection.grandTotal}}" stepKey="scrollToOrderGrandTotal"/> - <see selector="{{AdminOrderFormTotalSection.grandTotal}}" userInput="$1,280.00" stepKey="seeCorrectGrandTotal" after="scrollToOrderGrandTotal"/> - - <!--Submit Order and verify information--> - <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="clickSubmitOrder" after="seeCorrectGrandTotal"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskTodisappear"/> - <waitForPageLoad stepKey="waitForOrderToProcess"/> - <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPage" after="clickSubmitOrder"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the order." stepKey="seeSuccessMessage" after="seeViewOrderPage"/> - <grabTextFrom selector="|Order # (\d+)|" stepKey="getOrderId" after="seeSuccessMessage"/> - <scrollTo selector="{{AdminOrderItemsOrderedSection.qtyColumn}}" stepKey="scrollToItemsOrdered" after="getOrderId"/> - <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Ordered 10" stepKey="seeQtyOfItemsOrdered" after="scrollToItemsOrdered"/> - - <!--Create order invoice for first half of ordered items--> - <comment userInput="Admin creates invoice for order" stepKey="adminCreateInvoiceComment" /> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceActionButton"/> - <!--<seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl" after="clickInvoiceAction"/>--> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage" after="clickInvoiceActionButton"/> - <scrollTo selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced"/> - - <!--Verify items invoiced information--> - <fillField selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" userInput="5" stepKey="invoiceHalfTheItems"/> - <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQtyToBeInvoiced"/> - <waitForLoadingMaskToDisappear stepKey="WaitForQtyToUpdate"/> - <waitForElementVisible selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="waitforSubmitInvoiceBtn"/> - - <!--Submit Invoice--> - <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="submitInvoice"/> - <waitForLoadingMaskToDisappear stepKey="WaitForInvoiceToSubmit"/> - <!--<waitForElementVisible selector="{{AdminOrderDetailsMessagesSection.successMessage}}" stepKey="waitUntilInvoiceSucesssMsg"/>--> - - <!--Invoice created successfully--> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceSuccessMessage"/> - <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoicesTab"/> - <waitForLoadingMaskToDisappear stepKey="waitForInvoiceGridToLoad" after="clickInvoicesTab"/> - <see selector="{{AdminOrderInvoicesTabSection.gridRow('1')}}" userInput="$665.00" stepKey="seeOrderInvoiceTabInGrid" after="waitForInvoiceGridToLoad"/> - <click selector="{{AdminOrderInvoicesTabSection.viewGridRow('1')}}" stepKey="clickToViewInvoice" after="seeOrderInvoiceTabInGrid"/> - <click selector="{{AdminInvoiceOrderInformationSection.orderId}}" stepKey="clickOrderIdLinkOnInvoice"/> - - <!--Ship Order--> - <comment userInput="Admin creates shipment" stepKey="adminCreatesShipmentComment" before="clickShip"/> - <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip" after="clickOrderIdLinkOnInvoice"/> - <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="OrderShipmentUrl" after="clickShip"/> - <scrollTo selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" stepKey="scrollToItemsToShip"/> - <see selector="{{AdminShipmentItemsSection.itemQty('1')}}" userInput="Invoiced 5" stepKey="see5itemsInvoiced"/> - <fillField selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" userInput="5" stepKey="fillQtyOfItemsToShip"/> - - <!--Submit Shipment--> - <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="submitShipment" after="fillQtyOfItemsToShip"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="successfullShipmentCreation" after="submitShipment"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="$getOrderId" stepKey="seeOrderIdInPageTitleAfterShip"/> - - <!--Verify Items Status and Shipped Qty in the Items Ordered section--> - <scrollTo selector="{{AdminOrderItemsOrderedSection.itemStatus('1')}}" stepKey="scrollToItemsShipped"/> - <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Shipped 5" stepKey="see5itemsShipped"/> - - <!--Create Credit Memo--> - <comment userInput="Admin creates credit memo" stepKey="createCreditMemoComment"/> - <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreateCreditMemo" after="createCreditMemoComment"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewMemoInPageTitle"/> - - <!--Submit refund--> - <scrollTo selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" stepKey="scrollToItemsToRefund"/> - <!--<fillField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" stepKey="fillQtyOfItemsToRefund" after="scrollToItemsToRefund"/>--> - <!--<click selector="{{AdminCreditMemoItemsSection.updateQty}}" stepKey="updateRefundQty"/>--> - <waitForLoadingMaskToDisappear stepKey="waitForRefundQtyToUpdate"/> - <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="seeSubmitRefundBtn"/> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="submitRefundOffline"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoSuccessMsg" after="submitRefundOffline"/> - - <!--Create invoice for rest of the ordered items--> - <comment userInput="Admin creates invoice for rest of the items" stepKey="adminCreateInvoiceComment2" /> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceActionForRestOfItems"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage2" after="clickInvoiceActionForRestOfItems"/> - - <comment userInput="Qty To Invoice is 5" stepKey="seeRemainderInQtyToInvoice"/> - <scrollTo selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced2"/> - <!--<see selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="scrollToItemsInvoiced2"/>--> - <seeInField userInput="5" selector="{{AdminInvoiceItemsSection.itemQtyToInvoice('1')}}" stepKey="see5InTheQtyToInvoice"/> - - <!--Verify items invoiced information--> - <see selector="{{AdminInvoiceItemsSection.itemQty('1')}}" userInput="Refunded 5" stepKey="seeQtyOfItemsRefunded"/> - - <!--Submit Invoice--> - <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="submitInvoice2" /> - - <!--Invoice created successfully for the rest of the ordered items--> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceSuccessMessage2" after="submitInvoice2"/> - - <!--Verify Ship Action can be done for the rest of the invoiced items --> - <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipActionForRestOfItems" after="seeInvoiceSuccessMessage2"/> - - <!--Verify Items To Ship section --> - <scrollTo selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" stepKey="scrollToItemsToShip2"/> - <see selector="{{AdminShipmentItemsSection.itemQty('1')}}" userInput="Invoiced 10" stepKey="SeeAll10ItemsInvoiced"/> - <fillField selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" userInput="5" stepKey="fillRestOfItemsToShip"/> - - <!--Submit Shipment--> - <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="submitShipment2" after="fillRestOfItemsToShip"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="successfullyCreatedShipment" after="submitShipment2"/> - - <!--Verify Items Status and Shipped Qty in the Items Ordered section--> - <scrollTo selector="{{AdminOrderItemsOrderedSection.itemStatus('1')}}" stepKey="scrollToItemsOrdered2"/> - <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Shipped 10" stepKey="seeAllItemsShipped"/> - </test> -</tests> - diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php index 3d4a5785d6254..76bfd62a7b889 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemTest.php @@ -295,14 +295,14 @@ public function getItemQtyVariants() 'qty_ordered' => 12, 'qty_invoiced' => 5, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 7.0] + 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 7.0] ], 'partially_refunded' => [ 'options' => [ 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 0, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 12.0, 'to_invoice' => 0.0] + 'expectedResult' => ['to_ship' => 7.0, 'to_invoice' => 0.0] ], 'partially_shipped' => [ 'options' => [ @@ -316,7 +316,7 @@ public function getItemQtyVariants() 'qty_ordered' => 12, 'qty_invoiced' => 12, 'qty_refunded' => 5, 'qty_shipped' => 4, 'qty_canceled' => 0 ], - 'expectedResult' => ['to_ship' => 8.0, 'to_invoice' => 0.0] + 'expectedResult' => ['to_ship' => 3.0, 'to_invoice' => 0.0] ], 'complete' => [ 'options' => [ @@ -337,7 +337,7 @@ public function getItemQtyVariants() 'qty_ordered' => 4.4, 'qty_invoiced' => 0.4, 'qty_refunded' => 0.4, 'qty_shipped' => 4, 'qty_canceled' => 0, ], - 'expectedResult' => ['to_ship' => 0.4, 'to_invoice' => 4.0] + 'expectedResult' => ['to_ship' => 0.0, 'to_invoice' => 4.0] ], 'completely_invoiced_using_decimals' => [ 'options' => [ diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php index 873cd64e9c364..4c76dab99efa5 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php @@ -117,8 +117,6 @@ protected function setUp() 'getQuoteItemId', 'getLockedDoInvoice', 'getProductId', - 'getQtyRefunded', - 'getQtyInvoiced', ]); $this->salesOrderCollectionMock = $this->getMockBuilder( \Magento\Sales\Model\ResourceModel\Order\Collection::class @@ -623,163 +621,6 @@ public function testCanCancelAllInvoiced() $this->item->expects($this->any()) ->method('getQtyToInvoice') ->willReturn(0); - $this->item->expects($this->any()) - ->method('getQtyRefunded') - ->willReturn(0); - $this->item->expects($this->any()) - ->method('getQtyInvoiced') - ->willReturn(1); - - $this->assertFalse($this->order->canCancel()); - } - - public function testCanCancelAllRefunded() - { - $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) - ->disableOriginalConstructor() - ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) - ->getMock(); - $paymentMock->expects($this->any()) - ->method('canReviewPayment') - ->will($this->returnValue(false)); - $paymentMock->expects($this->any()) - ->method('canFetchTransactionInfo') - ->will($this->returnValue(false)); - $collectionMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, - ['getItems', 'setOrderFilter'] - ); - $this->orderItemCollectionFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($collectionMock)); - $collectionMock->expects($this->any()) - ->method('setOrderFilter') - ->willReturnSelf(); - $this->preparePaymentMock($paymentMock); - - $this->prepareItemMock(0); - - $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); - $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); - - $this->item->expects($this->any()) - ->method('isDeleted') - ->willReturn(false); - $this->item->expects($this->any()) - ->method('getQtyToInvoice') - ->willReturn(0); - $this->item->expects($this->any()) - ->method('getQtyRefunded') - ->willReturn(10); - $this->item->expects($this->any()) - ->method('getQtyInvoiced') - ->willReturn(10); - - $this->assertTrue($this->order->canCancel()); - } - - /** - * Test that order can be canceled if some items were partially invoiced with certain qty - * and then refunded for this qty. - * Sample: - * - ordered qty = 20 - * - invoiced = 10 - * - refunded = 10 - */ - public function testCanCancelPartiallyInvoicedAndRefunded() - { - $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) - ->disableOriginalConstructor() - ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) - ->getMock(); - $paymentMock->expects($this->any()) - ->method('canReviewPayment') - ->will($this->returnValue(false)); - $paymentMock->expects($this->any()) - ->method('canFetchTransactionInfo') - ->will($this->returnValue(false)); - $collectionMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, - ['getItems', 'setOrderFilter'] - ); - $this->orderItemCollectionFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($collectionMock)); - $collectionMock->expects($this->any()) - ->method('setOrderFilter') - ->willReturnSelf(); - $this->preparePaymentMock($paymentMock); - - $this->prepareItemMock(0); - - $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); - $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); - - $this->item->expects($this->any()) - ->method('isDeleted') - ->willReturn(false); - $this->item->expects($this->any()) - ->method('getQtyToInvoice') - ->willReturn(10); - $this->item->expects($this->any()) - ->method('getQtyRefunded') - ->willReturn(10); - $this->item->expects($this->any()) - ->method('getQtyInvoiced') - ->willReturn(10); - - $this->assertTrue($this->order->canCancel()); - } - - /** - * Test that order CAN NOT be canceled if some items were partially invoiced with certain qty - * and then refunded for less than that qty. - * Sample: - * - ordered qty = 10 - * - invoiced = 10 - * - refunded = 5 - */ - public function testCanCancelPartiallyInvoicedAndNotFullyRefunded() - { - $paymentMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Payment::class) - ->disableOriginalConstructor() - ->setMethods(['isDeleted', 'canReviewPayment', 'canFetchTransactionInfo', '__wakeUp']) - ->getMock(); - $paymentMock->expects($this->any()) - ->method('canReviewPayment') - ->will($this->returnValue(false)); - $paymentMock->expects($this->any()) - ->method('canFetchTransactionInfo') - ->will($this->returnValue(false)); - $collectionMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Item\Collection::class, - ['getItems', 'setOrderFilter'] - ); - $this->orderItemCollectionFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($collectionMock)); - $collectionMock->expects($this->any()) - ->method('setOrderFilter') - ->willReturnSelf(); - $this->preparePaymentMock($paymentMock); - - $this->prepareItemMock(0); - - $this->order->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_UNHOLD, false); - $this->order->setState(\Magento\Sales\Model\Order::STATE_NEW); - - $this->item->expects($this->any()) - ->method('isDeleted') - ->willReturn(false); - $this->item->expects($this->any()) - ->method('getQtyToInvoice') - ->willReturn(0); - $this->item->expects($this->any()) - ->method('getQtyRefunded') - ->willReturn(5); - $this->item->expects($this->any()) - ->method('getQtyInvoiced') - ->willReturn(10); $this->assertFalse($this->order->canCancel()); } @@ -1243,9 +1084,6 @@ public function testGetCreatedAtFormattedUsesCorrectLocale() $this->order->getCreatedAtFormatted(\IntlDateFormatter::SHORT); } - /** - * @return array - */ public function notInvoicingStatesProvider() { return [ @@ -1255,9 +1093,6 @@ public function notInvoicingStatesProvider() ]; } - /** - * @return array - */ public function canNotCreditMemoStatesProvider() { return [ diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml index a7bf82588f7c7..9a7b3f1ff6bbf 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml @@ -12,7 +12,6 @@ <element name="itemName" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-product .product-title" parameterized="true"/> <element name="itemSku" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-product .product-sku-block" parameterized="true"/> <element name="itemQty" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-ordered-qty .qty-table" parameterized="true"/> - <element name="itemQtyToShip" type="input" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-qty input.qty-item" parameterized="true"/> <element name="nameColumn" type="text" selector=".order-shipment-table .col-product .product-title"/> <element name="skuColumn" type="text" selector=".order-shipment-table .col-product .product-sku-block"/> </section> diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php index eae0e600434a6..8262a7e41543e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php @@ -115,8 +115,7 @@ public function testInvoke() ); $this->assertNotEmpty($result); $order = $this->objectManager->get(OrderRepositoryInterface::class)->get($order->getId()); - //Totally refunded orders still can be processed and shipped. - $this->assertEquals(Order::STATE_PROCESSING, $order->getState()); + $this->assertEquals(Order::STATE_CLOSED, $order->getState()); } private function getItemsForRest($order) diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php index aacda763ca2aa..12cbe1ca0e5e2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php @@ -86,11 +86,10 @@ public function testShortRequest() 'Failed asserting that proper shipping amount of the Order was refunded' ); - //Totally refunded orders can be processed. - $this->assertEquals( + $this->assertNotEquals( $existingOrder->getStatus(), $updatedOrder->getStatus(), - 'Failed asserting that order status has not changed' + 'Failed asserting that order status was changed' ); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $this->fail('Failed asserting that Creditmemo was created'); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml index 31d5c30d25fc7..f59e6df845b6e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml @@ -22,7 +22,7 @@ <data name="steps" xsi:type="string">invoice, shipment|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> - <data name="resultStatuses" xsi:type="string">Complete,Canceled</data> + <data name="resultStatuses" xsi:type="string">Complete,Closed</data> <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionPartialFailMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php index f2cd745e96d83..1a22ea947f85a 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php @@ -64,8 +64,7 @@ public function testProcessIpnRequestFullRefund() $creditmemoItems = $order->getCreditmemosCollection()->getItems(); $creditmemo = current($creditmemoItems); - //Totally refunded orders still can be shipped - $this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ; + $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ; $this->assertEquals(1, count($creditmemoItems)); $this->assertEquals(Creditmemo::STATE_REFUNDED, $creditmemo->getState()); $this->assertEquals(10, $order->getSubtotalRefunded()); @@ -147,8 +146,7 @@ public function testProcessIpnRequestRestRefund() $creditmemoItems = $order->getCreditmemosCollection()->getItems(); - //Totally refunded orders still can be shipped - $this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ; + $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ; $this->assertEquals(1, count($creditmemoItems)); $this->assertEquals(10, $order->getSubtotalRefunded()); $this->assertEquals(10, $order->getBaseSubtotalRefunded()); From 8bdcec2151953eb91ee61075917e60648662395f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 13 Nov 2018 09:43:19 -0600 Subject: [PATCH 1194/1415] MAGETWO-96262: Order with simple product after partial cancellation and credit memo has status 'Processing' --- ...ssertOrderCancelMassActionPartialFailMessage.php | 13 ++----------- .../Sales/Test/TestCase/MassOrdersUpdateTest.xml | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php index 6aed5cd39aaad..9208032a316ef 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionPartialFailMessage.php @@ -15,15 +15,10 @@ */ class AssertOrderCancelMassActionPartialFailMessage extends AbstractConstraint { - /** - * Message displayed after cancel order from archive - */ - const SUCCESS_MESSAGE = 'We canceled 1 order(s).'; - /** * Text value to be checked */ - const FAIL_CANCEL_MESSAGE = '1 order(s) cannot be canceled.'; + const FAIL_CANCEL_MESSAGE = 'You cannot cancel the order(s).'; /** * Assert cancel fail message is displayed on order index page @@ -37,10 +32,6 @@ public function processAssert(OrderIndex $orderIndex) self::FAIL_CANCEL_MESSAGE, $orderIndex->getMessagesBlock()->getErrorMessage() ); - \PHPUnit\Framework\Assert::assertEquals( - self::SUCCESS_MESSAGE, - $orderIndex->getMessagesBlock()->getSuccessMessage() - ); } /** @@ -50,6 +41,6 @@ public function processAssert(OrderIndex $orderIndex) */ public function toString() { - return 'Cancel and success fail message is displayed on order index page.'; + return 'Cancel fail message is displayed on order index page.'; } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml index f59e6df845b6e..99e25b062846b 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml @@ -18,7 +18,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation2"> - <data name="description" xsi:type="string">try to cancel orders in status Complete, Canceled</data> + <data name="description" xsi:type="string">try to cancel orders in status Complete, Closed</data> <data name="steps" xsi:type="string">invoice, shipment|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> @@ -31,7 +31,7 @@ <data name="steps" xsi:type="string">invoice|invoice, credit memo</data> <data name="action" xsi:type="string">Cancel</data> <data name="ordersCount" xsi:type="string">2</data> - <data name="resultStatuses" xsi:type="string">Processing,Canceled</data> + <data name="resultStatuses" xsi:type="string">Processing,Closed</data> <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelMassActionPartialFailMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> From 9d0773b8db2c2a74e76702c08a87b90a8976b4be Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Tue, 13 Nov 2018 18:53:30 +0200 Subject: [PATCH 1195/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - improve CE locator that is different from B2B --- .../Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml index bae7069859937..afc60e80954e2 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml @@ -11,4 +11,9 @@ <!-- This actionGroup was created to be merged from B2B because B2B has a very different form control here --> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> </actionGroup> + + <actionGroup name="selectRetailerCustomerGroup"> + <!-- This actionGroup was created to be merged from B2B. Retailer Customer Group --> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectCustomerGroup"/> + </actionGroup> </actionGroups> From 3b84172faf8612ca7fc54c4c3bb131923e521c01 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 19:07:45 +0200 Subject: [PATCH 1196/1415] Small refactoring --- app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index f7467ef07aadb..7c8a92397d8c5 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -161,12 +161,11 @@ public function afterDelete(CustomerRepository $subject, $result, CustomerInterf public function afterGetById(CustomerRepository $subject, CustomerInterface $customer) { $extensionAttributes = $customer->getExtensionAttributes(); - + $storeId = $this->storeManager->getStore()->getId(); + $customer->setStoreId($storeId); if ($extensionAttributes === null) { /** @var CustomerExtensionInterface $extensionAttributes */ $extensionAttributes = $this->extensionFactory->create(CustomerInterface::class); - $storeId = $this->storeManager->getStore()->getId(); - $customer->setStoreId($storeId); $customer->setExtensionAttributes($extensionAttributes); } if ($extensionAttributes->getIsSubscribed() === null) { From 702072502f924e380149709ecfe5247ff4a7d510 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 19:16:27 +0200 Subject: [PATCH 1197/1415] GraphQL-43: [Query] My Account > My Wish List - Refactoring --- .../Model/ProductDataProvider.php} | 21 ++++- .../Model/Resolver/ProductResolver.php | 53 ++++++++++++ .../WishlistItemsProductsResolver.php | 56 ------------- .../Model/Resolver/WishlistItemsResolver.php | 81 ++++++++++++++----- .../Model/Resolver/WishlistResolver.php | 53 +++++++----- .../Model/WishlistDataProvider.php | 37 --------- .../Model/WishlistItemsDataProvider.php | 50 ------------ .../WishlistGraphQl/etc/schema.graphqls | 16 ++-- .../Magento/GraphQl/Wishlist/WishlistTest.php | 60 +++++++++----- 9 files changed, 214 insertions(+), 213 deletions(-) rename app/code/Magento/{WishlistGraphQl/Model/WishlistItemsProductDataProvider.php => CatalogGraphQl/Model/ProductDataProvider.php} (60%) create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php similarity index 60% rename from app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php rename to app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php index 76df065a80702..0d38490407e7c 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php @@ -5,23 +5,38 @@ */ declare(strict_types=1); -namespace Magento\WishlistGraphQl\Model; +namespace Magento\CatalogGraphQl\Model; use Magento\Catalog\Api\ProductRepositoryInterface; -class WishlistItemsProductDataProvider +/** + * Product data provider + * + * TODO: will be replaces on deferred mechanism + */ +class ProductDataProvider { /** * @var ProductRepositoryInterface */ private $productRepository; + /** + * @param ProductRepositoryInterface $productRepository + */ public function __construct(ProductRepositoryInterface $productRepository) { $this->productRepository = $productRepository; } - public function getProductDataById(int $productId) { + /** + * Get product data by id + * + * @param int $productId + * @return array + */ + public function getProductDataById(int $productId): array + { $product = $this->productRepository->getById($productId); $productData = $product->toArray(); $productData['model'] = $product; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php new file mode 100644 index 0000000000000..b59582a189f60 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\CatalogGraphQl\Model\ProductDataProvider; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\Item; + +/** + * Fetches the Product data according to the GraphQL schema + */ +class ProductResolver implements ResolverInterface +{ + /** + * @var ProductDataProvider + */ + private $productDataProvider; + + /** + * @param ProductDataProvider $productDataProvider + */ + public function __construct(ProductDataProvider $productDataProvider) + { + $this->productDataProvider = $productDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('Missing key "model" in Wishlist Item value data')); + } + /** @var Item $wishlistItem */ + $wishlistItem = $value['model']; + + return $this->productDataProvider->getProductDataById($wishlistItem->getProductId()); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php deleted file mode 100644 index 26ace0e849e3f..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\WishlistGraphQl\Model\Resolver; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\WishlistGraphQl\Model\WishlistItemsProductDataProvider; - -class WishlistItemsProductsResolver implements ResolverInterface -{ - /** - * @var WishlistItemsProductDataProvider - */ - private $productDataProvider; - - public function __construct(WishlistItemsProductDataProvider $productDataProvider) - { - $this->productDataProvider = $productDataProvider; - } - - - /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['product_id'])) { - throw new GraphQlInputException( - __('Missing key %1 in wishlist item data', ['product_id']) - ); - } - return $this->productDataProvider->getProductDataById($value['product_id']); - } -} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 707618b10602d..033c63441e907 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -7,36 +7,46 @@ namespace Magento\WishlistGraphQl\Model\Resolver; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Wishlist\Model\ResourceModel\Item\Collection as WishlistItemCollection; +use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; use Magento\Wishlist\Model\Item; -use Magento\WishlistGraphQl\Model\WishlistItemsDataProvider; +use Magento\Wishlist\Model\Wishlist; +/** + * Fetches the Wishlist Items data according to the GraphQL schema + */ class WishlistItemsResolver implements ResolverInterface { /** - * @var WishlistItemsDataProvider + * @var WishlistItemCollectionFactory */ - private $wishlistItemsDataProvider; + private $wishlistItemCollectionFactory; - public function __construct(WishlistItemsDataProvider $wishlistItemsDataProvider) - { - $this->wishlistItemsDataProvider = $wishlistItemsDataProvider; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param WishlistItemCollectionFactory $wishlistItemCollectionFactory + * @param StoreManagerInterface $storeManager + */ + public function __construct( + WishlistItemCollectionFactory $wishlistItemCollectionFactory, + StoreManagerInterface $storeManager + ) { + $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->storeManager = $storeManager; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve( Field $field, @@ -45,14 +55,41 @@ public function resolve( array $value = null, array $args = null ) { - return array_map(function (Item $wishlistItem) { - return [ + if (!isset($value['model'])) { + throw new LocalizedException(__('Missing key "model" in Wishlist value data')); + } + /** @var Wishlist $wishlist */ + $wishlist = $value['model']; + + $wishlistItems = $this->getWishListItems($wishlist); + + $data = []; + foreach ($wishlistItems as $wishlistItem) { + $data[] = [ 'id' => $wishlistItem->getId(), 'qty' => $wishlistItem->getData('qty'), - 'description' => (string)$wishlistItem->getDescription(), + 'description' => $wishlistItem->getDescription(), 'added_at' => $wishlistItem->getAddedAt(), - 'product_id' => (int)$wishlistItem->getProductId() + 'model' => $wishlistItem, ]; - }, $this->wishlistItemsDataProvider->getWishlistItemsForCustomer($context->getUserId())); + } + return $data; + } + + /** + * @param Wishlist $wishlist + * @return Item[] + */ + private function getWishListItems(Wishlist $wishlist): array + { + /** @var WishlistItemCollection $wishlistItemCollection */ + $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); + $wishlistItemCollection + ->addWishlistFilter($wishlist) + ->addStoreFilter(array_map(function (StoreInterface $store) { + return $store->getId(); + }, $this->storeManager->getStores())) + ->setVisibilityFilter(); + return $wishlistItemCollection->getItems(); } } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index ba1a6e935c10e..e3a788af2ea7e 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -8,34 +8,39 @@ namespace Magento\WishlistGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\WishlistGraphQl\Model\WishlistDataProvider; +use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\Wishlist; +use Magento\Wishlist\Model\WishlistFactory; +/** + * Fetches the Wishlist data according to the GraphQL schema + */ class WishlistResolver implements ResolverInterface { /** - * @var WishlistDataProvider + * @var WishlistResourceModel + */ + private $wishlistResource; + + /** + * @var WishlistFactory */ - private $wishlistDataProvider; + private $wishlistFactory; - public function __construct(WishlistDataProvider $wishlistDataProvider) + /** + * @param WishlistResourceModel $wishlistResource + * @param WishlistFactory $wishlistFactory + */ + public function __construct(WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory) { - $this->wishlistDataProvider = $wishlistDataProvider; + $this->wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve( Field $field, @@ -44,10 +49,22 @@ public function resolve( array $value = null, array $args = null ) { - $wishlist = $this->wishlistDataProvider->getWishlistForCustomer($context->getUserId()); + $customerId = $context->getUserId(); + + /** @var Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + + if (null === $wishlist->getId()) { + return []; + } + return [ 'sharing_code' => $wishlist->getSharingCode(), - 'updated_at' => $wishlist->getUpdatedAt() + 'updated_at' => $wishlist->getUpdatedAt(), + 'items_count' => $wishlist->getItemsCount(), + 'name' => $wishlist->getName(), + 'model' => $wishlist, ]; } } diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php deleted file mode 100644 index a62ddebd91120..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\WishlistGraphQl\Model; - -use Magento\Wishlist\Model\ResourceModel\Wishlist; -use Magento\Wishlist\Model\WishlistFactory; - -class WishlistDataProvider -{ - /** - * @var Wishlist - */ - private $wishlistResource; - /** - * @var WishlistFactory - */ - private $wishlistFactory; - - public function __construct(Wishlist $wishlistResource, WishlistFactory $wishlistFactory) - { - $this->wishlistResource = $wishlistResource; - $this->wishlistFactory = $wishlistFactory; - } - - public function getWishlistForCustomer(int $customerId): \Magento\Wishlist\Model\Wishlist - { - /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ - $wishlist = $this->wishlistFactory->create(); - $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); - return $wishlist; - } -} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php deleted file mode 100644 index ca87b23460fc7..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\WishlistGraphQl\Model; - -use Magento\Store\Api\Data\StoreInterface; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Wishlist\Model\Item; -use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; - -class WishlistItemsDataProvider -{ - - /** - * @var WishlistItemCollectionFactory - */ - private $wishlistItemCollectionFactory; - /** - * @var StoreManagerInterface - */ - private $storeManager; - - public function __construct( - WishlistItemCollectionFactory $wishlistItemCollectionFactory, - StoreManagerInterface $storeManager - ) { - $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; - $this->storeManager = $storeManager; - } - - /** - * @param int $customerId - * @return Item[] - */ - public function getWishlistItemsForCustomer(int $customerId): array - { - $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); - $wishlistItemCollection->addCustomerIdFilter($customerId); - $wishlistItemCollection->addStoreFilter(array_map(function (StoreInterface $store) { - return $store->getId(); - }, $this->storeManager->getStores())); - $wishlistItemCollection->setVisibilityFilter(); - $wishlistItemCollection->load(); - return $wishlistItemCollection->getItems(); - } -} diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 5c6d701138560..a63ec6eff6f5b 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -7,14 +7,16 @@ type Query { type WishlistOutput { items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), - sharing_code: String! @doc(description: "todo"), - updated_at: String! @doc(description: "todo") + items_count: Int @doc(description: "todo"), + name: String @doc(description: "todo"), + sharing_code: String @doc(description: "todo"), + updated_at: String @doc(description: "todo") } type WishlistItem { - id: Int! @doc(description: "todo") - qty: Float! @doc(description: "todo"), - description: String! @doc(description: "todo"), - added_at: String! @doc(description: "todo"), - product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsProductsResolver") + id: Int @doc(description: "todo") + qty: Float @doc(description: "todo"), + description: String @doc(description: "todo"), + added_at: String @doc(description: "todo"), + product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver") } \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php index 53577d02df50f..d570fc09b7714 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php @@ -8,40 +8,45 @@ namespace Magento\GraphQl\Wishlist; use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Wishlist\Model\Item; +use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\WishlistFactory; class WishlistTest extends GraphQlAbstract { - /** - * @var \Magento\TestFramework\ObjectManager - */ - private $objectManager; /** * @var CustomerTokenServiceInterface */ private $customerTokenService; + /** + * @var WishlistFactory + */ + private $wishlistFactory; + + /** + * @var WishlistResourceModel + */ + private $wishlistResource; + protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); + $this->wishlistFactory = Bootstrap::getObjectManager()->get(WishlistFactory::class); + $this->wishlistResource = Bootstrap::getObjectManager()->get(WishlistResourceModel::class); } /** - * Verify the fields of CMS Block selected by identifiers - * * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php - * @throws \Magento\Framework\Exception\AuthenticationException - * @throws \Exception */ - public function testGetCustomersWishlist(): void + public function testGetCustomerWishlist(): void { /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ - $wishlist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Wishlist\Model\Wishlist::class - ); - $wishlist->loadByCustomerId(1, true); + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, 1, 'customer_id'); + /** @var Item $wishlistItem */ $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); $wishlistItemProduct = $wishlistItem->getProduct(); @@ -49,26 +54,41 @@ public function testGetCustomersWishlist(): void <<<QUERY { wishlist { + items_count + name + sharing_code + updated_at items { id qty + description + added_at product { sku name } - description - added_at } - sharing_code - updated_at } } QUERY; - $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders('customer@example.com', 'password')); + $response = $this->graphQlQuery( + $query, + [], + '', + $this->getCustomerAuthHeaders('customer@example.com', 'password') + ); + + $this->assertEquals($wishlist->getItemsCount(), $response['wishlist']['items_count']); + $this->assertEquals($wishlist->getName(), $response['wishlist']['name']); $this->assertEquals($wishlist->getSharingCode(), $response['wishlist']['sharing_code']); + $this->assertEquals($wishlist->getUpdatedAt(), $response['wishlist']['updated_at']); + + $this->assertEquals($wishlistItem->getId(), $response['wishlist']['items'][0]['id']); $this->assertEquals($wishlistItem->getData('qty'), $response['wishlist']['items'][0]['qty']); $this->assertEquals($wishlistItem->getDescription(), $response['wishlist']['items'][0]['description']); + $this->assertEquals($wishlistItem->getAddedAt(), $response['wishlist']['items'][0]['added_at']); + $this->assertEquals($wishlistItemProduct->getSku(), $response['wishlist']['items'][0]['product']['sku']); $this->assertEquals($wishlistItemProduct->getName(), $response['wishlist']['items'][0]['product']['name']); } From 0d3d631aba4c2c536fcf654b726cf085212de5dd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 13 Nov 2018 09:29:11 -0800 Subject: [PATCH 1198/1415] MAGETWO-96318: Revert MAGETWO-64316 due to performance degradation --- .../Model/WebapiProductUrlPathGenerator.php | 72 ------------------- .../CatalogUrlRewrite/etc/webapi_rest/di.xml | 10 --- .../CatalogUrlRewrite/etc/webapi_soap/di.xml | 10 --- .../Api/ProductRepositoryInterfaceTest.php | 56 --------------- 4 files changed, 148 deletions(-) delete mode 100644 app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php delete mode 100644 app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml delete mode 100644 app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml diff --git a/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php deleted file mode 100644 index ae93b76b31579..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\CatalogUrlRewrite\Model; - -use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; - -/** - * Class for creating product url through web-api. - */ -class WebapiProductUrlPathGenerator extends ProductUrlPathGenerator -{ - /** - * @var CollectionFactory - */ - private $collectionFactory; - - /** - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator - * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository - * @param CollectionFactory $collectionFactory - */ - public function __construct( - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator, - \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, - CollectionFactory $collectionFactory - ) { - parent::__construct($storeManager, $scopeConfig, $categoryUrlPathGenerator, $productRepository); - $this->collectionFactory = $collectionFactory; - } - - /** - * @inheritdoc - */ - protected function prepareProductUrlKey(\Magento\Catalog\Model\Product $product) - { - $urlKey = $product->getUrlKey(); - if ($urlKey === '' || $urlKey === null) { - $urlKey = $this->prepareUrlKey($product->formatUrlKey($product->getName())); - } - return $product->formatUrlKey($urlKey); - } - - /** - * Crete url key if it does not exist yet. - * - * @param string $urlKey - * @return string - */ - private function prepareUrlKey(string $urlKey) : string - { - /** @var ProductCollection $collection */ - $collection = $this->collectionFactory->create(); - $collection->addFieldToFilter('url_key', ['like' => $urlKey]); - if ($collection->getSize() !== 0) { - $urlKey = $urlKey . '-1'; - $urlKey = $this->prepareUrlKey($urlKey); - } - - return $urlKey; - } -} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml deleted file mode 100644 index ac8beb362f0fb..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/> -</config> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml deleted file mode 100644 index ac8beb362f0fb..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/> -</config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 1017fb6716709..3e935e1d7ae9b 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -159,62 +159,6 @@ private function loadWebsiteByCode($websiteCode) return $website; } - /** - * Test for check that 2 same product create and url_key save. - * - * @return void - */ - public function testSaveTwoSameProduct() - { - $serviceInfo = [ - 'rest' => [ - 'resourcePath' => self::RESOURCE_PATH, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, - ], - 'soap' => [ - 'service' => self::SERVICE_NAME, - 'serviceVersion' => self::SERVICE_VERSION, - 'operation' => self::SERVICE_NAME . 'Save', - ], - ]; - - $product1 = [ - 'product' => [ - 'attribute_set_id' => 4, - 'name' => "Test API 1", - 'price' => 254.13, - 'sku' => '1234' - ] - ]; - $product2 = [ - 'product' => [ - 'attribute_set_id' => 4, - 'name' => "Test API 1", - 'price' => 254.13, - 'sku' => '1235' - ] - ]; - - $product1 = $this->_webApiCall($serviceInfo, $product1); - $response = $this->_webApiCall($serviceInfo, $product2); - - $index = null; - foreach ($response['custom_attributes'] as $key => $customAttribute) { - if ($customAttribute['attribute_code'] == 'url_key') { - $index = $key; - break; - } - } - - $this->assertArrayHasKey(ProductInterface::SKU, $response); - - $expectedResult = $product1['custom_attributes'][$index]['value'] . '-1'; - $this->assertEquals($expectedResult, $response['custom_attributes'][$index]['value']); - - $this->deleteProduct('1234'); - $this->deleteProduct('1235'); - } - /** * Test removing association between product and website 1 * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php From 7c9de8e88705824b07378de2bca5ae383c5c80fb Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 13 Nov 2018 13:25:39 -0600 Subject: [PATCH 1199/1415] #13157 - Last Ordered Items block - bad js code --- .../frontend/templates/reorder/sidebar.phtml | 2 +- .../web/js/view/last-ordered-items.js | 27 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 370e034ead64a..9b3633fde60b4 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -51,7 +51,7 @@ <div id="cart-sidebar-reorder-advice-container"></div> <div class="actions-toolbar"> <div class="primary" - data-bind="visible: lastOrderedItems.isShowAddToCart"> + data-bind="visible: isShowAddToCart"> <button type="submit" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>" class="action tocart primary"> <span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span> </button> diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index 74465128f8c72..17e61a77d98a3 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -11,18 +11,37 @@ define([ 'use strict'; return Component.extend({ + defaults: { + isShowAddToCart: false + }, + /** @inheritdoc */ initialize: function () { - var isShowAddToCart; - this._super(); this.lastOrderedItems = customerData.get('last-ordered-items'); + this.lastOrderedItems.subscribe(this.checkSalableItems.bind(this)); + this.checkSalableItems(); + + return this; + }, + + /** @inheritdoc */ + initObservable: function () { + this._super() + .observe('isShowAddToCart'); + + return this; + }, - isShowAddToCart = _.some(this.lastOrderedItems().items, { + /** + * Check if items is_saleable and change add to cart button visibility. + */ + checkSalableItems: function () { + var isShowAddToCart = _.some(this.lastOrderedItems().items, { 'is_saleable': true }); - this.lastOrderedItems.isShowAddToCart = isShowAddToCart; + this.isShowAddToCart(isShowAddToCart); } }); }); From 39fe0fa91f1eb7146af7f7d542f54dfc0f764b20 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 13 Nov 2018 13:28:48 -0600 Subject: [PATCH 1200/1415] MQE-1339: Bump MFTF version in Magento - MFTF version bump and lockfile update --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 44452b6b4745f..00e5767fb4d6a 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.10", + "magento/magento2-functional-testing-framework": "2.3.11", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 3565ab2420e05..7ce9efeb65e6f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94ba8bea0470c1e4599c17145dcf3508", + "content-hash": "243bbfba7578f2084615fa0c092f87a8", "packages": [ { "name": "braintree/braintree_php", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.10", + "version": "2.3.11", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d" + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/7cd80dbf1af405473f1a976c3b75097a0f27725d", - "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/3ca1bd74228a61bd05520bed1ef88b5a19764d92", + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-11-06T20:54:16+00:00" + "time": "2018-11-13T18:22:25+00:00" }, { "name": "moontoast/math", From 0dfe7ffb2201ff360e9c34c123ae73b9a06af83f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 13 Nov 2018 18:22:12 -0600 Subject: [PATCH 1201/1415] MAGETWO-96262: Order with simple product after partial cancellation and credit memo has status 'Processing' --- .../Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml index 9a7b3f1ff6bbf..a7bf82588f7c7 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentItemsSection.xml @@ -12,6 +12,7 @@ <element name="itemName" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-product .product-title" parameterized="true"/> <element name="itemSku" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-product .product-sku-block" parameterized="true"/> <element name="itemQty" type="text" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-ordered-qty .qty-table" parameterized="true"/> + <element name="itemQtyToShip" type="input" selector=".order-shipment-table tbody:nth-of-type({{var1}}) .col-qty input.qty-item" parameterized="true"/> <element name="nameColumn" type="text" selector=".order-shipment-table .col-product .product-title"/> <element name="skuColumn" type="text" selector=".order-shipment-table .col-product .product-sku-block"/> </section> From d3078dbd147a6fb30592370256f34c84f078fa33 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 14 Nov 2018 10:17:15 +0300 Subject: [PATCH 1202/1415] MAGETWO-71022: After return "RMA" is complete in Admin, "remaining quantity" in customer account shows incorrect value - Stabilize test --- .../Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml index 4ab1e3327960c..00f290cd94e70 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml @@ -13,5 +13,6 @@ <element name="email" type="input" selector="#email"/> <element name="requiredGroup" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-group-id']"/> <element name="requiredEmail" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-email']"/> + <element name="defaultGeneral" type="text" selector="//*[text()='Default (General)']" time="15"/> </section> </sections> \ No newline at end of file From 0acab420008a958fcbbb635cd0317681a5f06309 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Wed, 14 Nov 2018 11:14:58 +0300 Subject: [PATCH 1203/1415] MAGETWO-62728: My Wishlist - quantity input box issue - Fix static tests --- .../Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index 8a20d2925849a..cab130f7c2104 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -188,7 +188,7 @@ define([ /** * Bind form submit. * - * @param {boolean} isFileUploaded + * @param {Boolean} isFileUploaded */ bindFormSubmit: function (isFileUploaded) { var self = this; @@ -199,6 +199,7 @@ define([ if (!$($(self.options.qtyInfo).closest('form')).valid()) { event.stopPropagation(); event.preventDefault(); + return; } From a9bdbdb95a4156aa3e05d31d245b3057c08f7080 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 14 Nov 2018 11:21:43 +0200 Subject: [PATCH 1204/1415] magento/magento2#13095: [Forwardport] No locale for Swedish (Finland). --- lib/internal/Magento/Framework/Locale/Config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Locale/Config.php b/lib/internal/Magento/Framework/Locale/Config.php index 8767bd515db82..790fa9c924c8e 100644 --- a/lib/internal/Magento/Framework/Locale/Config.php +++ b/lib/internal/Magento/Framework/Locale/Config.php @@ -90,6 +90,7 @@ class Config implements \Magento\Framework\Locale\ConfigInterface 'sq_AL', /*Albanian (Albania)*/ 'sr_Cyrl_RS', /*Serbian (Serbia)*/ 'sv_SE', /*Swedish (Sweden)*/ + 'sv_FI', /*Swedish (Finland)*/ 'sw_KE', /*Swahili (Kenya)*/ 'th_TH', /*Thai (Thailand)*/ 'tr_TR', /*Turkish (Turkey)*/ From ace100593b2903cbd79b9f3b4d0f49108b5465d4 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Wed, 31 Oct 2018 10:17:55 +0200 Subject: [PATCH 1205/1415] ENGCOM-3449: Fix/add expresion. --- .../Db/Collection/AbstractTest.php | 38 +++++++++++++++++++ .../Db/Collection/AbstractCollection.php | 14 +++++-- .../Db/Collection/AbstractCollectionTest.php | 3 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php index 419a7d04b778a..2ee0953dcdbf1 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php @@ -72,4 +72,42 @@ public function testGetAllIdsWithBind() $this->_model->addBindParam('code', 'admin'); $this->assertEquals(['0'], $this->_model->getAllIds()); } + + /** + * Check add field to select doesn't remove expression field from select. + * + * @return void + */ + public function testAddExpressionFieldToSelectWithAdditionalFields() + { + $expectedColumns = ['code', 'test_field']; + $actualColumns = []; + + $testExpression = new \Zend_Db_Expr('(sort_order + group_id)'); + $this->_model->addExpressionFieldToSelect('test_field', $testExpression, ['sort_order', 'group_id']); + $this->_model->addFieldToSelect('code', 'code'); + $columns = $this->_model->getSelect()->getPart(\Magento\Framework\DB\Select::COLUMNS); + foreach ($columns as $columnEntry) { + $actualColumns[] = $columnEntry[2]; + } + + $this->assertEquals($expectedColumns, $actualColumns); + } + + /** + * Check add expression field doesn't remove all fields from select. + * + * @return void + */ + public function testAddExpressionFieldToSelectWithoutAdditionalFields() + { + $expectedColumns = ['*', 'test_field']; + + $testExpression = new \Zend_Db_Expr('(sort_order + group_id)'); + $this->_model->addExpressionFieldToSelect('test_field', $testExpression, ['sort_order', 'group_id']); + $columns = $this->_model->getSelect()->getPart(\Magento\Framework\DB\Select::COLUMNS); + $actualColumns = [$columns[0][1], $columns[1][2]]; + + $this->assertEquals($expectedColumns, $actualColumns); + } } diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php index a88e013f5d2fe..6e1ea24a61a4a 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php @@ -45,6 +45,13 @@ abstract class AbstractCollection extends AbstractDb implements SourceProviderIn */ protected $_fieldsToSelect = null; + /** + * Expression fields to select in query. + * + * @var array + */ + private $expressionFieldsToSelect = []; + /** * Fields initial fields to select like id_field * @@ -205,7 +212,7 @@ protected function _initSelectFields() $columnsToSelect = []; foreach ($columns as $columnEntry) { list($correlationName, $column, $alias) = $columnEntry; - if ($correlationName !== 'main_table') { + if ($correlationName !== 'main_table' || isset($this->expressionFieldsToSelect[$alias])) { // Add joined fields to select if ($column instanceof \Zend_Db_Expr) { $column = $column->__toString(); @@ -346,9 +353,8 @@ public function addExpressionFieldToSelect($alias, $expression, $fields) $fullExpression = str_replace('{{' . $fieldKey . '}}', $fieldItem, $fullExpression); } - $fullExpression = new \Zend_Db_Expr($fullExpression); - $this->_fieldsToSelect[$alias] = $fullExpression; - $this->_fieldsToSelectChanged = true; + $this->getSelect()->columns([$alias => $fullExpression]); + $this->expressionFieldsToSelect[$alias] = $fullExpression; return $this; } diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php index 0eae94dabbbe8..4f27f083509d7 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/Collection/AbstractCollectionTest.php @@ -269,9 +269,8 @@ public function addFieldToSelectDataProvider() */ public function testAddExpressionFieldToSelect($alias, $expression, $fields, $expected) { + $this->selectMock->expects($this->once())->method('columns')->with($expected); $this->assertTrue($this->uut->addExpressionFieldToSelect($alias, $expression, $fields) instanceof Uut); - $this->assertEquals($expected, $this->uut->getFieldsToSelect()); - $this->assertTrue($this->uut->wereFieldsToSelectChanged()); } /** From 88a8763ab8646d2e7d69c344507a4701e0bcd3f0 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Wed, 14 Nov 2018 12:03:34 +0200 Subject: [PATCH 1206/1415] Fix selection of all items which are not visible in ui grid --- app/code/Magento/Ui/view/base/web/js/grid/massactions.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js index 48c04458ff49a..2e87e00fecda9 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js @@ -153,6 +153,11 @@ define([ var itemsType = data.excludeMode ? 'excluded' : 'selected', selections = {}; + if (itemsType === 'excluded' && data['selected'].length){ + data['selected'] = _.difference(data['selected'], data['excluded']); + itemsType = 'selected'; + } + selections[itemsType] = data[itemsType]; if (!selections[itemsType].length) { From 303698fbcaf7c6fcd519e1d92014cf567a2f310b Mon Sep 17 00:00:00 2001 From: Khodu Vaishnav <khodu.vaishnav@krishtechnolabs.com> Date: Wed, 14 Nov 2018 15:56:48 +0530 Subject: [PATCH 1207/1415] 9130 remove the negative qty block. --- .../CatalogInventory/Block/Stockqty/AbstractStockqty.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php index 568fa600ec52d..7b27125f73fa6 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php @@ -131,7 +131,7 @@ public function getPlaceholderId() */ public function isMsgVisible() { - return $this->getStockQty() > 0 && $this->getStockQtyLeft() <= $this->getThresholdQty(); + return $this->getStockQty() > 0 && $this->getStockQtyLeft() > 0 && $this->getStockQtyLeft() <= $this->getThresholdQty(); } /** From 32e0f571322e7a37d38e6b3d19856bc4ce90143b Mon Sep 17 00:00:00 2001 From: Mariana Lashch <mlashch@magento.com> Date: Wed, 14 Nov 2018 13:15:58 +0200 Subject: [PATCH 1208/1415] MAGETWO-94472: [2.3] Unable to create credit memo for order placed via online payment with taxes and discounts - add changes to actiongroup --- .../Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml index afc60e80954e2..a794c67e736fc 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCartPriceRuleActionGroup.xml @@ -14,6 +14,6 @@ <actionGroup name="selectRetailerCustomerGroup"> <!-- This actionGroup was created to be merged from B2B. Retailer Customer Group --> - <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectRetailerCustomerGroup"/> </actionGroup> </actionGroups> From 66fb58bc8acbf04083bf6d332b5d83a9906e42a6 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Wed, 14 Nov 2018 16:02:45 +0200 Subject: [PATCH 1209/1415] GraphQl-41: [Query] My Account > My Orders -- Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 7ce9efeb65e6f..2e1b77fe0a3c9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "243bbfba7578f2084615fa0c092f87a8", + "content-hash": "4f2fd2e8ffcc003e0a4a4116ec84b780", "packages": [ { "name": "braintree/braintree_php", From ce025fba563445590da3ca6f4d4d6caa5692ff34 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Wed, 14 Nov 2018 16:22:55 +0200 Subject: [PATCH 1210/1415] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- app/code/Magento/WishlistGraphQl/composer.json | 1 + composer.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index 9226ea1754e6a..e0f342174f879 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -6,6 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-catalog": "*", + "magento/module-catalog-graph-ql": "*", "magento/module-wishlist": "*", "magento/module-store": "*" }, diff --git a/composer.lock b/composer.lock index d4ac4fc091bbc..bbc15bd96073b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "78153b5c8150c0d145b3372a534a45eb", + "content-hash": "18b533cc6fd96cad7b777d61edf94bd4", "packages": [ { "name": "braintree/braintree_php", From 4c236e7e5134805ee1194a2809cc3f1ddf537cf8 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 13 Nov 2018 17:11:34 +0200 Subject: [PATCH 1211/1415] ENGCOM-3243: Fixed static test. --- .../testsuite/Magento/Framework/Interception/AbstractPlugin.php | 2 ++ .../Magento/Framework/Interception/Config/CacheManagerTest.php | 2 +- lib/internal/Magento/Framework/Interception/Config/Config.php | 2 +- .../src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php index 2a34f18fb0a0d..281a038a5a9a9 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/AbstractPlugin.php @@ -56,6 +56,8 @@ public function tearDown() /** * Set up Interception Config + * + * @param array $pluginConfig */ public function setUpInterceptionConfig($pluginConfig) { diff --git a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php index 6b0487d4afdae..75737f0147274 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Interception/Config/CacheManagerTest.php @@ -40,7 +40,7 @@ protected function setUp() $this->serializer = $this->objectManager->get(\Magento\Framework\Serialize\SerializerInterface::class); $this->cache = $this->objectManager->get(\Magento\Framework\App\CacheInterface::class); - $this->configWriter = + $this->configWriter = $this->objectManager->get(\Magento\Framework\App\ObjectManager\ConfigWriter\Filesystem::class); $this->initializeMetadataDirectory(); diff --git a/lib/internal/Magento/Framework/Interception/Config/Config.php b/lib/internal/Magento/Framework/Interception/Config/Config.php index 7632970705fff..3f16e9275bd08 100644 --- a/lib/internal/Magento/Framework/Interception/Config/Config.php +++ b/lib/internal/Magento/Framework/Interception/Config/Config.php @@ -113,7 +113,7 @@ public function __construct( $this->_cacheId = $cacheId; $this->_reader = $reader; $this->_scopeList = $scopeList; - $this->cacheManager = + $this->cacheManager = $cacheManager ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CacheManager::class); $intercepted = $this->cacheManager->load($cacheId); if ($intercepted !== null) { diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php index fbdbc951462e4..69de120cca49e 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/AreaTest.php @@ -48,7 +48,7 @@ protected function setUp() $this->configReaderMock = $this->getMockBuilder(\Magento\Setup\Module\Di\Compiler\Config\Reader::class) ->disableOriginalConstructor() ->getMock(); - $this->configWriterMock = + $this->configWriterMock = $this->getMockBuilder(\Magento\Framework\App\ObjectManager\ConfigWriterInterface::class) ->disableOriginalConstructor() ->getMock(); From ee50fcbca5726e4fbb120e72749e7ec9b7c45c50 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 14 Nov 2018 17:13:20 +0200 Subject: [PATCH 1212/1415] ENGCOM-3449: Fixed static test. --- .../Model/ResourceModel/Db/Collection/AbstractCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php index 6e1ea24a61a4a..8ec47ed97e11c 100644 --- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php +++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractCollection.php @@ -177,7 +177,7 @@ public function setMainTable($table) } /** - * {@inheritdoc} + * @inheritdoc */ protected function _initSelect() { From e90bc28be176ec24b027ba05e4d74882738ac1c9 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Wed, 14 Nov 2018 17:41:44 +0200 Subject: [PATCH 1213/1415] Fix static analysis errors --- app/code/Magento/Ui/view/base/web/js/grid/massactions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js index 2e87e00fecda9..f26ca8697c2ff 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/massactions.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/massactions.js @@ -153,9 +153,9 @@ define([ var itemsType = data.excludeMode ? 'excluded' : 'selected', selections = {}; - if (itemsType === 'excluded' && data['selected'].length){ - data['selected'] = _.difference(data['selected'], data['excluded']); + if (itemsType === 'excluded' && data.selected && data.selected.length) { itemsType = 'selected'; + data[itemsType] = _.difference(data.selected, data.excluded); } selections[itemsType] = data[itemsType]; From ec040afdb5692c435d58c70914471b64216f7059 Mon Sep 17 00:00:00 2001 From: Alexandre Jardin <info@ajardin.fr> Date: Wed, 14 Nov 2018 16:35:10 +0100 Subject: [PATCH 1214/1415] Fix dependency between Elasticsearch configuration fields --- app/code/Magento/Elasticsearch/etc/adminhtml/system.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Elasticsearch/etc/adminhtml/system.xml b/app/code/Magento/Elasticsearch/etc/adminhtml/system.xml index b9fddc46f78ec..dd42b408ff75e 100644 --- a/app/code/Magento/Elasticsearch/etc/adminhtml/system.xml +++ b/app/code/Magento/Elasticsearch/etc/adminhtml/system.xml @@ -92,15 +92,15 @@ <field id="elasticsearch5_username" translate="label" type="text" sortOrder="65" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch HTTP Username</label> <depends> - <field id="elasticsearch_enable_auth">1</field> <field id="engine">elasticsearch5</field> + <field id="elasticsearch5_enable_auth">1</field> </depends> </field> <field id="elasticsearch5_password" translate="label" type="text" sortOrder="66" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Elasticsearch HTTP Password</label> <depends> - <field id="elasticsearch_enable_auth">1</field> <field id="engine">elasticsearch5</field> + <field id="elasticsearch5_enable_auth">1</field> </depends> </field> <field id="elasticsearch5_server_timeout" translate="label" type="text" sortOrder="67" showInDefault="1" showInWebsite="0" showInStore="0"> From 9b3fe43f891d174ed00b7dd31306d3ef71a6c7dd Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 12 Nov 2018 14:00:10 -0600 Subject: [PATCH 1215/1415] MC-5595: Magento\FunctionalTestingFramework.functional.StorefrontTaxQuoteCartLoggedInSimple fails randomly unskip mftf test --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 0b2809dfc3543..0326a4cadb537 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MC-295"/> <group value="Tax"/> - <skip> - <issueId value="MAGETWO-96194"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From b47df3b1f3df6ae2cb53c5f1d1b18b090386d642 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 14 Nov 2018 11:31:10 -0600 Subject: [PATCH 1216/1415] MC-5595: Magento\FunctionalTestingFramework.functional.StorefrontTaxQuoteCartLoggedInSimple fails randomly - add wait for correct shipping amount --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 0326a4cadb537..a41f00c547a9a 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -94,6 +94,7 @@ <waitForPageLoad stepKey="waitForCart"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <waitForElementVisible stepKey="waitForCorrectShippingAmount" selector="{{CheckoutPaymentSection.orderSummaryShippingTotal}}[text()='$5.00']"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> From 0266f59a2d7a4a75bb27804f5f5eebfadeb46919 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Wed, 14 Nov 2018 13:32:44 -0600 Subject: [PATCH 1217/1415] MAGETWO-95892: Selecting Gift Options for items redirects on 404 Page - Resolve static test failures --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index be84dcd76bb88..5727447b3a527 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -10,6 +9,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\Action\HttpGetActionInterface; +/** + * Class UpdatePost + */ class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface, HttpGetActionInterface { /** From 31adbdbfa226f96fb1e98353645a206cc8e15c43 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 14 Nov 2018 15:00:47 -0600 Subject: [PATCH 1218/1415] MC-5538: Search terms are not cached in case of form_key present in the request --- .../Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml | 1 + lib/web/mage/common.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml index 7ca86b8b14a4d..387a7547f4daf 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml @@ -15,6 +15,7 @@ </arguments> <submitForm selector="#search_mini_form" parameterArray="['q' => '{{phrase}}']" stepKey="fillQuickSearch" /> <seeInCurrentUrl url="{{StorefrontCatalogSearchPage.url}}" stepKey="checkUrl"/> + <dontSeeInCurrentUrl url="form_key=" stepKey="checkUrlFormKey"/> <seeInTitle userInput="Search results for: '{{phrase}}'" stepKey="assertQuickSearchTitle"/> <see userInput="Search results for: '{{phrase}}'" selector="{{StorefrontCatalogSearchMainSection.SearchTitle}}" stepKey="assertQuickSearchName"/> </actionGroup> diff --git a/lib/web/mage/common.js b/lib/web/mage/common.js index 4742c77ea8627..01f696ec1b7fc 100644 --- a/lib/web/mage/common.js +++ b/lib/web/mage/common.js @@ -21,7 +21,7 @@ define([ form = $(e.target), formKey = $('input[name="form_key"]').val(); - if (formKey && !form.find('input[name="form_key"]').length) { + if (formKey && !form.find('input[name="form_key"]').length && form[0].method !== 'get') { formKeyElement = document.createElement('input'); formKeyElement.setAttribute('type', 'hidden'); formKeyElement.setAttribute('name', 'form_key'); From 0a12f2facafd2eaea06a208173cf1e564e107a19 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 14 Nov 2018 18:00:59 -0600 Subject: [PATCH 1219/1415] ENGCOM-3450: [Forwardport] Fixed tierprice discount not calculated correctly if has specialprice #19179 --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 23b2dfa01bfbd..e346c912dccaa 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -13,6 +13,9 @@ use Magento\Catalog\Model\Attribute\ScopeOverriddenValue; +/** + * Backend model for Tierprice attribute + */ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPrice\AbstractGroupPrice { /** @@ -186,6 +189,10 @@ protected function modifyPriceData($object, $data) } /** + * Update Price values in DB + * + * Updates price values in DB from array comparing to old values. Returns bool if updated + * * @param array $valuesToUpdate * @param array $oldValues * @return boolean From 03f0861a1be43c9d283c64ad31b804b715997d3a Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 15 Nov 2018 16:03:08 +0300 Subject: [PATCH 1220/1415] MAGETWO-71022: After return "RMA" is complete in Admin, "remaining quantity" in customer account shows incorrect value - Stabilize test --- .../Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml index 00f290cd94e70..11d973d1e19de 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml @@ -13,6 +13,6 @@ <element name="email" type="input" selector="#email"/> <element name="requiredGroup" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-group-id']"/> <element name="requiredEmail" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-email']"/> - <element name="defaultGeneral" type="text" selector="//*[text()='Default (General)']" time="15"/> + <element name="defaultGeneral" type="text" selector="//*[contains(text(),'General')]" time="15"/> </section> </sections> \ No newline at end of file From f8cbd49653e93a17a7d9a3997f0ea8d5b79aa48f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 15:14:41 +0200 Subject: [PATCH 1221/1415] GraphQL-43: [Query] My Account > My Wish List --- .../Magento/WishlistGraphQl/composer.json | 1 - .../WishlistGraphQl/etc/schema.graphqls | 20 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index e0f342174f879..630ee97acc2eb 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -5,7 +5,6 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-catalog": "*", "magento/module-catalog-graph-ql": "*", "magento/module-wishlist": "*", "magento/module-store": "*" diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index a63ec6eff6f5b..f5b5034fb734f 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -2,21 +2,21 @@ # See COPYING.txt for license details. type Query { - wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "todo") + wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish list") } type WishlistOutput { - items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), - items_count: Int @doc(description: "todo"), - name: String @doc(description: "todo"), - sharing_code: String @doc(description: "todo"), - updated_at: String @doc(description: "todo") + items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "An array of items in the customer's wish list"), + items_count: Int @doc(description: "The number of items in the wish list"), + name: String @doc(description: "When multiple wish lists are enabled, the name the customer assigns to the wishlist"), + sharing_code: String @doc(description: "An encrypted code that Magento uses to link to the wish list"), + updated_at: String @doc(description: "The time of the last modification to the wish list") } type WishlistItem { - id: Int @doc(description: "todo") - qty: Float @doc(description: "todo"), - description: String @doc(description: "todo"), - added_at: String @doc(description: "todo"), + id: Int @doc(description: "The wish list item ID") + qty: Float @doc(description: "The quantity of this wish list item"), + description: String @doc(description: "The customer's comment about this item"), + added_at: String @doc(description: "The time when the customer added the item to the wish list"), product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver") } \ No newline at end of file From 31797246faf847433f9353ec61375f3adb51e531 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 15:29:20 +0200 Subject: [PATCH 1222/1415] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 7ce9efeb65e6f..0af9477ff4ef9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "243bbfba7578f2084615fa0c092f87a8", + "content-hash": "b367db394f87f9f9006b40e36e5a4175", "packages": [ { "name": "braintree/braintree_php", From 52c5fba5b765dec8582ea527ce745fe77b7d2634 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 15 Nov 2018 13:24:42 +0300 Subject: [PATCH 1223/1415] MAGETWO-91496: Instantiating WYSIWYG in DynamicRows - Create parameter for suffix adding --- .../Magento/Ui/view/base/web/js/form/element/wysiwyg.js | 8 ++++++++ .../Magento/Framework/Data/Form/Element/Editor.php | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 235113b389fc7..070761fff53e3 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -80,6 +80,14 @@ define([ return config.name.replace(/(\.|-)/g, '_'); }, + /** + * @inheritdoc + */ + destroy: function () { + this._super(); + wysiwyg.removeEvents(this.wysiwygId); + }, + /** * * @returns {exports} diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php index dee0b6c842f5f..b5f2017501c01 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php @@ -548,6 +548,7 @@ protected function getInlineJs($jsSetupObject, $forceLoad) */ public function getHtmlId() { - return parent::getHtmlId() . '${ $.wysiwygUniqueSuffix }'; + $suffix = $this->getConfig('dynamic_id') ? '${ $.wysiwygUniqueSuffix }' : ''; + return parent::getHtmlId() . $suffix; } } From adda7da9743ef8eb90f1d060e72d65bcdc7d0b40 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 15 Nov 2018 08:59:26 -0600 Subject: [PATCH 1224/1415] Revert "MQE-1267: Unskip Timezone Tests in Magento 2.3" - This reverts commit 0e0c110 --- .../Test/AdminApplyCatalogRuleByCategoryTest.xml | 3 +++ .../Mftf/Test/AdminCreateCatalogPriceRuleTest.xml | 15 +++++++++++++++ .../Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml | 3 +++ .../Test/StorefrontInactiveCatalogRuleTest.xml | 3 +++ 4 files changed, 24 insertions(+) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml index 741da96179b8c..716a363ec5d78 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml @@ -16,6 +16,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-74"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategoryOne"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml index befe0b0ce7f98..072385c46645a 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-65"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <!-- Create the simple product and category that it will be in --> @@ -74,6 +77,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-93"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -97,6 +103,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-69"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -120,6 +129,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-60"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -143,6 +155,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-71"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <!-- Create a simple product and a category--> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml index d3546d06492be..83770ffff5eab 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-160"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index e7be6e8443a36..55f775e40feaa 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-79"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="login"/> From db851ff49c3e8e6c49dce7d10c0a56a57020f9c4 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 17:35:20 +0200 Subject: [PATCH 1225/1415] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 2e1b77fe0a3c9..36b4dca023191 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f2fd2e8ffcc003e0a4a4116ec84b780", + "content-hash": "7538e15ea4ff1378cf55983ce9acba82", "packages": [ { "name": "braintree/braintree_php", From 0154cf538f0129ab3578bb0506ee9c820baf505b Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 15 Nov 2018 09:51:20 -0600 Subject: [PATCH 1226/1415] MC-5535: Numbers mismatch between the products displayed and the product count on Category structure - Fixed condition and added assertions --- .../Catalog/Model/ResourceModel/Category/Collection.php | 6 +----- ...AdminFilteringCategoryProductsUsingScopeSelectorTest.xml | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php index 46bb74513b59c..4562aa0b0e75f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php @@ -322,11 +322,7 @@ public function loadProductCount($items, $countRegular = true, $countAnchor = tr ['e' => $this->getTable('catalog_category_entity')], 'main_table.category_id=e.entity_id', [] - )->where( - 'e.entity_id = :entity_id' - )->orWhere( - 'e.path LIKE :c_path' - ); + )->where('e.entity_id = :entity_id OR e.path LIKE :c_path'); if ($websiteId) { $select->join( ['w' => $this->getProductWebsiteTable()], diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index a748635ac9a53..9e323745835c2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -140,6 +140,7 @@ userInput="$$createProduct1.name$$" stepKey="seeProductName4"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" userInput="$$createProduct12.name$$" stepKey="seeProductName5"/> + <waitForText userInput="$$createCategory.name$$ (2)" stepKey="seeCorrectProductCount"/> <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}" userInput="$$createProduct0.name$$" stepKey="dontSeeProductName"/> <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" @@ -164,6 +165,7 @@ userInput="$$createProduct2.name$$" stepKey="seeProductName6"/> <see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}" userInput="$$createProduct12.name$$" stepKey="seeProductName7"/> + <waitForText userInput="$$createCategory.name$$ (2)" stepKey="seeCorrectProductCount2"/> <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}" userInput="$$createProduct0.name$$" stepKey="dontSeeProductName2"/> <dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}" From a0a150fce54acdbb6fc8fc85820972cd33ebdaa9 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 15 Nov 2018 12:00:53 -0600 Subject: [PATCH 1227/1415] #2340: Fixed static tests --- .../Magento/Bundle/Model/OptionRepository.php | 20 +++++++++++++------ .../Test/Unit/Model/OptionRepositoryTest.php | 3 ++- .../product_grouped_with_out_of_stock.php | 2 +- ...uct_grouped_with_out_of_stock_rollback.php | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index 46c44c83b5bb5..0b96ea8d5b789 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -90,7 +90,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($sku, $optionId) { @@ -123,7 +123,7 @@ public function get($sku, $optionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { @@ -132,6 +132,8 @@ public function getList($sku) } /** + * Return list of product options + * * @param ProductInterface $product * @return \Magento\Bundle\Api\Data\OptionInterface[] */ @@ -141,7 +143,7 @@ public function getListByProduct(ProductInterface $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) { @@ -157,7 +159,7 @@ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($sku, $optionId) { @@ -169,7 +171,7 @@ public function deleteById($sku, $optionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function save( \Magento\Catalog\Api\Data\ProductInterface $product, @@ -189,6 +191,9 @@ public function save( * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param \Magento\Bundle\Api\Data\OptionInterface $option * @return $this + * @throws InputException + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\CouldNotSaveException */ protected function updateOptionSelection( \Magento\Catalog\Api\Data\ProductInterface $product, @@ -228,9 +233,12 @@ protected function updateOptionSelection( } /** + * Retrieve product by SKU + * * @param string $sku * @return \Magento\Catalog\Api\Data\ProductInterface - * @throws \Magento\Framework\Exception\InputException + * @throws InputException + * @throws NoSuchEntityException */ private function getProduct($sku) { diff --git a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php index c579d8289d1b6..2450f63c38933 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php @@ -280,7 +280,8 @@ public function testDeleteById() /** * Tests if NoSuchEntityException thrown when provided $optionId not found */ - public function testDeleteByIdException() { + public function testDeleteByIdException() + { $productSku = 'sku'; $optionId = null; diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php index 7aa62b149b8c0..369ce7d490eea 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php @@ -1,4 +1,4 @@ -\<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php index 48e7d495f8985..26a7487077e44 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php @@ -1,4 +1,4 @@ -\<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. From 5ef851a596363d40ed259d10f10299a43b6891bf Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 16 Nov 2018 10:30:35 +0200 Subject: [PATCH 1228/1415] =?UTF-8?q?ENGCOM-3435:=2019082-Fatal-error-Unca?= =?UTF-8?q?ught-Error-Cannot-call-abstract-method-Magento-=E2=80=A6=20#191?= =?UTF-8?q?55=20Fix=20static=20tests.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Magento/Catalog/Controller/Product/Compare.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php index 63478080bce1a..084a82f87d645 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Controller\Product; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\View\Result\PageFactory; @@ -15,7 +16,7 @@ * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -abstract class Compare extends \Magento\Framework\App\Action\Action +abstract class Compare extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface { /** * Customer id @@ -141,11 +142,13 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function execute() { - return $this->_redirect('catalog/product_compare'); - } + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('catalog/product_compare'); + return $resultRedirect; + } } From b7c25f3f60649c7f4f2f47e46d13a6f94aba552f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 16:23:12 +0200 Subject: [PATCH 1229/1415] GraphQL-43: [Query] My Account > My Wish List -- Fix static tests --- .../WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php | 2 ++ app/code/Magento/WishlistGraphQl/registration.php | 1 + 2 files changed, 3 insertions(+) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 033c63441e907..dfbbf6543f66f 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -77,6 +77,8 @@ public function resolve( } /** + * Get wishlist items + * * @param Wishlist $wishlist * @return Item[] */ diff --git a/app/code/Magento/WishlistGraphQl/registration.php b/app/code/Magento/WishlistGraphQl/registration.php index f2047f225e5b6..c5d468421f96e 100644 --- a/app/code/Magento/WishlistGraphQl/registration.php +++ b/app/code/Magento/WishlistGraphQl/registration.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; From 5ff88c0854d7683fbf7bfa74ae464b74fa79de7d Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 16 Nov 2018 11:01:44 -0400 Subject: [PATCH 1230/1415] Removed PHPMD suppress warning directive --- app/code/Magento/DownloadableImportExport/Helper/Uploader.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php index de10bcea5d61e..197250faaea91 100644 --- a/app/code/Magento/DownloadableImportExport/Helper/Uploader.php +++ b/app/code/Magento/DownloadableImportExport/Helper/Uploader.php @@ -51,8 +51,6 @@ class Uploader extends \Magento\Framework\App\Helper\AbstractHelper * @param \Magento\CatalogImportExport\Model\Import\UploaderFactory $uploaderFactory * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Framework\Filesystem $filesystem - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Framework\App\Helper\Context $context, From 6a68a187e972b1e241e55153b0ba2a1483255f92 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 16 Nov 2018 10:30:31 -0600 Subject: [PATCH 1231/1415] ENGCOM-3291: Set cache id prefix on installation #18641 - fixed docblock --- setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php index 85c0e2c4e9b3b..173064b472217 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Cache.php @@ -79,7 +79,7 @@ public function __construct(RedisConnectionValidator $redisValidator) } /** - * {@inheritdoc} + * @inheritdoc */ public function getOptions() { From 3ccd55e308823f8342c0503ab90af11b91c26f61 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 16 Nov 2018 10:30:59 -0600 Subject: [PATCH 1232/1415] ENGCOM-3291: Set cache id prefix on installation #18641 - fixed docblock --- setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php index 35a9955aad506..7451b59356828 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/PageCache.php @@ -83,7 +83,7 @@ public function __construct(RedisConnectionValidator $redisValidator) } /** - * {@inheritdoc} + * @inheritdoc */ public function getOptions() { From 370aaebbd95045ed4aaefa37592e4abf12869215 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 18:31:05 +0200 Subject: [PATCH 1233/1415] GraphQL-43: [Query] My Account > My Wish List -- Fix API-functional tests --- .../Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php index b59582a189f60..65c8498fc89ad 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php @@ -48,6 +48,6 @@ public function resolve( /** @var Item $wishlistItem */ $wishlistItem = $value['model']; - return $this->productDataProvider->getProductDataById($wishlistItem->getProductId()); + return $this->productDataProvider->getProductDataById((int)$wishlistItem->getProductId()); } } From f14949c840286e75199d9696377f65995fd69278 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 16 Nov 2018 10:31:38 -0600 Subject: [PATCH 1234/1415] ENGCOM-3291: Set cache id prefix on installation #18641 - fixed static test --- .../Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php index d804266096f7b..1cf3937f98684 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsList/PageCacheTest.php @@ -164,7 +164,6 @@ public function testCreateConfigWithFileCache() $this->assertEquals($expectedConfigData, $configData->getData()); } - /** * testCreateConfigCacheRedis */ From 571af253e06151ab02e570495b485560211e06c7 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 16 Nov 2018 18:49:33 +0200 Subject: [PATCH 1235/1415] MAGETWO-93425: Permanent Redirect for old URL missing via API or no documentation --- .../Controller/Rest/InputParamsResolver.php | 87 +++++++++++++ .../Rest/InputParamsResolverTest.php | 116 ++++++++++++++++++ .../CatalogUrlRewrite/etc/webapi_rest/di.xml | 3 + 3 files changed, 206 insertions(+) create mode 100644 app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php new file mode 100644 index 0000000000000..5d1eff81874be --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Webapi\Rest\Request as RestRequest; + +/** + * Plugin for InputParamsResolver + * + * Used to modify product data with save_rewrites_history flag + */ +class InputParamsResolver +{ + /** + * @var RestRequest + */ + private $request; + + /** + * @param RestRequest $request + */ + public function __construct(RestRequest $request) { + $this->request = $request; + } + + /** + * Add 'save_rewrites_history' param to the product data + * + * @see \Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization\Helper + * @param \Magento\Webapi\Controller\Rest\InputParamsResolver $subject + * @param array $result + * @return array + */ + public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver $subject, array $result): array + { + $route = $subject->getRoute(); + $serviceMethodName = $route->getServiceMethod(); + $serviceClassName = $route->getServiceClass(); + $requestBodyParams = $this->request->getBodyParams(); + + if ($this->isProductSaveCalled($serviceClassName, $serviceMethodName) + && $this->isCustomOptionExists($requestBodyParams)) { + + foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) { + if ($attribute['attribute_code'] === 'save_rewrites_history') { + foreach ($result as $resultItem) { + if ($resultItem instanceof \Magento\Catalog\Model\Product) { + $resultItem->setData('save_rewrites_history', (bool)$attribute['value']); + break 2; + } + } + } + } + } + return $result; + } + + /** + * Check that product save method called + * + * @param string $serviceClassName + * @param string $serviceMethodName + * @return bool + */ + private function isProductSaveCalled(string $serviceClassName, string $serviceMethodName): bool + { + return $serviceClassName === ProductRepositoryInterface::class && $serviceMethodName === 'save'; + } + + /** + * Check is any custom options exists in product data + * + * @param array $requestBodyParams + * @return bool + */ + private function isCustomOptionExists(array $requestBodyParams): bool + { + return !empty($requestBodyParams['product']['custom_attributes']); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php new file mode 100644 index 0000000000000..8e705b2c09f6b --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php @@ -0,0 +1,116 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogUrlRewrite\Test\Unit\Plugin\Webapi\Controller\Rest; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Webapi\Controller\Rest\InputParamsResolver; +use Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest\InputParamsResolver as InputParamsResolverPlugin; +use Magento\Framework\Webapi\Rest\Request as RestRequest; +use Magento\Catalog\Model\Product; +use Magento\Webapi\Controller\Rest\Router\Route; +use Magento\Catalog\Api\ProductRepositoryInterface; + +/** + * Unit test for InputParamsResolver plugin + */ +class InputParamsResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var string + */ + private $saveRewritesHistory; + + /** + * @var array + */ + private $requestBodyParams; + + /** + * @var array + */ + private $result; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var InputParamsResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $subject; + + /** + * @var RestRequest|\PHPUnit_Framework_MockObject_MockObject + */ + private $request; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var Route|\PHPUnit_Framework_MockObject_MockObject + */ + private $route; + + /** + * @var InputParamsResolverPlugin + */ + private $plugin; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->saveRewritesHistory = 'save_rewrites_history'; + $this->requestBodyParams = [ + 'product' => [ + 'sku' => 'test', + 'custom_attributes' => [ + ['attribute_code' => $this->saveRewritesHistory, 'value' => 1] + ] + ] + ]; + + $this->route = $this->createPartialMock(Route::class, ['getServiceMethod', 'getServiceClass']); + $this->request = $this->createPartialMock(RestRequest::class, ['getBodyParams']); + $this->request->expects($this->any())->method('getBodyParams')->willReturn($this->requestBodyParams); + $this->subject = $this->createPartialMock(InputParamsResolver::class, ['getRoute']); + $this->subject->expects($this->any())->method('getRoute')->willReturn($this->route); + $this->product = $this->createPartialMock(Product::class, ['setData']); + + $this->result = [false, $this->product, 'test']; + + $this->objectManager = new ObjectManager($this); + $this->plugin = $this->objectManager->getObject( + InputParamsResolverPlugin::class, + [ + 'request' => $this->request + ] + ); + } + + public function testAfterResolve() + { + $this->route->expects($this->once()) + ->method('getServiceClass') + ->willReturn(ProductRepositoryInterface::class); + $this->route->expects($this->once()) + ->method('getServiceMethod') + ->willReturn('save'); + $this->product->expects($this->once()) + ->method('setData') + ->with($this->saveRewritesHistory, true); + + $this->plugin->afterResolve($this->subject, $this->result); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml index ac8beb362f0fb..34b7487725d76 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml @@ -7,4 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/> + <type name="Magento\Webapi\Controller\Rest\InputParamsResolver"> + <plugin name="product_save_rewrites_history_rest_plugin" type="Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest\InputParamsResolver" sortOrder="1" disabled="false" /> + </type> </config> From 0d58352a7924ba28c0ba159f5b806048dea974f8 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 19:12:46 +0200 Subject: [PATCH 1236/1415] GraphQL-115: Travis api-functional tests automated execution introduced --- dev/travis/before_script.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 9f1edbf6c8a50..5d091efbb30a3 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,17 +152,17 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" - echo "Enabling production mode" - php bin/magento deploy:mode:set production - echo "Prepare api-functional tests for running" cd dev/tests/api-functional - cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests + cp -r _files/Magento/TestModuleGraphQl* ../../../app/code/Magento # Deploy and enable test modules before running tests cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml cd ../../.. php bin/magento setup:upgrade + + echo "Enabling production mode" + php bin/magento deploy:mode:set production ;; esac From cbacef5774ccf7fd1aa27b722abf0b8be508aa75 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 16 Nov 2018 14:20:23 -0600 Subject: [PATCH 1237/1415] MC-5595: Magento\FunctionalTestingFramework.functional.StorefrontTaxQuoteCartLoggedInSimple fails randomly - change waitForElementVisible to waitForText --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index af6545c6c4b58..73e018ec83161 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -95,7 +95,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> - <waitForElementVisible stepKey="waitForCorrectShippingAmount" selector="{{CheckoutPaymentSection.orderSummaryShippingTotal}}[text()='$5.00']"/> + <waitForText userInput="$5.00" selector="{{CheckoutPaymentSection.orderSummaryShippingTotal}}" time="30" stepKey="waitForCorrectShippingAmount"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> From e56232cb19eb29b496a2e37a7987f56d0101bbc4 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 16 Nov 2018 16:01:02 -0600 Subject: [PATCH 1238/1415] MC-5650: Custom customer address attributes not displayed on Shipping or billing address form - Added selector --- .../Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 70bb0532222a4..3dcf399c9ad54 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -13,6 +13,7 @@ <element name="availablePaymentSolutions" type="text" selector="#checkout-payment-method-load>div>div>div:nth-child(2)>div.payment-method-title.field.choice"/> <element name="notAvailablePaymentSolutions" type="text" selector="#checkout-payment-method-load>div>div>div.payment-method._active>div.payment-method-title.field.choice"/> <element name="billingNewAddressForm" type="text" selector="[data-form='billing-new-address']"/> + <element name="billingAddressNotSameCheckbox" type="checkbox" selector="#billing-address-same-as-shipping-checkmo"/> <element name="placeOrderDisabled" type="button" selector="#checkout-payment-method-load button.disabled"/> <element name="update" type="button" selector=".payment-method-billing-address .action.action-update"/> <element name="guestFirstName" type="input" selector=".billing-address-form input[name*='firstname']"/> From 46d533e97bdd2c05560bf51f1ca0ed1b47a347ff Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sun, 2 Sep 2018 16:11:02 +0200 Subject: [PATCH 1239/1415] Fixed child items showing on My Account order view --- app/code/Magento/Sales/Block/Order/Items.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Block/Order/Items.php b/app/code/Magento/Sales/Block/Order/Items.php index 028544cd56219..0b67e9a0746d3 100644 --- a/app/code/Magento/Sales/Block/Order/Items.php +++ b/app/code/Magento/Sales/Block/Order/Items.php @@ -71,7 +71,6 @@ protected function _prepareLayout() $this->itemCollection = $this->itemCollectionFactory->create(); $this->itemCollection->setOrderFilter($this->getOrder()); - $this->itemCollection->filterByParent(null); /** @var \Magento\Theme\Block\Html\Pager $pagerBlock */ $pagerBlock = $this->getChildBlock('sales_order_item_pager'); From b9790c67d25af83e8cbaecad223c4317d4337e8d Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Sun, 18 Nov 2018 11:50:50 +0200 Subject: [PATCH 1240/1415] Fixed code style issues --- app/code/Magento/Review/Model/ResourceModel/Rating.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 04dce420ae522..9cd9b0650a278 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -425,7 +425,7 @@ public function getReviewSummary($object, $onlyForCurrentStore = true) $data = $connection->fetchAll($select, [':review_id' => $object->getReviewId()]); - $currentStore = ($this->_storeManager->isSingleStoreMode()) ? $this->_storeManager->getStore()->getId() : null ; + $currentStore = $this->_storeManager->isSingleStoreMode() ? $this->_storeManager->getStore()->getId() : null; if ($onlyForCurrentStore) { foreach ($data as $row) { From 9dfe1372ce941a36b700efe1dbb4851ea5bc3520 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 18 Nov 2018 17:31:34 +0530 Subject: [PATCH 1241/1415] issue #19205 fixed for 2.3-develop --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index b61df8d7cb125..e5755df2291ee 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -827,7 +827,7 @@ private function multiToFlatArray(array $array) if (is_array($value)) { $flatArray = array_merge($flatArray, $this->multiToFlatArray($value)); } else { - $flatArray[$key] = $value; + $flatArray[] = $value; } } From eb2e505c68b1ed24ccc7d45e4a7eb4c2b0216f23 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 18 Nov 2018 18:57:14 +0530 Subject: [PATCH 1242/1415] removed unused variable --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index e5755df2291ee..c8cd8c15fdb8e 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -823,7 +823,7 @@ private function recursiveIntval(array $array) private function multiToFlatArray(array $array) { $flatArray = []; - foreach ($array as $key => $value) { + foreach ($array as $value) { if (is_array($value)) { $flatArray = array_merge($flatArray, $this->multiToFlatArray($value)); } else { From 62bc03fa15aea7d0ca9021cbffb52abf574cd636 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 18 Nov 2018 17:19:20 +0200 Subject: [PATCH 1243/1415] Fix the issue: Content overlaps the "close" button #19263 --- lib/web/css/source/components/_modals.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/web/css/source/components/_modals.less b/lib/web/css/source/components/_modals.less index fb29a74c60585..a8e8cebde3a6c 100644 --- a/lib/web/css/source/components/_modals.less +++ b/lib/web/css/source/components/_modals.less @@ -103,6 +103,10 @@ &.confirm { .modal-inner-wrap { .lib-css(width, @modal-popup-confirm__width); + + .modal-content { + padding-right: 7rem; + } } } From 176b303b509953f84278614249c4b3559105c579 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Mon, 19 Nov 2018 09:21:15 +0200 Subject: [PATCH 1244/1415] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../web/js/model/shipping-rates-validator.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index ca11fec7cd5a0..b53be1a40f30a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -35,6 +35,7 @@ define([ var checkoutConfig = window.checkoutConfig, validators = [], observedElements = [], + postcodeElements = [], postcodeElementName = 'postcode'; validators.push(defaultValidator); @@ -78,11 +79,7 @@ define([ } $.each(elements, function (index, field) { - var elementBinding = self.doElementBinding.bind(self), - fullPath = formPath + '.' + field, - func = uiRegistry.async(fullPath); - - func(elementBinding); + uiRegistry.async(formPath + '.' + field)(self.doElementBinding.bind(self)); }); }, @@ -104,6 +101,7 @@ define([ if (element.index === postcodeElementName) { this.bindHandler(element, delay); + postcodeElements.push(element); } }, @@ -138,7 +136,13 @@ define([ if (!formPopUpState.isVisible()) { clearTimeout(self.validateAddressTimeout); self.validateAddressTimeout = setTimeout(function () { - self.postcodeValidation(element); + if (element.index === postcodeElementName) { + self.postcodeValidation(element); + } else { + $.each(postcodeElements, function (index, elem) { + self.postcodeValidation(elem); + }); + } self.validateFields(); }, delay); } @@ -151,7 +155,7 @@ define([ * @return {*} */ postcodeValidation: function (postcodeElement) { - var countryId = $('select[name="country_id"]').val(), + var countryId = $('#checkoutSteps > :visible select[name="country_id"]').val(), validationResult, warnMessage; From 740c0c60df1346a53ac84501dea447244bf1531a Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 19 Nov 2018 11:02:15 +0200 Subject: [PATCH 1245/1415] MAGETWO-93425: Permanent Redirect for old URL missing via API or no documentation --- app/code/Magento/CatalogUrlRewrite/composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index e373d8c8c1756..b4ceff96b50b7 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -16,6 +16,9 @@ "magento/module-ui": "*", "magento/module-url-rewrite": "*" }, + "suggest": { + "magento/module-webapi": "*" + }, "type": "magento2-module", "license": [ "OSL-3.0", From cb466f1df4bd6a513ec3f565431794c72fd281f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 19 Nov 2018 11:04:59 +0200 Subject: [PATCH 1246/1415] MAGETWO-93425: Permanent Redirect for old URL missing via API or no documentation --- .../Plugin/Webapi/Controller/Rest/InputParamsResolver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php index 5d1eff81874be..729c85fe858e2 100644 --- a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -26,7 +26,8 @@ class InputParamsResolver /** * @param RestRequest $request */ - public function __construct(RestRequest $request) { + public function __construct(RestRequest $request) + { $this->request = $request; } @@ -47,7 +48,6 @@ public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver if ($this->isProductSaveCalled($serviceClassName, $serviceMethodName) && $this->isCustomOptionExists($requestBodyParams)) { - foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) { if ($attribute['attribute_code'] === 'save_rewrites_history') { foreach ($result as $resultItem) { From 9e9c74c7b3b1e39112a5179da02db3948dc802c9 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Mon, 19 Nov 2018 12:24:14 +0200 Subject: [PATCH 1247/1415] Update _notifications.less --- .../css/source/module/header/actions-group/_notifications.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index 93fc0d3eb4948..ceeb8d8eeb2b3 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -103,7 +103,8 @@ padding: .3em .5em; position: absolute; top: 50%; - width: 18px; + min-width: 18px; + height: 18px; } } From 52fabb91d0b11dd15050cb5c14babe0a6950f686 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 19 Nov 2018 13:25:52 +0200 Subject: [PATCH 1248/1415] MAGETWO-93425: Permanent Redirect for old URL missing via API or no documentation --- .../Plugin/Webapi/Controller/Rest/InputParamsResolver.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php index 729c85fe858e2..4e8e3840693a5 100644 --- a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -47,7 +47,7 @@ public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver $requestBodyParams = $this->request->getBodyParams(); if ($this->isProductSaveCalled($serviceClassName, $serviceMethodName) - && $this->isCustomOptionExists($requestBodyParams)) { + && $this->isCustomAttributesExists($requestBodyParams)) { foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) { if ($attribute['attribute_code'] === 'save_rewrites_history') { foreach ($result as $resultItem) { @@ -56,6 +56,7 @@ public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver break 2; } } + break; } } } @@ -80,7 +81,7 @@ private function isProductSaveCalled(string $serviceClassName, string $serviceMe * @param array $requestBodyParams * @return bool */ - private function isCustomOptionExists(array $requestBodyParams): bool + private function isCustomAttributesExists(array $requestBodyParams): bool { return !empty($requestBodyParams['product']['custom_attributes']); } From 4694c061b74e2d4e5c169480de7e855c3abc0a85 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 14:52:29 +0200 Subject: [PATCH 1249/1415] GraphQL-39: Manage Shipping methods on Cart --- .../Model/Cart/SetShippingAddressOnCart.php | 30 ++++++++++--------- .../SetShippingAddressesOnCartInterface.php | 3 +- .../Resolver/SetShippingAddressesOnCart.php | 2 +- app/code/Magento/QuoteGraphQl/composer.json | 3 +- .../Quote/SetShippingAddressOnCartTest.php | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 960900682db4c..b9fd5c7807d2f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -7,9 +7,8 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Quote\Api\Data\CartInterface; @@ -37,19 +36,27 @@ class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface */ private $addressModel; + /** + * @var CheckCustomerAccount + */ + private $checkCustomerAccount; + /** * @param ShippingAddressManagementInterface $shippingAddressManagement * @param AddressRepositoryInterface $addressRepository * @param Address $addressModel + * @param CheckCustomerAccount $checkCustomerAccount */ public function __construct( ShippingAddressManagementInterface $shippingAddressManagement, AddressRepositoryInterface $addressRepository, - Address $addressModel + Address $addressModel, + CheckCustomerAccount $checkCustomerAccount ) { $this->shippingAddressManagement = $shippingAddressManagement; $this->addressRepository = $addressRepository; $this->addressModel = $addressModel; + $this->checkCustomerAccount = $checkCustomerAccount; } /** @@ -66,7 +73,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s $customerAddressId = $shippingAddress['customer_address_id'] ?? null; $addressInput = $shippingAddress['address'] ?? null; - if (!$customerAddressId && !$addressInput) { + if (null === $customerAddressId && null === $addressInput) { throw new GraphQlInputException( __('The shipping address must contain either "customer_address_id" or "address".') ); @@ -76,19 +83,14 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') ); } - if ($customerAddressId) { - if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { - throw new GraphQlAuthorizationException( - __( - 'Guest users cannot manage addresses.' - ) - ); - } + if (null === $customerAddressId) { + $shippingAddress = $this->addressModel->addData($addressInput); + } else { + $this->checkCustomerAccount->execute($context->getUserId(), $context->getUserType()); + /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); - } else { - $shippingAddress = $this->addressModel->addData($addressInput); } $this->shippingAddressManagement->assign($cart->getId(), $shippingAddress); diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index dde9cce9d8693..c5da3db75add7 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -15,11 +15,10 @@ * Extension point for setting shipping addresses for a specified shopping cart * * All objects that are responsible for setting shipping addresses on a cart via GraphQl - *should implement this interface. + * should implement this interface. */ interface SetShippingAddressesOnCartInterface { - /** * Set shipping addresses for a specified shopping cart * diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index 587ebb2b6db1f..b024e7b77af40 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -93,7 +93,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'cart' => [ 'cart_id' => $maskedCartId, - 'model' => $cart + 'model' => $cart, ] ]; } diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 9d29cda3b872b..881450745b84a 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,8 +9,7 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-customer": "*", - "magento/module-authorization": "*" + "magento/module-customer": "*" }, "suggest": { "magento/module-graph-ql": "*" diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 2b4223cf67a89..a023d37895c23 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -139,7 +139,7 @@ public function testSetSavedShippingAddressOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Guest users cannot manage addresses.'); + self::expectExceptionMessage('The current customer isn\'t authorized.'); $this->graphQlQuery($query); } From ac93407e2e12cc9d953574bc448e1830390de380 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:22:56 +0200 Subject: [PATCH 1250/1415] GraphQL-189: Replace GraphQlInputException on LocalizedException --- .../BundleGraphQl/Model/Resolver/BundleItemLinks.php | 4 ++-- .../BundleGraphQl/Model/Resolver/Options/Label.php | 4 ++-- .../Model/LayerFilterItemTypeResolverComposite.php | 6 ++---- .../Model/ProductLinkTypeResolverComposite.php | 8 ++------ .../Magento/CatalogGraphQl/Model/Resolver/Categories.php | 4 ++-- .../Model/Resolver/Category/Breadcrumbs.php | 4 ++-- .../Model/Resolver/Product/CanonicalUrl.php | 4 ++-- .../Model/Resolver/Product/EntityIdToId.php | 4 ++-- .../Model/Resolver/Product/MediaGalleryEntries.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/NewFromTo.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Options.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Price.php | 4 ++-- .../Resolver/Product/ProductComplexTextAttribute.php | 4 ++-- .../Model/Resolver/Product/ProductLinks.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/TierPrices.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Websites.php | 4 ++-- .../Model/Resolver/OnlyXLeftInStockResolver.php | 4 ++-- .../Model/Resolver/StockStatusProvider.php | 4 ++-- .../Model/Resolver/Product/DownloadableOptions.php | 4 ++-- .../EavGraphQl/Model/Resolver/AttributeOptions.php | 9 +++++---- .../Magento/EavGraphQl/Model/Resolver/Query/Type.php | 3 +-- app/code/Magento/GraphQl/Model/EntityAttributeList.php | 6 +++--- .../Model/Resolver/GroupedItems.php | 4 ++-- .../UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php | 4 ++-- 24 files changed, 51 insertions(+), 57 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index f55028a7d1a5b..184f7177a995c 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -7,7 +7,7 @@ namespace Magento\BundleGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\BundleGraphQl\Model\Resolver\Links\Collection; use Magento\Framework\GraphQl\Config\Element\Field; @@ -47,7 +47,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['option_id']) || !isset($value['parent_id'])) { - throw new GraphQlInputException(__('"option_id" and "parent_id" values should be specified')); + throw new LocalizedException(__('"option_id" and "parent_id" values should be specified')); } $this->linkCollection->addIdFilters((int)$value['option_id'], (int)$value['parent_id']); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php index bcddd5d084629..de72b18982c12 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php @@ -7,7 +7,7 @@ namespace Magento\BundleGraphQl\Model\Resolver\Options; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; @@ -50,7 +50,7 @@ public function resolve( array $args = null ) { if (!isset($value['sku'])) { - throw new GraphQlInputException(__('"sku" value should be specified')); + throw new LocalizedException(__('"sku" value should be specified')); } $this->product->addProductSku($value['sku']); diff --git a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php index e04b5d1bf67ff..02594ecfaf8e8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php @@ -31,7 +31,7 @@ public function __construct(array $typeResolvers = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function resolveType(array $data) : string { @@ -42,8 +42,6 @@ public function resolveType(array $data) : string return $resolvedType; } } - if (empty($resolvedType)) { - throw new \LogicException('Cannot resolve layered filter type'); - } + throw new GraphQlInputException(__('Cannot resolve layered filter type')); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index 5f6d1a65519f8..fbce18dfb67a5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -29,8 +29,7 @@ public function __construct(array $productLinksTypeNameResolvers = []) } /** - * {@inheritdoc} - * @throws GraphQlInputException + * @inheritdoc */ public function resolveType(array $data) : string { @@ -48,9 +47,6 @@ public function resolveType(array $data) : string return $resolvedType; } } - - if (!$resolvedType) { - throw new \LogicException('Cannot resolve type'); - } + throw new GraphQlInputException(__('Cannot resolve type')); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index de4c7dd71ca36..cb392a7b2295d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Catalog\Model\ResourceModel\Category\Collection; @@ -85,7 +85,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var \Magento\Catalog\Model\Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php index 9e966a060e5c6..b93c7e279153d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Category; use Magento\CatalogGraphQl\Model\Resolver\Category\DataProvider\Breadcrumbs as BreadcrumbsDataProvider; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -38,7 +38,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['path'])) { - throw new GraphQlInputException(__('"path" value should be specified')); + throw new LocalizedException(__('"path" value should be specified')); } $breadcrumbsData = $this->breadcrumbsDataProvider->getData($value['path']); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php index 0f1a7d8ee9dab..9047eaee4b568 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php @@ -8,8 +8,8 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -29,7 +29,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product Product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index a09510be8bc7d..962256ceff442 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; @@ -46,7 +46,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index a54cb62c16527..785cd75585d5d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -31,7 +31,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index 2fa47f86ecb9d..88ae457c9986f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -31,7 +31,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index 7c7e4ef117a50..cb53ebdab4810 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Option; @@ -32,7 +32,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index 6f4f8553a324a..3bc9057f06b01 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Pricing\Price\FinalPrice; @@ -59,7 +59,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index 96519d6191eee..2573e92e564b9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -7,11 +7,11 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Catalog\Helper\Output as OutputHelper; /** @@ -44,7 +44,7 @@ public function resolve( array $args = null ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product Product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index 4d5622bd5c6d0..b2a612d6ae02d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductLink\Link; @@ -39,7 +39,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index 63599a88c79a0..cf1b621ad65b6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\TierPrice; @@ -34,7 +34,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php index 9fe64a16935c7..070c564713a96 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; @@ -47,7 +47,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['entity_id'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } $this->productWebsitesCollection->addIdFilters((int)$value['entity_id']); $result = function () use ($value) { diff --git a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php index 169456f7d4bbd..9e10f0b448504 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php +++ b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php @@ -11,7 +11,7 @@ use Magento\CatalogInventory\Api\StockRegistryInterface; use Magento\CatalogInventory\Model\Configuration; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -50,7 +50,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product ProductInterface */ diff --git a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php index 2f3d520c2cb8f..354e053efa90f 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php +++ b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php @@ -10,7 +10,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockStatusInterface; use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -39,7 +39,7 @@ public function __construct(StockStatusRepositoryInterface $stockStatusRepositor public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product ProductInterface */ diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 5141361fecc0e..0842c96ef4b1a 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -7,7 +7,7 @@ namespace Magento\DownloadableGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Downloadable\Helper\Data as DownloadableHelper; @@ -77,7 +77,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php index 6ccd610bead0d..b0def15f3a0d4 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php @@ -9,6 +9,7 @@ use Magento\EavGraphQl\Model\Resolver\DataProvider\AttributeOptions as AttributeOptionsDataProvider; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; @@ -68,12 +69,12 @@ public function resolve( /** * @param array $value * @return int - * @throws GraphQlInputException + * @throws LocalizedException */ private function getEntityType(array $value): int { if (!isset($value['entity_type'])) { - throw new GraphQlInputException(__('"Entity type should be specified')); + throw new LocalizedException(__('"Entity type should be specified')); } return (int)$value['entity_type']; @@ -82,12 +83,12 @@ private function getEntityType(array $value): int /** * @param array $value * @return string - * @throws GraphQlInputException + * @throws LocalizedException */ private function getAttributeCode(array $value): string { if (!isset($value['attribute_code'])) { - throw new GraphQlInputException(__('"Attribute code should be specified')); + throw new LocalizedException(__('"Attribute code should be specified')); } return $value['attribute_code']; diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index b1d7aae5df101..390279f2cfe2e 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -9,7 +9,6 @@ use Magento\Framework\Webapi\CustomAttributeTypeLocatorInterface; use Magento\Framework\Reflection\TypeProcessor; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** @@ -71,7 +70,7 @@ public function getType(string $attributeCode, string $entityType) : string try { $type = $this->typeProcessor->translateTypeName($type); } catch (\InvalidArgumentException $exception) { - throw new \LogicException('Cannot resolve EAV type'); + throw new GraphQlInputException(__('Cannot resolve EAV type')); } } else { $type = $type === 'double' ? 'float' : $type; diff --git a/app/code/Magento/GraphQl/Model/EntityAttributeList.php b/app/code/Magento/GraphQl/Model/EntityAttributeList.php index 6b8a4f477069e..3802b74f3ec13 100644 --- a/app/code/Magento/GraphQl/Model/EntityAttributeList.php +++ b/app/code/Magento/GraphQl/Model/EntityAttributeList.php @@ -14,7 +14,7 @@ use Magento\Framework\Api\MetadataServiceInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; /** * Iterate through all attribute sets to retrieve attributes for any given entity type @@ -69,7 +69,7 @@ public function __construct( * @param string $entityCode * @param MetadataServiceInterface $metadataService * @return boolean[] - * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException */ public function getDefaultEntityAttributes( string $entityCode, @@ -93,7 +93,7 @@ public function getDefaultEntityAttributes( $this->attributeManagement->getAttributes($entityCode, $attributeSet->getAttributeSetId()) ); } catch (NoSuchEntityException $exception) { - throw new GraphQlInputException(__('Entity code %1 does not exist.', [$entityCode])); + throw new GraphQlNoSuchEntityException(__('Entity code %1 does not exist.', [$entityCode])); } } $attributeCodes = []; diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php index fee4063affef1..d51b22ffe21df 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -7,7 +7,7 @@ namespace Magento\GroupedProductGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -44,7 +44,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } $data = []; diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index 0c4c78b582941..fb7bbd634d11f 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -7,7 +7,7 @@ namespace Magento\UrlRewriteGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -45,7 +45,7 @@ public function resolve( array $args = null ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var AbstractModel $entity */ From c498773af5dc671b511534d759645808c7ae04c3 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:28:46 +0200 Subject: [PATCH 1251/1415] GraphQL-39: Manage Shipping methods on Cart --- app/code/Magento/QuoteGraphQl/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 881450745b84a..1bf4d581a5fe3 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,7 +9,8 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-customer": "*" + "magento/module-customer": "*", + "magento/module-customer-graph-ql": "*" }, "suggest": { "magento/module-graph-ql": "*" From 028a15ced987666269cf9cdb269b5002cfa5b11d Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rainwater@netatmo.com> Date: Mon, 19 Nov 2018 14:38:07 +0100 Subject: [PATCH 1252/1415] Refactored _getMultiSelectAttributeWithSourceModels to use repo getList as opposed to direct query --- .../Product/Indexer/Eav/Source.php | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index ab09171a6f2ed..a2aa217941cb9 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -7,6 +7,7 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; /** * Catalog Product Eav Select and Multiply Select Attributes Indexer resource model @@ -29,6 +30,16 @@ class Source extends AbstractEav */ protected $_attributeRepository; + /** + * @var \Magento\Framework\Api\SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + /** * Construct * @@ -38,6 +49,8 @@ class Source extends AbstractEav * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository + * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Psr\Log\LoggerInterface $logger * @param null|string $connectionName */ public function __construct( @@ -47,6 +60,8 @@ public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, + \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, + \Psr\Log\LoggerInterface $logger, $connectionName = null ) { parent::__construct( @@ -58,6 +73,8 @@ public function __construct( ); $this->_resourceHelper = $resourceHelper; $this->_attributeRepository = $attributeRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->logger = $logger; } /** @@ -310,39 +327,31 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu /** * Get options for multiselect attributes using custom source models - * @maderlock's fix from: https://github.com/magento/magento2/issues/417#issuecomment-265146285 + * Based on @maderlock's fix from: + * https://github.com/magento/magento2/issues/417#issuecomment-265146285 * * @param array $attrIds * @param array $options * * @return array - * @throws \Zend_Db_Statement_Exception */ protected function _getMultiSelectAttributeWithSourceModels($attrIds, $options) { // Add options from custom source models - $select = $this->getConnection()->select() - ->from( - ['ea' => $this->getTable('eav_attribute')], - ['attribute_id','entity_type_id', 'attribute_code'] - ) - ->where('attribute_id IN(?)', $attrIds) - ->where('source_model is not null'); - $query = $select->query(); - - while ($row = $query->fetch()) { - try { - /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ - $attribute = $this->_attributeRepository->get($row['entity_type_id'], $row['attribute_code']); - $sourceModelOptions = $attribute->getOptions(); - // Add options to list used below - foreach ($sourceModelOptions as $o) { - $options[$row['attribute_id']][$o->getValue()] = true; - } - } catch (\BadMethodCallException $e) { - // Skip - } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { - // skip + $this->searchCriteriaBuilder + ->addFilter('attribute_id', $attrIds, 'in') + ->addFilter('source_model', true, 'notnull'); + $criteria = $this->searchCriteriaBuilder->create(); + $attributes = $this->_attributeRepository->getList( + ProductAttributeInterface::ENTITY_TYPE_CODE, + $criteria + )->getItems(); + + foreach ($attributes as $attribute) { + $sourceModelOptions = $attribute->getOptions(); + // Add options to list used below + foreach ($sourceModelOptions as $o) { + $options[$attribute->getAttributeId()][$o->getValue()] = true; } } From f38283304a86c7d720e74daed60420a9064e1e6e Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rainwater@netatmo.com> Date: Mon, 19 Nov 2018 14:39:17 +0100 Subject: [PATCH 1253/1415] Removed logger interface since we no longer have exceptions to log --- .../Model/ResourceModel/Product/Indexer/Eav/Source.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index a2aa217941cb9..ea90d089e9353 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -35,11 +35,6 @@ class Source extends AbstractEav */ private $searchCriteriaBuilder; - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - /** * Construct * @@ -50,7 +45,6 @@ class Source extends AbstractEav * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder - * @param \Psr\Log\LoggerInterface $logger * @param null|string $connectionName */ public function __construct( @@ -61,7 +55,6 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, - \Psr\Log\LoggerInterface $logger, $connectionName = null ) { parent::__construct( @@ -74,7 +67,6 @@ public function __construct( $this->_resourceHelper = $resourceHelper; $this->_attributeRepository = $attributeRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->logger = $logger; } /** From 645cdd2fe463d0b200a2e87848eb79da3c716f8d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:41:04 +0200 Subject: [PATCH 1254/1415] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../Model/ProductLinkTypeResolverComposite.php | 2 +- .../Model/Resolver/Product/EntityIdToId.php | 4 ++-- .../Resolver/Product/MediaGalleryEntries.php | 11 ++++++++++- .../Model/Resolver/Product/NewFromTo.php | 10 +++++++++- .../Model/Resolver/Product/Options.php | 11 ++++++++++- .../Model/Resolver/Product/Price.php | 11 ++++++++++- .../Model/Resolver/Product/ProductLinks.php | 15 ++++++++++++--- .../Model/Resolver/Product/TierPrices.php | 15 ++++++++++++--- .../Resolver/Product/DownloadableOptions.php | 15 ++++++++++++--- .../Model/Resolver/AttributeOptions.php | 8 +++++++- .../EavGraphQl/Model/Resolver/Query/Type.php | 2 +- 11 files changed, 86 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index fbce18dfb67a5..c1bf5c0b7bb1c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Query\Resolver\TypeResolverInterface; /** - * {@inheritdoc} + * @inheritdoc */ class ProductLinkTypeResolverComposite implements TypeResolverInterface { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index 962256ceff442..b3e76ea78d183 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -16,9 +16,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Fixed the id related data in the product data - * * {@inheritdoc} + * + * Fixed the id related data in the product data */ class EntityIdToId implements ResolverInterface { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index 785cd75585d5d..f9bb3071ff378 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -19,9 +20,17 @@ class MediaGalleryEntries implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's media gallery entry data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index 88ae457c9986f..eb9f0d401e3a1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -19,9 +19,17 @@ class NewFromTo implements ResolverInterface { /** + * {@inheritdoc} + * * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index cb53ebdab4810..bb386833b5b75 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Option; @@ -20,9 +21,17 @@ class Options implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's option data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index 3bc9057f06b01..ca29b46aae9f7 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Pricing\Price\FinalPrice; @@ -47,9 +48,17 @@ public function __construct( } /** + * {@inheritdoc} + * * Format product's tier price data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index b2a612d6ae02d..4a0fcfaa413fa 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductLink\Link; @@ -15,9 +16,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format the product links information to conform to GraphQL schema representation - * * {@inheritdoc} + * + * Format the product links information to conform to GraphQL schema representation */ class ProductLinks implements ResolverInterface { @@ -27,9 +28,17 @@ class ProductLinks implements ResolverInterface private $linkTypes = ['related', 'upsell', 'crosssell']; /** + * {@inheritdoc} + * * Format product links data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index cf1b621ad65b6..e4a1b2889d470 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\TierPrice; @@ -15,16 +16,24 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format a product's tier price information to conform to GraphQL schema representation - * * {@inheritdoc} + * + * Format a product's tier price information to conform to GraphQL schema representation */ class TierPrices implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's tier price data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 0842c96ef4b1a..4d0bdb4c61f3e 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -8,6 +8,7 @@ namespace Magento\DownloadableGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Downloadable\Helper\Data as DownloadableHelper; @@ -20,9 +21,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format for downloadable product types - * * {@inheritdoc} + * + * Format for downloadable product types */ class DownloadableOptions implements ResolverInterface { @@ -65,9 +66,17 @@ public function __construct( } /** + * {@inheritdoc} + * * Add downloadable options to configurable types * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php index b0def15f3a0d4..e4c27adc60247 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php @@ -47,7 +47,7 @@ public function __construct( } /** - * @inheritDoc + * @inheritdoc */ public function resolve( Field $field, @@ -67,6 +67,8 @@ public function resolve( } /** + * Get entity type + * * @param array $value * @return int * @throws LocalizedException @@ -81,6 +83,8 @@ private function getEntityType(array $value): int } /** + * Get attribute code + * * @param array $value * @return string * @throws LocalizedException @@ -95,6 +99,8 @@ private function getAttributeCode(array $value): string } /** + * Get attribute options data + * * @param int $entityType * @param string $attributeCode * @return array diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index 390279f2cfe2e..ef21a26f1f62e 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -36,7 +36,7 @@ class Type /** * @param CustomAttributeTypeLocatorInterface $typeLocator * @param TypeProcessor $typeProcessor - * @param $customTypes + * @param array $customTypes */ public function __construct( CustomAttributeTypeLocatorInterface $typeLocator, From a54fed5ce35eb5d6c6d1c95b4b5b94dd37a111b1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:15:33 +0200 Subject: [PATCH 1255/1415] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php | 2 +- .../Model/Resolver/Product/MediaGalleryEntries.php | 4 +++- .../CatalogGraphQl/Model/Resolver/Product/NewFromTo.php | 4 +++- .../Magento/CatalogGraphQl/Model/Resolver/Product/Options.php | 2 +- .../Magento/CatalogGraphQl/Model/Resolver/Product/Price.php | 2 +- .../CatalogGraphQl/Model/Resolver/Product/ProductLinks.php | 2 +- .../CatalogGraphQl/Model/Resolver/Product/TierPrices.php | 4 ++-- .../Model/Resolver/Product/DownloadableOptions.php | 4 ++-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index b3e76ea78d183..ada3caad5f9f8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -16,7 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Fixed the id related data in the product data */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index f9bb3071ff378..c8f167da583d3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -15,12 +15,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** + * @inheritdoc + * * Format a product's media gallery information to conform to GraphQL schema representation */ class MediaGalleryEntries implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's media gallery entry data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index eb9f0d401e3a1..12016282a3081 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -14,12 +14,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** + * @inheritdoc + * * Format the new from and to typo of legacy fields news_from_date and news_to_date */ class NewFromTo implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index bb386833b5b75..76602288039c5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -21,7 +21,7 @@ class Options implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's option data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index ca29b46aae9f7..55d930101fb60 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -48,7 +48,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * * Format product's tier price data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index 4a0fcfaa413fa..f72f873fc8e55 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -28,7 +28,7 @@ class ProductLinks implements ResolverInterface private $linkTypes = ['related', 'upsell', 'crosssell']; /** - * {@inheritdoc} + * @inheritdoc * * Format product links data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index e4a1b2889d470..726ef91c56880 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -16,14 +16,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format a product's tier price information to conform to GraphQL schema representation */ class TierPrices implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's tier price data to conform to GraphQL schema * diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 4d0bdb4c61f3e..a1e25663a9c3d 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -21,7 +21,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format for downloadable product types */ @@ -66,7 +66,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * * Add downloadable options to configurable types * From 39225d4aceee4f6f6cf2d8da09235333c8b8961d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:21:09 +0200 Subject: [PATCH 1256/1415] GraphQL-39: Manage Shipping methods on Cart -- fixes after merge --- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 3e622f9fa5412..edc643973ce77 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,7 +6,7 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") From 7f41544848b0496779a4a8d07ccb8869d9ef435b Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:23:51 +0200 Subject: [PATCH 1257/1415] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../CatalogGraphQl/Model/Resolver/Product/ProductLinks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index f72f873fc8e55..4d1b11a74b9d4 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -16,7 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format the product links information to conform to GraphQL schema representation */ From 130e160986d20ec7b4e1717c3bb4f61a7aa5900e Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Mon, 19 Nov 2018 16:54:22 +0200 Subject: [PATCH 1258/1415] MAGETWO-96290: [Magento Cloud] Cannot update category positions via REST API --- .../Model/Category/Link/SaveHandler.php | 27 ++-- .../ResourceModel/Product/CategoryLink.php | 16 ++- .../Model/Category/Link/SaveHandlerTest.php | 130 ++++++++++++++++++ 3 files changed, 152 insertions(+), 21 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php diff --git a/app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php b/app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php index f22c6903a230c..4ea06d4e34d71 100644 --- a/app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php +++ b/app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php @@ -6,7 +6,6 @@ namespace Magento\Catalog\Model\Category\Link; use Magento\Catalog\Api\Data\CategoryLinkInterface; -use Magento\Catalog\Model\Indexer\Product\Category; use Magento\Framework\EntityManager\Operation\ExtensionInterface; /** @@ -40,6 +39,8 @@ public function __construct( } /** + * Execute + * * @param object $entity * @param array $arguments * @return object @@ -78,6 +79,8 @@ public function execute($entity, $arguments = []) } /** + * Get category links positions + * * @param object $entity * @return array */ @@ -106,27 +109,19 @@ private function getCategoryLinksPositions($entity) */ private function mergeCategoryLinks($newCategoryPositions, $oldCategoryPositions) { - $result = []; if (empty($newCategoryPositions)) { - return $result; + return []; } + $categoryPositions = array_combine(array_column($oldCategoryPositions, 'category_id'), $oldCategoryPositions); foreach ($newCategoryPositions as $newCategoryPosition) { - $key = array_search( - $newCategoryPosition['category_id'], - array_column($oldCategoryPositions, 'category_id') - ); - - if ($key === false) { - $result[] = $newCategoryPosition; - } elseif (isset($oldCategoryPositions[$key]) - && $oldCategoryPositions[$key]['position'] != $newCategoryPosition['position'] - ) { - $result[] = $newCategoryPositions[$key]; - unset($oldCategoryPositions[$key]); + $categoryId = $newCategoryPosition['category_id']; + if (!isset($categoryPositions[$categoryId])) { + $categoryPositions[$categoryId] = ['category_id' => $categoryId]; } + $categoryPositions[$categoryId]['position'] = $newCategoryPosition['position']; } - $result = array_merge($result, $oldCategoryPositions); + $result = array_values($categoryPositions); return $result; } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php index b54c19a111508..f11c975396f2e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php @@ -93,6 +93,8 @@ public function saveCategoryLinks(ProductInterface $product, array $categoryLink } /** + * Get category link metadata + * * @return \Magento\Framework\EntityManager\EntityMetadataInterface */ private function getCategoryLinkMetadata() @@ -114,16 +116,16 @@ private function getCategoryLinkMetadata() private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositions) { $result = ['changed' => [], 'updated' => []]; + + $oldCategoryPositions = array_values($oldCategoryPositions); + $oldCategoryList = array_column($oldCategoryPositions, 'category_id'); foreach ($newCategoryPositions as $newCategoryPosition) { - $key = array_search( - $newCategoryPosition['category_id'], - array_column($oldCategoryPositions, 'category_id') - ); + $key = array_search($newCategoryPosition['category_id'], $oldCategoryList); if ($key === false) { $result['changed'][] = $newCategoryPosition; } elseif ($oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']) { - $result['updated'][] = $newCategoryPositions[$key]; + $result['updated'][] = $newCategoryPosition; unset($oldCategoryPositions[$key]); } } @@ -132,6 +134,8 @@ private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositi } /** + * Update category links + * * @param ProductInterface $product * @param array $insertLinks * @param bool $insert @@ -175,6 +179,8 @@ private function updateCategoryLinks(ProductInterface $product, array $insertLin } /** + * Delete category links + * * @param ProductInterface $product * @param array $deleteLinks * @return array diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php new file mode 100644 index 0000000000000..af5028cb16479 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php @@ -0,0 +1,130 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Category\Link; + +use Magento\Catalog\Api\Data\CategoryLinkInterfaceFactory; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Save handler test + * + * @magentoDataFixture Magento/Catalog/_files/categories_no_products.php + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + */ +class SaveHandlerTest extends TestCase +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var string + */ + private $productLinkField; + + /** + * @var CategoryLinkInterfaceFactory + */ + private $categoryLinkFactory; + + /** + * @var SaveHandler + */ + private $saveHandler; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); + $metadataPool = Bootstrap::getObjectManager()->create(MetadataPool::class); + $this->productLinkField = $metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $this->categoryLinkFactory = Bootstrap::getObjectManager()->create(CategoryLinkInterfaceFactory::class); + $this->saveHandler = Bootstrap::getObjectManager()->create(SaveHandler::class); + } + + /** + * Execute test + * + * @return void + */ + public function testExecute(): void + { + $product = $this->productRepository->get('simple2'); + $product->setCategoryIds([3, 4, 6]); + $this->productRepository->save($product); + $categoryPositions = [ + 3 => [ + 'category_id' => 3, + 'position' => 0, + ], + 4 => [ + 'category_id' => 4, + 'position' => 0, + ], + 6 => [ + 'category_id' => 6, + 'position' => 0, + ], + ]; + + $categoryLinks = $product->getExtensionAttributes()->getCategoryLinks(); + $this->assertEmpty($categoryLinks); + + $categoryLinks = []; + $categoryPositions[4]['position'] = 1; + $categoryPositions[6]['position'] = 1; + foreach ($categoryPositions as $categoryPosition) { + $categoryLink = $this->categoryLinkFactory->create() + ->setCategoryId($categoryPosition['category_id']) + ->setPosition($categoryPosition['position']); + $categoryLinks[] = $categoryLink; + } + $categoryLinks = $this->updateCategoryLinks($product, $categoryLinks); + foreach ($categoryLinks as $categoryLink) { + $categoryPosition = $categoryPositions[$categoryLink->getCategoryId()]; + $this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId()); + $this->assertEquals($categoryPosition['position'], $categoryLink->getPosition()); + } + + $categoryPositions[4]['position'] = 2; + $categoryLink = $this->categoryLinkFactory->create() + ->setCategoryId(4) + ->setPosition($categoryPositions[4]['position']); + $categoryLinks = $this->updateCategoryLinks($product, [$categoryLink]); + foreach ($categoryLinks as $categoryLink) { + $categoryPosition = $categoryPositions[$categoryLink->getCategoryId()]; + $this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId()); + $this->assertEquals($categoryPosition['position'], $categoryLink->getPosition()); + } + } + + /** + * Update category links + * + * @param ProductInterface $product + * @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks + * @return \Magento\Catalog\Api\Data\CategoryLinkInterface[] + */ + private function updateCategoryLinks(ProductInterface $product, array $categoryLinks): array + { + $product->getExtensionAttributes()->setCategoryLinks($categoryLinks); + $arguments = [$this->productLinkField => $product->getData($this->productLinkField)]; + $this->saveHandler->execute($product, $arguments); + $product = $this->productRepository->get($product->getSku(), false, null, true); + $categoryLinks = $product->getExtensionAttributes()->getCategoryLinks(); + + return $categoryLinks; + } +} From 6d26686321561fb0460f8024d89af2483a2dfda9 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 19 Nov 2018 17:35:28 +0200 Subject: [PATCH 1259/1415] MAGETWO-94424: Wrong product and shipping prices are applying on admin orders --- app/code/Magento/Store/Model/Store.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index 32c9a78448428..c92d62cd0bbe3 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -412,7 +412,7 @@ public function __construct( } /** - * @return string[] + * @inheritdoc */ public function __sleep() { @@ -786,7 +786,7 @@ public function isFrontUrlSecure() } /** - * @return bool + * @inheritdoc */ public function isUrlSecure() { @@ -1338,6 +1338,8 @@ public function getIdentities() } /** + * Get store path + * * @return string */ public function getStorePath() @@ -1347,8 +1349,7 @@ public function getStorePath() } /** - * {@inheritdoc} - * @since 100.1.0 + * @inheritdoc */ public function getScopeType() { @@ -1356,8 +1357,7 @@ public function getScopeType() } /** - * {@inheritdoc} - * @since 100.1.0 + * @inheritdoc */ public function getScopeTypeName() { @@ -1365,7 +1365,7 @@ public function getScopeTypeName() } /** - * {@inheritdoc} + * @inheritdoc */ public function getExtensionAttributes() { @@ -1373,8 +1373,7 @@ public function getExtensionAttributes() } /** - * @param \Magento\Store\Api\Data\StoreExtensionInterface $extensionAttributes - * @return $this + * @inheritdoc */ public function setExtensionAttributes( \Magento\Store\Api\Data\StoreExtensionInterface $extensionAttributes From b9c4e77bc0cca1f87efa569c2804e7bfe6723025 Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rain2o@gmail.com> Date: Mon, 19 Nov 2018 17:28:25 +0100 Subject: [PATCH 1260/1415] Resolved code standard errors. --- .../Product/Indexer/Eav/Source.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index ea90d089e9353..f9fb8ec3bb338 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -28,12 +28,12 @@ class Source extends AbstractEav /** * @var \Magento\Eav\Api\AttributeRepositoryInterface */ - protected $_attributeRepository; + private $attributeRepository; /** * @var \Magento\Framework\Api\SearchCriteriaBuilder */ - private $searchCriteriaBuilder; + private $criteriaBuilder; /** * Construct @@ -44,7 +44,7 @@ class Source extends AbstractEav * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository - * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder * @param null|string $connectionName */ public function __construct( @@ -54,7 +54,7 @@ public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, - \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, + \Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder, $connectionName = null ) { parent::__construct( @@ -65,8 +65,8 @@ public function __construct( $connectionName ); $this->_resourceHelper = $resourceHelper; - $this->_attributeRepository = $attributeRepository; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->attributeRepository = $attributeRepository; + $this->criteriaBuilder = $criteriaBuilder; } /** @@ -252,7 +252,7 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu } // Include custom source model options - $options = $this->_getMultiSelectAttributeWithSourceModels($attrIds, $options); + $options = $this->getMultiSelectAttributeWithSourceModels($attrIds, $options); // prepare get multiselect values query $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value'); @@ -327,13 +327,13 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu * * @return array */ - protected function _getMultiSelectAttributeWithSourceModels($attrIds, $options) + private function getMultiSelectAttributeWithSourceModels($attrIds, $options) { // Add options from custom source models - $this->searchCriteriaBuilder + $this->criteriaBuilder ->addFilter('attribute_id', $attrIds, 'in') ->addFilter('source_model', true, 'notnull'); - $criteria = $this->searchCriteriaBuilder->create(); + $criteria = $this->criteriaBuilder->create(); $attributes = $this->_attributeRepository->getList( ProductAttributeInterface::ENTITY_TYPE_CODE, $criteria From faa85353df4be28674a07d406ff87e422284b985 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 18:48:55 +0200 Subject: [PATCH 1261/1415] GraphQL-202: Products: Email to a Friend --- .../Model/Resolver/SendEmailToFriend.php | 179 +++++++++++------- .../Model/Validation/Validation.php | 69 ------- .../Magento/SendFriendGraphQl/composer.json | 26 +++ .../SendFriendGraphQl/etc/schema.graphqls | 9 +- composer.json | 1 + composer.lock | 2 +- 6 files changed, 145 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php create mode 100644 app/code/Magento/SendFriendGraphQl/composer.json diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 56f6d20b20f18..06c5da94819df 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -7,38 +7,60 @@ namespace Magento\SendFriendGraphQl\Model\Resolver; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\DataObjectFactory; +use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\SendFriend\Model\SendFriend; +use Magento\SendFriend\Model\SendFriendFactory; +/** + * @inheritdoc + */ class SendEmailToFriend implements ResolverInterface { /** - * @var SendFriend + * @var SendFriendFactory */ - private $sendFriend; + private $sendFriendFactory; + /** * @var ProductRepositoryInterface */ private $productRepository; + /** * @var DataObjectFactory */ private $dataObjectFactory; + /** + * @var ManagerInterface + */ + private $eventManager; + + /** + * @param SendFriendFactory $sendFriendFactory + * @param ProductRepositoryInterface $productRepository + * @param DataObjectFactory $dataObjectFactory + * @param ManagerInterface $eventManager + */ public function __construct( - SendFriend $sendFriend, + SendFriendFactory $sendFriendFactory, ProductRepositoryInterface $productRepository, - DataObjectFactory $dataObjectFactory + DataObjectFactory $dataObjectFactory, + ManagerInterface $eventManager ) { - $this->sendFriend = $sendFriend; + $this->sendFriendFactory = $sendFriendFactory; $this->productRepository = $productRepository; $this->dataObjectFactory = $dataObjectFactory; + $this->eventManager = $eventManager; } /** @@ -46,102 +68,131 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + /** @var SendFriend $sendFriend */ + $sendFriend = $this->sendFriendFactory->create(); + + if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() + $sendFriend->getMaxSendsToFriend() )); } - $product = $this->getProductFromRepository($args['input']['params']['product_id']); - $senderArray = $this->getSenderArrayFromArgs($args); - $recipientsArray = $this->getRecipientsArray($args); - //@todo clarify if event should be dispatched - //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); - $this->sendFriend->setSender($senderArray); - $this->sendFriend->setRecipients($recipientsArray); - $this->sendFriend->setProduct($product); - - $this->prepareDataForValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - $this->addRecipientNameValidation($args); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } + $product = $this->getProduct($args['input']['product_id']); + $this->eventManager->dispatch('sendfriend_product', ['product' => $product]); + $sendFriend->setProduct($product); - $this->sendFriend->send(); + $senderData = $this->extractSenderData($args); + $sendFriend->setSender($senderData); - return array_merge($senderArray, $recipientsArray); - } + $recipientsData = $this->extractRecipientsData($args); + $sendFriend->setRecipients($recipientsData); - private function prepareDataForValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $this->validateSendFriendModel($sendFriend, $senderData, $recipientsData); + $sendFriend->send(); - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); + return array_merge($senderData, $recipientsData); } /** - * @param array $args + * Validate send friend model + * + * @param SendFriend $sendFriend + * @param array $senderData + * @param array $recipientsData + * @return void * @throws GraphQlInputException */ - private function addRecipientNameValidation(array $args): void + private function validateSendFriendModel(SendFriend $sendFriend, array $senderData, array $recipientsData): void { - foreach ($args['input']['recipients'] as $recipient) { - if (empty($recipient['name'])) { - throw new GraphQlInputException( - __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] - )); - } + $sender = $this->dataObjectFactory->create()->setData($senderData['sender']); + $sendFriend->setData('_sender', $sender); + + $emails = array_column($recipientsData['recipients'], 'email'); + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $sendFriend->setData('_recipients', $recipients); + + $validationResult = $sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); } } /** + * Get product + * * @param int $productId - * @return bool|\Magento\Catalog\Api\Data\ProductInterface + * @return ProductInterface + * @throws GraphQlNoSuchEntityException */ - private function getProductFromRepository(int $productId) + private function getProduct(int $productId): ProductInterface { try { $product = $this->productRepository->getById($productId); if (!$product->isVisibleInCatalog()) { - return false; + throw new GraphQlNoSuchEntityException( + __("The product that was requested doesn't exist. Verify the product and try again.") + ); } - } catch (NoSuchEntityException $noEntityException) { - return false; + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } - return $product; } - private function getRecipientsArray(array $args): array + /** + * Extract recipients data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractRecipientsData(array $args): array { - $recipientsArray = []; + $recipients = []; foreach ($args['input']['recipients'] as $recipient) { - $recipientsArray[] = [ + if (empty($recipient['name'])) { + throw new GraphQlInputException(__('Please provide Name for all of recipients.')); + } + + if (empty($recipient['email'])) { + throw new GraphQlInputException(__('Please provide Email for all of recipients.')); + } + + $recipients[] = [ 'name' => $recipient['name'], 'email' => $recipient['email'], ]; } - return ['recipients' => $recipientsArray]; + return ['recipients' => $recipients]; } - private function getSenderArrayFromArgs(array $args): array + /** + * Extract sender data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractSenderData(array $args): array { - return ['sender' => [ - 'name' => $args['input']['sender']['name'], - 'email' => $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ] - ]; + if (empty($args['input']['sender']['name'])) { + throw new GraphQlInputException(__('Please provide Name of sender.')); + } + + if (empty($args['input']['sender']['email'])) { + throw new GraphQlInputException(__('Please provide Email of sender.')); + } + + if (empty($args['input']['sender']['message'])) { + throw new GraphQlInputException(__('Please provide Message.')); + } + + return [ + 'sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ], + ]; } } diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php deleted file mode 100644 index 49f7feeaba489..0000000000000 --- a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\SendFriendGraphQl\Model\Validation; - -use Magento\Framework\DataObjectFactory; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\SendFriend\Model\SendFriend; - -class Validation -{ - /** - * @var SendFriend - */ - private $sendFriend; - /** - * @var DataObjectFactory - */ - private $dataObjectFactory; - - public function __construct( - DataObjectFactory $dataObjectFactory, - SendFriend $sendFriend - ) { - $this->sendFriend = $sendFriend; - $this->dataObjectFactory = $dataObjectFactory; - } - - /** - * @param $args - * @param array $recipientsArray - * @throws GraphQlInputException - */ - public function validate($args, array $recipientsArray): void - { - $this->prepareDataForSendFriendValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() - )); - } - } - - private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); - - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); - } - -} \ No newline at end of file diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json new file mode 100644 index 0000000000000..10d7e63bfc770 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-send-friend-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-catalog": "*", + "magento/module-send-friend": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SendFriendGraphGl\\": "" + } + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 4123387650838..3915d48681ab1 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -6,9 +6,9 @@ type Mutation { } input SendEmailToFriendSenderInput { + product_id: Int! sender: Sender! - params: Params! - recipients: [Recipient] + recipients: [Recipient!]! } type Sender { @@ -16,17 +16,12 @@ type Sender { email: String! message: String! } -type Params { - product_id: Int! - category_id: Int! -} type Recipient { name: String! email: String! } - type SendEmailToFriendOutput { sender: Sender recipients: [Recipient] diff --git a/composer.json b/composer.json index 3f8f0a033c893..99f5beeb9c7e7 100644 --- a/composer.json +++ b/composer.json @@ -208,6 +208,7 @@ "magento/module-search": "*", "magento/module-security": "*", "magento/module-send-friend": "*", + "magento/module-send-friend-graph-ql": "*", "magento/module-shipping": "*", "magento/module-signifyd": "*", "magento/module-sitemap": "*", diff --git a/composer.lock b/composer.lock index 1d101c8aaaf15..a3e7a72e69026 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6640ddfd342feceaec44c406c056f57", + "content-hash": "886f5497f18a46a42d05cc672f1b8f2f", "packages": [ { "name": "braintree/braintree_php", From b6e07229fbd610a6617d47ab4c73cae0c335bb8f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 18:53:31 +0200 Subject: [PATCH 1262/1415] GraphQL-202: Products: Email to a Friend --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 36b4dca023191..f26b71f1cc392 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7538e15ea4ff1378cf55983ce9acba82", + "content-hash": "93418bd14ad2d9f54f4059550ded7061", "packages": [ { "name": "braintree/braintree_php", From 793c72d47707c6f4824a500ff3c84f5e0637833f Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 19 Nov 2018 11:18:55 -0600 Subject: [PATCH 1263/1415] MAGETWO-95934: Can't upload Watermark Image - Fixed ui component element type - Added mftf test --- .../ui_component/design_config_form.xml | 6 +-- .../Mftf/Test/AdminWatermarkUploadTest.xml | 16 +++++++ .../ui_component/design_config_form.xml | 2 +- .../Theme/Test/Mftf/Page/DesignConfigPage.xml | 14 ++++++ .../Mftf/Section/AdminDesignConfigSection.xml | 18 ++++++++ .../Mftf/Test/AdminWatermarkUploadTest.xml | 46 +++++++++++++++++++ 6 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/AdminWatermarkUploadTest.xml create mode 100644 app/code/Magento/Theme/Test/Mftf/Page/DesignConfigPage.xml create mode 100644 app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml create mode 100644 app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml index 1e60823929770..cb0beb67c2711 100644 --- a/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml @@ -18,7 +18,7 @@ <level>2</level> <label translate="true">Base</label> </settings> - <field name="watermark_image_image" formElement="fileUploader"> + <field name="watermark_image_image" formElement="imageUploader"> <settings> <notice translate="true">Allowed file types: jpeg, gif, png.</notice> <label translate="true">Image</label> @@ -78,7 +78,7 @@ <level>2</level> <label translate="true">Thumbnail</label> </settings> - <field name="watermark_thumbnail_image" formElement="fileUploader"> + <field name="watermark_thumbnail_image" formElement="imageUploader"> <settings> <label translate="true">Image</label> <componentType>imageUploader</componentType> @@ -137,7 +137,7 @@ <level>2</level> <label translate="true">Small</label> </settings> - <field name="watermark_small_image_image" formElement="fileUploader"> + <field name="watermark_small_image_image" formElement="imageUploader"> <settings> <label translate="true">Image</label> <componentType>imageUploader</componentType> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminWatermarkUploadTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminWatermarkUploadTest.xml new file mode 100644 index 0000000000000..e9df186bae5e6 --- /dev/null +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminWatermarkUploadTest.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminWatermarkUploadTest"> + <waitForElement selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Swatch Image')}}" stepKey="waitForInputVisible4" after="waitForPreviewImage3"/> + <attachFile selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Swatch Image')}}" userInput="adobe-small.jpg" stepKey="attachFile4" after="waitForInputVisible4"/> + <waitForElementVisible selector="{{AdminDesignConfigSection.imageUploadPreviewByFieldsetName('Swatch Image')}}" stepKey="waitForPreviewImage4" after="attachFile4"/> + </test> +</tests> diff --git a/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml index 1c58243be3262..b38e8ecc6e201 100644 --- a/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml @@ -13,7 +13,7 @@ <level>2</level> <label translate="true">Swatch Image</label> </settings> - <field name="watermark_swatch_image_image" formElement="fileUploader"> + <field name="watermark_swatch_image_image" formElement="imageUploader"> <settings> <label translate="true">Image</label> <componentType>imageUploader</componentType> diff --git a/app/code/Magento/Theme/Test/Mftf/Page/DesignConfigPage.xml b/app/code/Magento/Theme/Test/Mftf/Page/DesignConfigPage.xml new file mode 100644 index 0000000000000..7a802aee73e3c --- /dev/null +++ b/app/code/Magento/Theme/Test/Mftf/Page/DesignConfigPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="DesignConfigPage" url="theme/design_config/" area="admin" module="Magento_Theme"> + <section name="AdminDesignConfigSection"/> + </page> +</pages> diff --git a/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml b/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml new file mode 100644 index 0000000000000..5035cf2299ea5 --- /dev/null +++ b/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminDesignConfigSection"> + <element name="scopeRow" type="button" selector="//*[contains(@class,'data-row')][{{arg1}}]//*[contains(@class,'action-menu-item')]" parameterized="true"/> + <element name="watermarkSectionHeader" type="text" selector="[data-index='watermark']"/> + <element name="watermarkSection" type="text" selector="[data-index='watermark'] .admin__fieldset-wrapper-content"/> + <element name="imageUploadInputByFieldsetName" type="input" selector="//*[contains(@class,'fieldset-wrapper')][child::*[contains(@class,'fieldset-wrapper-title')]//*[contains(text(),'{{arg1}}')]]//*[contains(@class,'file-uploader')]//input" parameterized="true"/> + <element name="imageUploadPreviewByFieldsetName" type="input" selector="//*[contains(@class,'fieldset-wrapper')][child::*[contains(@class,'fieldset-wrapper-title')]//*[contains(text(),'{{arg1}}')]]//*[contains(@class,'file-uploader-preview')]//img" parameterized="true"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml new file mode 100644 index 0000000000000..046f8c405dfdf --- /dev/null +++ b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminWatermarkUploadTest"> + <annotations> + <features value="Watermark"/> + <stories value="Watermark"/> + <title value="MAGETWO-95934: Can't upload Watermark Image"/> + <description value="Watermark images should be able to be uploaded in the admin"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95934"/> + <group value="Watermark"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminArea"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> + </after> + <amOnPage url="{{DesignConfigPage.url}}" stepKey="navigateToDesignConfigPage" /> + <waitForPageLoad stepKey="waitForPageload1"/> + <click selector="{{AdminDesignConfigSection.scopeRow('3')}}" stepKey="editStoreView"/> + <waitForPageLoad stepKey="waitForPageload2"/> + <scrollTo selector="{{AdminDesignConfigSection.watermarkSectionHeader}}" stepKey="scrollToWatermarkSection"/> + <click selector="{{AdminDesignConfigSection.watermarkSectionHeader}}" stepKey="openWatermarkSection"/> + + <waitForElement selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Base')}}" stepKey="waitForInputVisible1"/> + <attachFile selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Base')}}" userInput="adobe-base.jpg" stepKey="attachFile1"/> + <waitForElementVisible selector="{{AdminDesignConfigSection.imageUploadPreviewByFieldsetName('Base')}}" stepKey="waitForPreviewImage"/> + + <waitForElement selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Thumbnail')}}" stepKey="waitForInputVisible2"/> + <attachFile selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Thumbnail')}}" userInput="adobe-thumb.jpg" stepKey="attachFile2"/> + <waitForElementVisible selector="{{AdminDesignConfigSection.imageUploadPreviewByFieldsetName('Thumbnail')}}" stepKey="waitForPreviewImage2"/> + + <waitForElement selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Small')}}" stepKey="waitForInputVisible3"/> + <attachFile selector="{{AdminDesignConfigSection.imageUploadInputByFieldsetName('Small')}}" userInput="adobe-small.jpg" stepKey="attachFile3"/> + <waitForElementVisible selector="{{AdminDesignConfigSection.imageUploadPreviewByFieldsetName('Small')}}" stepKey="waitForPreviewImage3"/> + </test> +</tests> From 5dc91198c458a888d45955542a3d6ef32ffeb8c9 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 19 Nov 2018 11:20:56 -0600 Subject: [PATCH 1264/1415] MAGETWO-95934: Can't upload Watermark Image - Added newline --- .../Theme/Test/Mftf/Section/AdminDesignConfigSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml b/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml index 5035cf2299ea5..0aa2f7f35218a 100644 --- a/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml +++ b/app/code/Magento/Theme/Test/Mftf/Section/AdminDesignConfigSection.xml @@ -15,4 +15,4 @@ <element name="imageUploadInputByFieldsetName" type="input" selector="//*[contains(@class,'fieldset-wrapper')][child::*[contains(@class,'fieldset-wrapper-title')]//*[contains(text(),'{{arg1}}')]]//*[contains(@class,'file-uploader')]//input" parameterized="true"/> <element name="imageUploadPreviewByFieldsetName" type="input" selector="//*[contains(@class,'fieldset-wrapper')][child::*[contains(@class,'fieldset-wrapper-title')]//*[contains(text(),'{{arg1}}')]]//*[contains(@class,'file-uploader-preview')]//img" parameterized="true"/> </section> -</sections> \ No newline at end of file +</sections> From 202ce32dd4bed272a9ddb1a4618fa0e14a179dcb Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 19 Nov 2018 11:40:27 -0600 Subject: [PATCH 1265/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 --- .../Magento/Config/App/Config/Type/System.php | 90 +++++++------------ .../Framework/Encryption/Adapter/Mcrypt.php | 8 +- .../Framework/Encryption/Encryptor.php | 26 ++++-- .../View/Element/Template/File/Validator.php | 3 +- .../Magento/Setup/Model/CryptKeyGenerator.php | 2 +- 5 files changed, 60 insertions(+), 69 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 7f61ded7d8835..095daf553b614 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -16,13 +16,13 @@ use Magento\Framework\Serialize\SerializerInterface; use Magento\Store\Model\Config\Processor\Fallback; use Magento\Store\Model\ScopeInterface as StoreScope; +use Magento\Framework\Encryption\Encryptor; /** * System configuration type * * @api * @since 100.1.2 - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class System implements ConfigTypeInterface { @@ -70,6 +70,11 @@ class System implements ConfigTypeInterface */ private $availableDataScopes; + /** + * @var \Magento\Framework\Filter\Encrypt\AdapterInterface + */ + private $encriptFilter; + /** * @param ConfigSourceInterface $source * @param PostProcessorInterface $postProcessor @@ -79,7 +84,8 @@ class System implements ConfigTypeInterface * @param PreProcessorInterface $preProcessor * @param int $cachingNestedLevel * @param string $configType - * @param Reader $reader + * @param Reader|null $reader + * @param Encryptor|null $encryptorFilter * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -92,18 +98,18 @@ public function __construct( PreProcessorInterface $preProcessor, $cachingNestedLevel = 1, $configType = self::CONFIG_TYPE, - Reader $reader = null + Reader $reader = null, + Encryptor $encryptorFilter = null ) { $this->postProcessor = $postProcessor; $this->cache = $cache; $this->serializer = $serializer; $this->configType = $configType; $this->reader = $reader ?: ObjectManager::getInstance()->get(Reader::class); + $this->encriptFilter = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); } /** - * Get config value by path. - * * System configuration is separated by scopes (default, websites, stores). Configuration of a scope is inherited * from its parent scope (store inherits website). * @@ -124,7 +130,7 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->data, $this->loadAllData()); + $this->data = array_replace_recursive($this->loadAllData(), $this->data); return $this->data; } @@ -132,32 +138,6 @@ public function get($path = '') return $this->getWithParts($path); } - /** - * Merge newly loaded config data into already loaded. - * - * @param array $newData - * @return void - */ - private function mergeData(array $newData): void - { - if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { - //Sometimes new data may contain links to arrays and we don't want that. - $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; - unset($newData[ScopeInterface::SCOPE_DEFAULT]); - } - foreach ($newData as $scopeType => $scopeTypeData) { - if (!array_key_exists($scopeType, $this->data)) { - //Sometimes new data may contain links to arrays and we don't want that. - $this->data[$scopeType] = (array)$scopeTypeData; - } else { - foreach ($scopeTypeData as $scopeId => $scopeData) { - //Sometimes new data may contain links to arrays and we don't want that. - $this->data[$scopeType][$scopeId] = (array)$scopeData; - } - } - } - } - /** * Proceed with parts extraction from path. * @@ -170,10 +150,8 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { - //First filling data property with unprocessed data for post-processors to be able to use. $data = $this->readData(); - //Post-processing only the data we know is not yet processed. - $this->mergeData($this->postProcessor->process($data)); + $this->data = array_replace_recursive($data, $this->data); } return $this->data[$pathParts[0]]; @@ -183,11 +161,7 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - //Adding unprocessed data to the data property so it can be used in post-processing. - $this->mergeData($scopeData = $this->loadDefaultScopeData($scopeType)); - //Only post-processing the data we know is raw. - $scopeData = $this->postProcessor->process($scopeData); - $this->mergeData($scopeData); + $this->data = array_replace_recursive($this->loadDefaultScopeData($scopeType), $this->data); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -197,11 +171,10 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); - //Adding unprocessed data to the data property so it can be used in post-processing. - $this->mergeData($scopeData); - //Only post-processing the data we know is raw. - $scopeData = $this->postProcessor->process($scopeData); - $this->mergeData($scopeData); + + if (!isset($this->data[$scopeType][$scopeId])) { + $this->data = array_replace_recursive($scopeData, $this->data); + } } return isset($this->data[$scopeType][$scopeId]) @@ -221,11 +194,10 @@ private function loadAllData() if ($cachedData === false) { $data = $this->readData(); } else { - $data = $this->serializer->unserialize($cachedData); - $this->data = $data; + $data = $this->serializer->unserialize($this->encriptFilter->decrypt($cachedData)); } - return $this->postProcessor->process($data); + return $data; } /** @@ -242,7 +214,7 @@ private function loadDefaultScopeData($scopeType) $data = $this->readData(); $this->cacheData($data); } else { - $data = [$scopeType => $this->serializer->unserialize($cachedData)]; + $data = [$scopeType => $this->serializer->unserialize($this->encriptFilter->decrypt($cachedData))]; } return $data; @@ -263,7 +235,8 @@ private function loadScopeData($scopeType, $scopeId) if ($this->availableDataScopes === null) { $cachedScopeData = $this->cache->load($this->configType . '_scopes'); if ($cachedScopeData !== false) { - $this->availableDataScopes = $this->serializer->unserialize($cachedScopeData); + $serializedCachedData = $this->encriptFilter->decrypt($cachedScopeData); + $this->availableDataScopes = $this->serializer->unserialize($serializedCachedData); } } if (is_array($this->availableDataScopes) && !isset($this->availableDataScopes[$scopeType][$scopeId])) { @@ -271,8 +244,9 @@ private function loadScopeData($scopeType, $scopeId) } $data = $this->readData(); $this->cacheData($data); - } else { - $data = [$scopeType => [$scopeId => $this->serializer->unserialize($cachedData)]]; + } else { + $serializedCachedData = $this->encriptFilter->decrypt($cachedData); + $data = [$scopeType => [$scopeId => $this->serializer->unserialize($serializedCachedData)]]; } return $data; @@ -280,7 +254,6 @@ private function loadScopeData($scopeType, $scopeId) /** * Cache configuration data. - * * Caches data per scope to avoid reading data for all scopes on every request * * @param array $data @@ -289,12 +262,12 @@ private function loadScopeData($scopeType, $scopeId) private function cacheData(array $data) { $this->cache->save( - $this->serializer->serialize($data), + $this->encriptFilter->encrypt($this->serializer->serialize($data)), $this->configType, [self::CACHE_TAG] ); $this->cache->save( - $this->serializer->serialize($data['default']), + $this->encriptFilter->encrypt($this->serializer->serialize($data['default'])), $this->configType . '_default', [self::CACHE_TAG] ); @@ -303,14 +276,14 @@ private function cacheData(array $data) foreach ($data[$curScopeType] ?? [] as $curScopeId => $curScopeData) { $scopes[$curScopeType][$curScopeId] = 1; $this->cache->save( - $this->serializer->serialize($curScopeData), + $this->encriptFilter->encrypt($this->serializer->serialize($curScopeData)), $this->configType . '_' . $curScopeType . '_' . $curScopeId, [self::CACHE_TAG] ); } } $this->cache->save( - $this->serializer->serialize($scopes), + $this->encriptFilter->encrypt($this->serializer->serialize($scopes)), $this->configType . '_scopes', [self::CACHE_TAG] ); @@ -346,6 +319,9 @@ private function getDataByPathParts($data, $pathParts) private function readData(): array { $this->data = $this->reader->read(); + $this->data = $this->postProcessor->process( + $this->data + ); return $this->data; } diff --git a/lib/internal/Magento/Framework/Encryption/Adapter/Mcrypt.php b/lib/internal/Magento/Framework/Encryption/Adapter/Mcrypt.php index 3660b28657b58..c2e82a6a7f6f8 100644 --- a/lib/internal/Magento/Framework/Encryption/Adapter/Mcrypt.php +++ b/lib/internal/Magento/Framework/Encryption/Adapter/Mcrypt.php @@ -144,9 +144,11 @@ public function getHandle() */ public function encrypt(string $data): string { - throw new \Exception( - (string)new \Magento\Framework\Phrase('Mcrypt cannot be used for encryption. Use Sodium instead') - ); + if (strlen($data) == 0) { + return $data; + } + // @codingStandardsIgnoreLine + return @mcrypt_generic($this->getHandle(), $data); } /** diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index f7d52d5474ad7..a0c70ba36e16b 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -274,10 +274,10 @@ private function getPasswordVersion() */ public function encrypt($data) { - $crypt = new SodiumChachaIetf($this->keys[$this->keyVersion]); + $crypt = $this->getCrypt(); return $this->keyVersion . - ':' . self::CIPHER_AEAD_CHACHA20POLY1305 . + ':' . $this->getCipherVersion() . ':' . base64_encode($crypt->encrypt($data)); } @@ -391,7 +391,7 @@ private function getCrypt( string $initVector = null ): ?EncryptionAdapterInterface { if (null === $key && null === $cipherVersion) { - $cipherVersion = self::CIPHER_RIJNDAEL_256; + $cipherVersion = $this->getCipherVersion(); } if (null === $key) { @@ -413,15 +413,27 @@ private function getCrypt( if ($cipherVersion === self::CIPHER_RIJNDAEL_128) { $cipher = MCRYPT_RIJNDAEL_128; - $mode = MCRYPT_MODE_ECB; } elseif ($cipherVersion === self::CIPHER_RIJNDAEL_256) { $cipher = MCRYPT_RIJNDAEL_256; - $mode = MCRYPT_MODE_CBC; } else { $cipher = MCRYPT_BLOWFISH; - $mode = MCRYPT_MODE_ECB; } - return new Mcrypt($key, $cipher, $mode, $initVector); + return new Mcrypt($key, $cipher, MCRYPT_MODE_ECB, $initVector); + } + + /** + * Get cipher Version + * + * + * @return int + */ + private function getCipherVersion() + { + if (extension_loaded('sodium')) { + return $this->cipher; + } else { + return self::CIPHER_RIJNDAEL_256; + } } } diff --git a/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php b/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php index 5f18c78e3a0ad..285c05c9db69c 100644 --- a/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php +++ b/lib/internal/Magento/Framework/View/Element/Template/File/Validator.php @@ -135,8 +135,9 @@ protected function isPathInDirectories($path, $directories) if (!is_array($directories)) { $directories = (array)$directories; } + $realPath = $this->fileDriver->getRealPath($path); foreach ($directories as $directory) { - if (0 === strpos($this->fileDriver->getRealPath($path), $directory)) { + if (0 === strpos($realPath, $directory)) { return true; } } diff --git a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php index ec9d3f028126a..398ec73f94d4f 100644 --- a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php +++ b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php @@ -39,7 +39,7 @@ public function __construct(Random $random) */ public function generate() { - return md5($this->getRandomString()); + return $this->getRandomString(); } /** From f33328dab91d0945d16733236d9311d656a8c00b Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Mon, 19 Nov 2018 11:57:45 -0600 Subject: [PATCH 1266/1415] MAGETWO-96463: Add caching to improve admin performance - add layout config, product layout options and copyright cache --- .../Magento/Backend/Block/Page/Footer.php | 8 ++++ .../Model/Product/Attribute/Source/Layout.php | 44 ++++++++++++++++--- .../Magento/Framework/Config/View.php | 34 ++++++++++++-- 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Backend/Block/Page/Footer.php b/app/code/Magento/Backend/Block/Page/Footer.php index 3d1570e5ddfe7..ca4d708c939d1 100644 --- a/app/code/Magento/Backend/Block/Page/Footer.php +++ b/app/code/Magento/Backend/Block/Page/Footer.php @@ -57,4 +57,12 @@ public function getMagentoVersion() { return $this->productMetadata->getVersion(); } + + /** + * @inheritdoc + */ + protected function getCacheLifetime() + { + return 3600 * 24 * 10; + } } diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php index 63b1444d1db07..dd44e2942ed82 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php @@ -5,10 +5,13 @@ */ namespace Magento\Catalog\Model\Product\Attribute\Source; +use Magento\Framework\App\Cache\Type\Layout as LayoutCache; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Serialize\Serializer\Serialize; + /** * Catalog product landing page attribute source - * - * @author Magento Core Team <core@magentocommerce.com> */ class Layout extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource { @@ -17,23 +20,50 @@ class Layout extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ protected $pageLayoutBuilder; + /** + * @var LayoutCache + */ + private $layoutCache; + + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder + * @param LayoutCache|null $layoutCache + * @param SerializerInterface|null $serializer */ - public function __construct(\Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder) - { + public function __construct( + \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder, + LayoutCache $layoutCache = null, + SerializerInterface $serializer = null + ) { $this->pageLayoutBuilder = $pageLayoutBuilder; + $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Serialize::class); } /** + * Get list of available layouts + * * @return array + * @throws \InvalidArgumentException */ public function getAllOptions() { if (!$this->_options) { - $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); - array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); + $layoutCacheKey = __CLASS__; + if ($data = $this->layoutCache->load($layoutCacheKey)) { + return $this->_options = $this->serializer->unserialize($data); + } else { + $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); + array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); + $this->layoutCache->save($this->serializer->serialize($this->_options), $layoutCacheKey); + } + } return $this->_options; } -} +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 05863caeec2b6..7fe8ed1ef7227 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -5,6 +5,11 @@ */ namespace Magento\Framework\Config; +use Magento\Framework\App\Cache\Type\Layout as LayoutCache; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Serialize\Serializer\Serialize; + /** * View configuration files handler * @@ -23,17 +28,28 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @var array */ protected $data; + /** + * @var LayoutCache + */ + private $layoutCache; + + /** + * @var SerializerInterface + */ + private $serializer; /** * @param FileResolverInterface $fileResolver * @param ConverterInterface $converter * @param SchemaLocatorInterface $schemaLocator * @param ValidationStateInterface $validationState - * @param string $fileName + * @param $fileName * @param array $idAttributes * @param string $domDocumentClass * @param string $defaultScope * @param array $xpath + * @param LayoutCache|null $layoutCache + * @param SerializerInterface|null $serializer */ public function __construct( FileResolverInterface $fileResolver, @@ -44,10 +60,13 @@ public function __construct( $idAttributes = [], $domDocumentClass = \Magento\Framework\Config\Dom::class, $defaultScope = 'global', - $xpath = [] + $xpath = [], + LayoutCache $layoutCache = null, + SerializerInterface $serializer = null ) { $this->xpath = $xpath; $idAttributes = $this->getIdAttributes(); + parent::__construct( $fileResolver, $converter, @@ -58,6 +77,8 @@ public function __construct( $domDocumentClass, $defaultScope ); + $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Serialize::class); } /** @@ -190,11 +211,18 @@ protected function getItems() * Initialize data array * * @return void + * @throws \InvalidArgumentException */ protected function initData() { if ($this->data === null) { - $this->data = $this->read(); + $layoutCacheKey = __CLASS__; + if ($data = $this->layoutCache->load($layoutCacheKey)) { + $this->data = $this->serializer->unserialize($data); + } else { + $this->data = $this->read(); + $this->layoutCache->save($this->serializer->serialize($this->data), $layoutCacheKey); + } } } From a653c2baf540fa0a7c42f84a8d72e9228aaeb9d4 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:18:31 +0200 Subject: [PATCH 1267/1415] GraphQL-202: Products: Email to a Friend --- app/code/Magento/SendFriendGraphQl/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/README.md diff --git a/app/code/Magento/SendFriendGraphQl/README.md b/app/code/Magento/SendFriendGraphQl/README.md new file mode 100644 index 0000000000000..d8051922ddad7 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/README.md @@ -0,0 +1,3 @@ +# SendFriendGraphQl + +**SendFriendGraphQl** provides support of GraphQL for SendFriend functionality. From 0bdc2fd3918e9fbd6ab48dc5cd97b270b17d163a Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:35:53 +0200 Subject: [PATCH 1268/1415] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 3 ++- app/code/Magento/SendFriendGraphQl/registration.php | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 06c5da94819df..2b183ca209c0c 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -72,7 +72,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $sendFriend = $this->sendFriendFactory->create(); if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + throw new GraphQlInputException( + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend() )); } diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index c41607a0dc864..5988738268147 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; From b6d9adeed9bd275e0e819c33af35dff134b17834 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:40:10 +0200 Subject: [PATCH 1269/1415] GraphQL-202: Products: Email to a Friend -- fix static tests --- app/code/Magento/SendFriendGraphQl/composer.json | 2 +- app/code/Magento/SendFriendGraphQl/etc/module.xml | 2 +- app/code/Magento/SendFriendGraphQl/registration.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index 10d7e63bfc770..d401f57b2257a 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -20,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\SendFriendGraphGl\\": "" + "Magento\\SendFriendGraphQl\\": "" } } } diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml index 14d792198cd5f..3df33266cac6e 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/module.xml +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -7,5 +7,5 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_SendFriendGraphGl"/> + <module name="Magento_SendFriendGraphQl"/> </config> diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index 5988738268147..13ec47b16abdb 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -7,4 +7,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphGl', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphQl', __DIR__); From 05c1c8a02790974b5574f66a3ba81f721c325785 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 21:00:42 +0200 Subject: [PATCH 1270/1415] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 2b183ca209c0c..c0c01c71df764 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -73,9 +73,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException( - __('You can\'t send messages more than %1 times an hour.', - $sendFriend->getMaxSendsToFriend() - )); + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend()) + ); } $product = $this->getProduct($args['input']['product_id']); From 54da6f6a10250a49fe8fd54b1479271076d7a2fa Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Mon, 19 Nov 2018 14:48:18 -0600 Subject: [PATCH 1271/1415] MC-5318: Create tax rate, all postcodes --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 13 +++ .../Mftf/Section/AdminTaxRateFormSection.xml | 21 +++++ .../Mftf/Section/AdminTaxRateGridSection.xml | 21 +++++ .../Mftf/Section/AdminTaxRulesSection.xml | 1 + .../AdminCreateTaxRateAllPostCodesTest.xml | 79 +++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml new file mode 100644 index 0000000000000..7a8dc35e79690 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SimpleTaxRate" type="taxRate"> + <data key="code" unique="suffix">TaxRate</data> + </entity> +</entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml new file mode 100644 index 0000000000000..580ce8cb485fb --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminTaxRateFormSection"> + <element name="taxIdentifier" type="input" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> + <element name="labelForZipCode" type="text" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> + <element name="deleteRate" type="button" selector="#delete"/> + <element name="ok" type="button" selector="button.action-primary.action-accept"/> + + <element name="country" type="select" selector="#tax_country_id"/> + <element name="state" type="select" selector="#tax_region_id"/> + <element name="rate" type="text" selector="#rate"/> + </section> +</sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml new file mode 100644 index 0000000000000..daa86c5216219 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminTaxRateGridSection"> + <element name="grid" type="block" selector="#tax_rate_grid"/> + <element name="add" type="button" selector="#add" timeout="30"/> + <element name="search" type="button" selector="button[data-action='grid-filter-apply']" timeout="30"/> + <element name="filterByTaxIdentifier" type="input" selector="#tax_rate_grid_filter_code"/> + <element name="filterByCountry" type="input" selector="#tax_rate_grid_filter_tax_country_id"/> + <element name="filterByPostCode" type="input" selector="#tax_rate_grid_filter_tax_postcode"/> + <element name="nthRow" type="block" selector="tr[data-role='row']:nth-of-type({{var}})" parameterized="true" timeout="30"/> + <element name="country" type="select" selector="#tax_country_id"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml index 6c258f2de18e7..04d0d7f766eef 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml @@ -28,5 +28,6 @@ <element name="deleteTaxClassName" type="button" selector="//span[contains(text(),'{{var1}}')]" parameterized="true"/> <element name="deleteTaxClass" type="button" selector="//span[contains(text(),'{{var1}}')]/../..//*[@class='mselect-delete']" parameterized="true"/> <element name="popUpDialogOK" type="button" selector="//*[@class='modal-footer']//*[contains(text(),'OK')]"/> + <element name="taxRateMultiSelectItems" type="block" selector=".mselect-list-item"/> </section> </sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml new file mode 100644 index 0000000000000..40146a8632368 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateTaxRateAllPostCodesTest"> + <annotations> + <stories value="Create tax rate"/> + <title value="Create tax rate, all postcodes"/> + <description value="Tests log into Create tax rate and create all postcodes"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + <group value="banana"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> + <click selector="{{AdminTaxRateGridSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> + <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the tax rate." stepKey="seeSuccess"/> + </after> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + + <!-- Create a tax rate with * for postcodes --> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddButton"/> + <fillField selector="{{AdminTaxRateFormSection.ruleName}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> + <fillField selector="{{AdminTaxRateSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> + <selectOption selector="{{AdminTaxRateSection.country}}" userInput="Australia" stepKey="selectCountry"/> + <fillField selector="{{AdminTaxRateSection.rate}}" userInput="20" stepKey="fillRate"/> + <click selector="{{AdminTaxRateSection.saveRule}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify the tax rate grid page shows the tax rate we just created --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <selectOption selector="{{AdminTaxRateGridSection.filterByCountry}}" userInput="Australia" stepKey="fillCountryFilter"/> + <fillField selector="{{AdminTaxRateGridSection.filterByPostCode}}" userInput="*" stepKey="fillPostCodeFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <see selector="{{AdminTaxRateGridSection.grid}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRuleName"/> + <see selector="{{AdminTaxRateGridSection.grid}}" userInput="Australia" stepKey="seeCountry"/> + <see selector="{{AdminTaxRateGridSection.grid}}" userInput="*" stepKey="seePostCode"/> + + <!-- Go to the tax rate edit page for our new tax rate --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex3"/> + <waitForPageLoad stepKey="waitForTaxRateIndex3"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter2"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + + <!-- Verify we see expected values on the tax rate edit page --> + <seeInField selector="{{AdminTaxRateFormSection.ruleName}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRuleName2"/> + <seeInField selector="{{AdminTaxRateSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> + <seeOptionIsSelected selector="{{AdminTaxRateSection.country}}" userInput="Australia" stepKey="seeCountry2"/> + <seeInField selector="{{AdminTaxRateSection.rate}}" userInput="20" stepKey="seeRate"/> + + <!-- Go to the tax rule grid page and verify our tax rate can be used in the rule --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> + <waitForPageLoad stepKey="waitForTaxRuleIndex"/> + <click selector="{{AdminGridMainControls.add}}" stepKey="clickAddNewTaxRule"/> + <see selector="{{AdminTaxRulesSection.taxRateMultiSelectItems}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxRateOnNewTaxRulePage"/> + </test> +</tests> \ No newline at end of file From 7dcc9853e178b7f84884fe699d32c48250c74232 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Mon, 19 Nov 2018 15:47:44 -0600 Subject: [PATCH 1272/1415] MAGETWO-96463: Add caching to improve admin performance - fix annotation --- lib/internal/Magento/Framework/Config/View.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 7fe8ed1ef7227..57638e6d6c471 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -28,6 +28,7 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @var array */ protected $data; + /** * @var LayoutCache */ @@ -43,7 +44,7 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param ConverterInterface $converter * @param SchemaLocatorInterface $schemaLocator * @param ValidationStateInterface $validationState - * @param $fileName + * @param string $fileName * @param array $idAttributes * @param string $domDocumentClass * @param string $defaultScope From e8689c49df74d68acd1b52f5b48ca9e261620cb5 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 19 Nov 2018 16:34:36 -0600 Subject: [PATCH 1273/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 --- .../Variable/Model/Source/Variables.php | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Variable/Model/Source/Variables.php b/app/code/Magento/Variable/Model/Source/Variables.php index 38c2f92d25545..e878a3172be4b 100644 --- a/app/code/Magento/Variable/Model/Source/Variables.php +++ b/app/code/Magento/Variable/Model/Source/Variables.php @@ -23,6 +23,16 @@ class Variables implements \Magento\Framework\Option\ArrayInterface */ private $configVariables = []; + /** + * @var array + */ + private $configPaths = []; + + /** + * @var \Magento\Config\Model\Config\Structure\SearchInterface + */ + private $configStructure; + /** * Constructor. * @@ -33,25 +43,8 @@ public function __construct( \Magento\Config\Model\Config\Structure\SearchInterface $configStructure, array $configPaths = [] ) { - foreach ($configPaths as $groupPath => $groupElements) { - $groupPathElements = explode('/', $groupPath); - $path = []; - $labels = []; - foreach ($groupPathElements as $groupPathElement) { - $path[] = $groupPathElement; - $labels[] = __( - $configStructure->getElementByConfigPath(implode('/', $path))->getLabel() - ); - } - $this->configVariables[$groupPath]['label'] = implode(' / ', $labels); - foreach (array_keys($groupElements) as $elementPath) { - $this->configVariables[$groupPath]['elements'][] = [ - 'value' => $elementPath, - 'label' => __($configStructure->getElementByConfigPath($elementPath)->getLabel()), - ]; - } - } - $this->configVariables; + $this->configStructure = $configStructure; + $this->configPaths = $configPaths; } /** @@ -64,7 +57,7 @@ public function toOptionArray($withGroup = false) { $optionArray = []; if ($withGroup) { - foreach ($this->configVariables as $configVariableGroup) { + foreach ($this->getConfigVariables() as $configVariableGroup) { $group = [ 'label' => $configVariableGroup['label'] ]; @@ -79,7 +72,7 @@ public function toOptionArray($withGroup = false) $optionArray[] = $group; } } else { - foreach ($this->configVariables as $configVariableGroup) { + foreach ($this->getConfigVariables() as $configVariableGroup) { foreach ($configVariableGroup['elements'] as $element) { $optionArray[] = [ 'value' => '{{config path="' . $element['value'] . '"}}', @@ -110,7 +103,7 @@ public function getData() private function getFlatConfigVars() { $result = []; - foreach ($this->configVariables as $configVariableGroup) { + foreach ($this->getConfigVariables() as $configVariableGroup) { foreach ($configVariableGroup['elements'] as $element) { $element['group_label'] = $configVariableGroup['label']; $result[] = $element; @@ -118,4 +111,35 @@ private function getFlatConfigVars() } return $result; } + + /** + * Merge config with user defined data + * + * @return array + */ + private function getConfigVariables() + { + if (empty($this->configVariables)) { + foreach ($this->configPaths as $groupPath => $groupElements) { + $groupPathElements = explode('/', $groupPath); + $path = []; + $labels = []; + foreach ($groupPathElements as $groupPathElement) { + $path[] = $groupPathElement; + $labels[] = __( + $this->configStructure->getElementByConfigPath(implode('/', $path))->getLabel() + ); + } + $this->configVariables[$groupPath]['label'] = implode(' / ', $labels); + foreach (array_keys($groupElements) as $elementPath) { + $this->configVariables[$groupPath]['elements'][] = [ + 'value' => $elementPath, + 'label' => __($this->configStructure->getElementByConfigPath($elementPath)->getLabel()), + ]; + } + } + } + + return $this->configVariables; + } } From 6f308c9a426dfd59e3e17cccf7693f2afcf0b21d Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Mon, 19 Nov 2018 17:33:03 -0600 Subject: [PATCH 1274/1415] MAGETWO-96463: Add caching to improve admin performance - refactor to not use PHP serialize --- .../Catalog/Model/Product/Attribute/Source/Layout.php | 6 +++--- lib/internal/Magento/Framework/Config/View.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php index dd44e2942ed82..61c382ea0459f 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php @@ -8,7 +8,7 @@ use Magento\Framework\App\Cache\Type\Layout as LayoutCache; use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Serialize; +use Magento\Framework\Serialize\Serializer\Json; /** * Catalog product landing page attribute source @@ -42,7 +42,7 @@ public function __construct( ) { $this->pageLayoutBuilder = $pageLayoutBuilder; $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); - $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Serialize::class); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); } /** @@ -59,11 +59,11 @@ public function getAllOptions() return $this->_options = $this->serializer->unserialize($data); } else { $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); - array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); $this->layoutCache->save($this->serializer->serialize($this->_options), $layoutCacheKey); } } + array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); return $this->_options; } } \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 57638e6d6c471..798a44bc630f8 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -8,7 +8,7 @@ use Magento\Framework\App\Cache\Type\Layout as LayoutCache; use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Serialize; +use Magento\Framework\Serialize\Serializer\Json; /** * View configuration files handler @@ -79,7 +79,7 @@ public function __construct( $defaultScope ); $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); - $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Serialize::class); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); } /** From 58c3b82257d97538751e97a5a01ffdb0ed3b3a54 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 19 Nov 2018 18:34:55 -0600 Subject: [PATCH 1275/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 --- .../Magento/Framework/Encryption/Encryptor.php | 4 +++- .../Encryption/Test/Unit/Adapter/McryptTest.php | 9 --------- .../Encryption/Test/Unit/EncryptorTest.php | 15 +++++++-------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index a0c70ba36e16b..d07dbace993b8 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -275,7 +275,9 @@ private function getPasswordVersion() public function encrypt($data) { $crypt = $this->getCrypt(); - + if (null === $crypt) { + return $data; + } return $this->keyVersion . ':' . $this->getCipherVersion() . ':' . base64_encode($crypt->encrypt($data)); diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/Adapter/McryptTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/Adapter/McryptTest.php index 2622441aa0896..452357003630c 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/Adapter/McryptTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/Adapter/McryptTest.php @@ -160,15 +160,6 @@ public function testDecrypt( $this->assertEquals($expectedData, $actualData); } - /** - * @expectedException \Exception - */ - public function testEncrypt() - { - $crypt = new \Magento\Framework\Encryption\Adapter\Mcrypt($this->key); - $crypt->encrypt('Hello World!!'); - } - /** * @dataProvider getCipherModeCombinations */ diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php index f3853a123c156..7bf43f149531b 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php @@ -109,7 +109,6 @@ public function validateHashDataProvider() * @param mixed $key * * @dataProvider encryptWithEmptyKeyDataProvider - * @expectedException \SodiumException */ public function testEncryptWithEmptyKey($key) { @@ -164,10 +163,10 @@ public function testEncrypt() $actual = $this->_model->encrypt($data); // Extract the initialization vector and encrypted data - $parts = explode(':', $actual, 3); + $parts = explode(':', $actual, 4); list(, , $encryptedData) = $parts; - - $crypt = new SodiumChachaIetf(self::CRYPT_KEY_1); + // Decrypt returned data with RIJNDAEL_256 cipher, cbc mode + $crypt = new Mcrypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256); // Verify decrypted matches original data $this->assertEquals($data, $crypt->decrypt(base64_decode((string)$encryptedData))); } @@ -193,7 +192,7 @@ public function testLegacyDecrypt() list(, , $iv, $encrypted) = $parts; // Decrypt returned data with RIJNDAEL_256 cipher, cbc mode - $crypt = new Crypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC, $iv); + $crypt = new Crypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB, $iv); // Verify decrypted matches original data $this->assertEquals($encrypted, base64_encode($crypt->encrypt($actual))); } @@ -224,7 +223,7 @@ public function testEncryptDecryptNewKeyAdded() public function testValidateKey() { - $this->_model->validateKey(self::CRYPT_KEY_1); + $this->assertNull($this->_model->validateKey(self::CRYPT_KEY_1)); } /** @@ -238,7 +237,7 @@ public function testValidateKeyInvalid() /** * @return array */ - public function testUseSpecifiedHashingAlgoDataProvider() + public function useSpecifiedHashingAlgoDataProvider() { return [ ['password', 'salt', Encryptor::HASH_VERSION_MD5, @@ -253,7 +252,7 @@ public function testUseSpecifiedHashingAlgoDataProvider() } /** - * @dataProvider testUseSpecifiedHashingAlgoDataProvider + * @dataProvider useSpecifiedHashingAlgoDataProvider * * @param $password * @param $salt From 6b21123a42877ad61fa51ff337a181d70c1d79e7 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Mon, 19 Nov 2018 18:40:16 -0600 Subject: [PATCH 1276/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 - fix integration tests --- .../Setup/Patch/Data/SodiumChachaPatchTest.php | 15 ++++++++++++++- .../Interception/PluginList/PluginList.php | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php index 3a47692bdb932..8843f3ce7236e 100644 --- a/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php +++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php @@ -93,6 +93,19 @@ private function legacyEncrypt(string $data): string @mcrypt_module_close($handle); // @codingStandardsIgnoreEnd - return '0:' . Encryptor::CIPHER_RIJNDAEL_256 . ':' . base64_encode($encrpted); + return '0:' . $this->getCipherVersion() . ':' . base64_encode($encrpted); + } + + /** + * Get cipher version + * + * @return int + */ + private function getCipherVersion() + { + if (extension_loaded('sodium')) { + return Encryptor::CIPHER_LATEST; + } + return Encryptor::CIPHER_RIJNDAEL_256; } } diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index e21841b48bc13..a4f728454a524 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -30,7 +30,7 @@ class PluginList extends Scoped implements InterceptionPluginList * * @var array */ - protected $_inherited; + protected $_inherited = []; /** * Inherited plugin data, preprocessed for read From 924df8ee679c4b23a9667cf88024cc1b9c95adea Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Mon, 19 Nov 2018 23:38:50 -0600 Subject: [PATCH 1277/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 - fix static tests --- app/code/Magento/Backend/Block/Page/Footer.php | 2 +- .../Catalog/Model/Product/Attribute/Source/Layout.php | 3 +-- app/code/Magento/Config/App/Config/Type/System.php | 7 +++++-- .../Magento/Framework/Encryption/Encryptor.php | 11 +++++++++-- setup/src/Magento/Setup/Model/CryptKeyGenerator.php | 2 -- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Backend/Block/Page/Footer.php b/app/code/Magento/Backend/Block/Page/Footer.php index ca4d708c939d1..e0c173a4cbfec 100644 --- a/app/code/Magento/Backend/Block/Page/Footer.php +++ b/app/code/Magento/Backend/Block/Page/Footer.php @@ -40,7 +40,7 @@ public function __construct( } /** - * @return void + * @inheritdoc */ protected function _construct() { diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php index 61c382ea0459f..caae962cc309e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php @@ -61,9 +61,8 @@ public function getAllOptions() $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); $this->layoutCache->save($this->serializer->serialize($this->_options), $layoutCacheKey); } - } array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); return $this->_options; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 095daf553b614..c692017573fba 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -110,6 +110,8 @@ public function __construct( } /** + * Get configuration value by path + * * System configuration is separated by scopes (default, websites, stores). Configuration of a scope is inherited * from its parent scope (store inherits website). * @@ -244,7 +246,7 @@ private function loadScopeData($scopeType, $scopeId) } $data = $this->readData(); $this->cacheData($data); - } else { + } else { $serializedCachedData = $this->encriptFilter->decrypt($cachedData); $data = [$scopeType => [$scopeId => $this->serializer->unserialize($serializedCachedData)]]; } @@ -253,7 +255,8 @@ private function loadScopeData($scopeType, $scopeId) } /** - * Cache configuration data. + * Cache configuration data + * * Caches data per scope to avoid reading data for all scopes on every request * * @param array $data diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index d07dbace993b8..a7d649894d6d5 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -228,6 +228,8 @@ public function validateHashVersion($hash, $validateCount = false) } /** + * Split password hash into parts: hash, salt, version + * * @param string $hash * @return array */ @@ -243,6 +245,8 @@ private function explodePasswordHash($hash) } /** + * Get password hash + * * @return string */ private function getPasswordHash() @@ -251,6 +255,8 @@ private function getPasswordHash() } /** + * Get password salt + * * @return string */ private function getPasswordSalt() @@ -259,6 +265,8 @@ private function getPasswordSalt() } /** + * Get password version + * * @return array */ private function getPasswordVersion() @@ -425,8 +433,7 @@ private function getCrypt( } /** - * Get cipher Version - * + * Get cipher version * * @return int */ diff --git a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php index 398ec73f94d4f..da5cb8b4d918a 100644 --- a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php +++ b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php @@ -31,10 +31,8 @@ public function __construct(Random $random) /** * Generates & returns a string to be used as crypt key. - * The key length is not a parameter, but an implementation detail. * * @return string - * * @throws \Magento\Framework\Exception\LocalizedException */ public function generate() From c640bc4441b8a1bde94d9b95da57aeb9f65dcae7 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 20 Nov 2018 10:57:39 +0200 Subject: [PATCH 1278/1415] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../view/frontend/web/js/model/shipping-rates-validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index b53be1a40f30a..fde88ebadb393 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -155,7 +155,7 @@ define([ * @return {*} */ postcodeValidation: function (postcodeElement) { - var countryId = $('#checkoutSteps > :visible select[name="country_id"]').val(), + var countryId = $('select[name="country_id"]:visible').val(), validationResult, warnMessage; From 3694c65e95fa12258afdfc561ff29ad23fb00969 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 20 Nov 2018 12:12:37 +0100 Subject: [PATCH 1279/1415] Added model to category data upon the hydration --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index e783c749fdc6e..d2c1fc8f7be9f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -56,6 +56,7 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData['id'] = $category->getId(); $categoryData['children'] = []; $categoryData['available_sort_by'] = $category->getAvailableSortBy(); + $categoryData['model'] = $category; return $this->flattener->flatten($categoryData); } } From 5016ad6e4554e90d46f8d6cc9390d5a1d5e45f7c Mon Sep 17 00:00:00 2001 From: Vincent MARMIESSE <vincent.marmiesse@ph2m.com> Date: Tue, 20 Nov 2018 13:02:16 +0100 Subject: [PATCH 1280/1415] Remove checkout edit link extra space --- .../templates/cart/item/renderer/actions/edit.phtml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/renderer/actions/edit.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/renderer/actions/edit.phtml index 1876cf2edb786..da0a83f05ef60 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/renderer/actions/edit.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/renderer/actions/edit.phtml @@ -12,8 +12,6 @@ <a class="action action-edit" href="<?= /* @escapeNotVerified */ $block->getConfigureUrl() ?>" title="<?= $block->escapeHtml(__('Edit item parameters')) ?>"> - <span> - <?= /* @escapeNotVerified */ __('Edit') ?> - </span> - </a> + <span><?= /* @escapeNotVerified */ __('Edit') ?></span> + </a> <?php endif ?> From 0a2a61a029c1eab6084a1fb840e6208d0f7f8963 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 20 Nov 2018 14:09:51 +0200 Subject: [PATCH 1281/1415] Fix static tests --- .../Magento/PageCache/view/frontend/web/js/page-cache.js | 8 +++++--- .../Magento_Checkout/web/css/source/module/_minicart.less | 2 +- .../Magento_MultipleWishlist/web/css/source/_module.less | 8 ++++---- .../Magento_Checkout/web/css/source/module/_minicart.less | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index 11707ea491fb5..c391b2c3aa72f 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -36,7 +36,9 @@ define([ * @returns {Array} */ $.fn.comments = function () { - var elements = []; + var elements = [], + contents, + elementContents; /** * @param {jQuery} element - Comment holder @@ -55,7 +57,7 @@ define([ } // rewrite jQuery contents() - var contents = function (element) { + contents = function (element) { return $.map(element, function (elem) { try { return $.nodeName(elem, "iframe") ? @@ -68,7 +70,7 @@ define([ }); }; - var elementContents = contents($(element)); + elementContents = contents($(element)); $.each(elementContents, function (index, el) { switch (el.nodeType) { diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less index d7ff3ba1e5732..673131563417d 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less @@ -107,7 +107,7 @@ @_toggle-selector: ~'.action.showcart', @_options-selector: ~'.block-minicart', @_dropdown-list-width: 320px, - @_dropdown-list-position-right: 0px, + @_dropdown-list-position-right: 0, @_dropdown-list-pointer-position: right, @_dropdown-list-pointer-position-left-right: 26px, @_dropdown-list-z-index: 101, diff --git a/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less index cb341f3f479ba..2761a2f74f990 100644 --- a/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_MultipleWishlist/web/css/source/_module.less @@ -389,16 +389,16 @@ .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { .wishlist { &.window.popup { + .field { + .lib-form-field-type-revert(@_type: block); + } + bottom: auto; .lib-css(top, @desktop-popup-position-top); .lib-css(left, @desktop-popup-position-left); .lib-css(margin-left, @desktop-popup-margin-left); .lib-css(width, @desktop-popup-width); right: auto; - - .field { - .lib-form-field-type-revert(@_type: block); - } } } diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less index 17fbdc8ba495b..9576004421e48 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less @@ -110,7 +110,7 @@ @_toggle-selector: ~'.action.showcart', @_options-selector: ~'.block-minicart', @_dropdown-list-width: 320px, - @_dropdown-list-position-right: 0px, + @_dropdown-list-position-right: 0, @_dropdown-list-pointer-position: right, @_dropdown-list-pointer-position-left-right: 26px, @_dropdown-list-z-index: 101, From fe68f5b643551e989215539f7d3dc04b9eeb36d5 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 20 Nov 2018 14:32:42 +0200 Subject: [PATCH 1282/1415] MAGETWO-96290: [Magento Cloud] Cannot update category positions via REST API --- .../Model/Category/Link/SaveHandlerTest.php | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php index af5028cb16479..5b24c4e22191a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/Link/SaveHandlerTest.php @@ -47,11 +47,13 @@ class SaveHandlerTest extends TestCase */ protected function setUp() { - $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); - $metadataPool = Bootstrap::getObjectManager()->create(MetadataPool::class); - $this->productLinkField = $metadataPool->getMetadata(ProductInterface::class)->getLinkField(); - $this->categoryLinkFactory = Bootstrap::getObjectManager()->create(CategoryLinkInterfaceFactory::class); - $this->saveHandler = Bootstrap::getObjectManager()->create(SaveHandler::class); + $objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $objectManager->create(ProductRepositoryInterface::class); + $metadataPool = $objectManager->create(MetadataPool::class); + $this->productLinkField = $metadataPool->getMetadata(ProductInterface::class) + ->getLinkField(); + $this->categoryLinkFactory = $objectManager->create(CategoryLinkInterfaceFactory::class); + $this->saveHandler = $objectManager->create(SaveHandler::class); } /** @@ -92,22 +94,14 @@ public function testExecute(): void $categoryLinks[] = $categoryLink; } $categoryLinks = $this->updateCategoryLinks($product, $categoryLinks); - foreach ($categoryLinks as $categoryLink) { - $categoryPosition = $categoryPositions[$categoryLink->getCategoryId()]; - $this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId()); - $this->assertEquals($categoryPosition['position'], $categoryLink->getPosition()); - } + $this->assertPositions($categoryPositions, $categoryLinks); $categoryPositions[4]['position'] = 2; $categoryLink = $this->categoryLinkFactory->create() ->setCategoryId(4) ->setPosition($categoryPositions[4]['position']); $categoryLinks = $this->updateCategoryLinks($product, [$categoryLink]); - foreach ($categoryLinks as $categoryLink) { - $categoryPosition = $categoryPositions[$categoryLink->getCategoryId()]; - $this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId()); - $this->assertEquals($categoryPosition['position'], $categoryLink->getPosition()); - } + $this->assertPositions($categoryPositions, $categoryLinks); } /** @@ -123,8 +117,25 @@ private function updateCategoryLinks(ProductInterface $product, array $categoryL $arguments = [$this->productLinkField => $product->getData($this->productLinkField)]; $this->saveHandler->execute($product, $arguments); $product = $this->productRepository->get($product->getSku(), false, null, true); - $categoryLinks = $product->getExtensionAttributes()->getCategoryLinks(); + $categoryLinks = $product->getExtensionAttributes() + ->getCategoryLinks(); return $categoryLinks; } + + /** + * Assert positions + * + * @param array $categoryPositions + * @param array $categoryLinks + * @return void + */ + private function assertPositions(array $categoryPositions, array $categoryLinks): void + { + foreach ($categoryLinks as $categoryLink) { + $categoryPosition = $categoryPositions[$categoryLink->getCategoryId()]; + $this->assertEquals($categoryPosition['category_id'], $categoryLink->getCategoryId()); + $this->assertEquals($categoryPosition['position'], $categoryLink->getPosition()); + } + } } From aa8e5d54665d435a613b093e8dfe83a741dd9c35 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 20 Nov 2018 15:41:30 +0200 Subject: [PATCH 1283/1415] Fix static tests --- .../view/frontend/web/js/page-cache.js | 16 ++++++++++------ app/code/Magento/Sales/Block/Order/Items.php | 17 ++++++++++------- .../Magento/Framework/Locale/Config.php | 3 +++ .../Framework/View/Layout/Generator/Block.php | 4 +--- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index c391b2c3aa72f..3789359696605 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -56,13 +56,17 @@ define([ } } - // rewrite jQuery contents() - contents = function (element) { - return $.map(element, function (elem) { + /** + * Rewrite jQuery contents(). + * + * @param {jQuery} elem + */ + contents = function (elem) { + return $.map(elem, function (el) { try { - return $.nodeName(elem, "iframe") ? - elem.contentDocument || (elem.contentWindow ? elem.contentWindow.document : []) : - $.merge([], elem.childNodes); + return $.nodeName(el, "iframe") ? + el.contentDocument || (el.contentWindow ? el.contentWindow.document : []) : + $.merge([], el.childNodes); } catch (e) { consoleLogger.error(e); return []; diff --git a/app/code/Magento/Sales/Block/Order/Items.php b/app/code/Magento/Sales/Block/Order/Items.php index 0b67e9a0746d3..d7255a24aead5 100644 --- a/app/code/Magento/Sales/Block/Order/Items.php +++ b/app/code/Magento/Sales/Block/Order/Items.php @@ -5,13 +5,13 @@ */ /** - * Sales order view items block - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Sales\Block\Order; /** + * Sales order view items block. + * * @api * @since 100.0.2 */ @@ -86,8 +86,9 @@ protected function _prepareLayout() } /** - * Determine if the pager should be displayed for order items list - * To be called from templates(after _prepareLayout()) + * Determine if the pager should be displayed for order items list. + * + * To be called from templates(after _prepareLayout()). * * @return bool * @since 100.1.7 @@ -100,7 +101,8 @@ public function isPagerDisplayed() /** * Get visible items for current page. - * To be called from templates(after _prepareLayout()) + * + * To be called from templates(after _prepareLayout()). * * @return \Magento\Framework\DataObject[] * @since 100.1.7 @@ -111,8 +113,9 @@ public function getItems() } /** - * Get pager HTML according to our requirements - * To be called from templates(after _prepareLayout()) + * Get pager HTML according to our requirements. + * + * To be called from templates(after _prepareLayout()). * * @return string HTML output * @since 100.1.7 diff --git a/lib/internal/Magento/Framework/Locale/Config.php b/lib/internal/Magento/Framework/Locale/Config.php index 790fa9c924c8e..fe685fdf35b73 100644 --- a/lib/internal/Magento/Framework/Locale/Config.php +++ b/lib/internal/Magento/Framework/Locale/Config.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Locale; +/** + * Allowed locale and currency configuration. + */ class Config implements \Magento\Framework\Locale\ConfigInterface { /** diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php index f0e62fce2a7ce..39da65a2d1f3d 100755 --- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php @@ -103,9 +103,7 @@ public function __construct( } /** - * {@inheritdoc} - * - * @return string + * @inheritdoc */ public function getType() { From 2aa7ad274cbc919530210f2c09db2515744b0af8 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 20 Nov 2018 16:13:24 +0200 Subject: [PATCH 1284/1415] Fix static tests --- app/code/Magento/PageCache/view/frontend/web/js/page-cache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index 3789359696605..144e20f2e728d 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -64,7 +64,7 @@ define([ contents = function (elem) { return $.map(elem, function (el) { try { - return $.nodeName(el, "iframe") ? + return $.nodeName(el, 'iframe') ? el.contentDocument || (el.contentWindow ? el.contentWindow.document : []) : $.merge([], el.childNodes); } catch (e) { From 0e6409db3ec5aa282ff1cf53083a059724fe96ef Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 20 Nov 2018 17:00:25 +0200 Subject: [PATCH 1285/1415] Fix static tests --- app/code/Magento/PageCache/view/frontend/web/js/page-cache.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index 144e20f2e728d..2e8a4769be10b 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -69,6 +69,7 @@ define([ $.merge([], el.childNodes); } catch (e) { consoleLogger.error(e); + return []; } }); From bcd3b24d1cc6261c1b43c3cc3f332791a801e9da Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 09:52:58 -0600 Subject: [PATCH 1286/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 --- .../Framework/Encryption/Test/Unit/EncryptorTest.php | 8 +------- .../Setup/Test/Unit/Model/CryptKeyGeneratorTest.php | 2 +- .../Setup/Test/Unit/Module/ConfigGeneratorTest.php | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php index 7bf43f149531b..3c1b4395bd064 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php @@ -161,14 +161,8 @@ public function testEncrypt() $data = 'Mares eat oats and does eat oats, but little lambs eat ivy.'; $actual = $this->_model->encrypt($data); - - // Extract the initialization vector and encrypted data - $parts = explode(':', $actual, 4); - list(, , $encryptedData) = $parts; - // Decrypt returned data with RIJNDAEL_256 cipher, cbc mode - $crypt = new Mcrypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256); // Verify decrypted matches original data - $this->assertEquals($data, $crypt->decrypt(base64_decode((string)$encryptedData))); + $this->assertEquals($data, $this->_model->decrypt($actual)); } public function testDecrypt() diff --git a/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php index d7a4d477de7b0..e367747fc92c1 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php @@ -54,6 +54,6 @@ public function testReturnsMd5OfRandomString() $actual = $this->cryptKeyGenerator->generate(); - $this->assertEquals($expected, $actual); + $this->assertEquals($expected, md5($actual)); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php index 65fe4a5f47711..e05c6667e6a6c 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php @@ -64,7 +64,7 @@ public function testCreateCryptConfigWithoutInput() { $returnValue = $this->configGeneratorObject->createCryptConfig([]); $this->assertEquals(ConfigFilePool::APP_ENV, $returnValue->getFileKey()); - $this->assertEquals(['crypt' => ['key' => md5('key')]], $returnValue->getData()); + $this->assertEquals(['crypt' => ['key' => ('key')]], $returnValue->getData()); } public function testCreateSessionConfigWithInput() From da337aa751cf56acbb27104a039cbd564dcee9af Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Tue, 20 Nov 2018 10:10:59 -0600 Subject: [PATCH 1287/1415] MAGETWO-96463: Add caching to improve admin performance - revert fix to \Magento\Framework\Config\View --- .../Magento/Framework/Config/View.php | 33 ++----------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 798a44bc630f8..05863caeec2b6 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -5,11 +5,6 @@ */ namespace Magento\Framework\Config; -use Magento\Framework\App\Cache\Type\Layout as LayoutCache; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Json; - /** * View configuration files handler * @@ -29,16 +24,6 @@ class View extends \Magento\Framework\Config\Reader\Filesystem */ protected $data; - /** - * @var LayoutCache - */ - private $layoutCache; - - /** - * @var SerializerInterface - */ - private $serializer; - /** * @param FileResolverInterface $fileResolver * @param ConverterInterface $converter @@ -49,8 +34,6 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param string $domDocumentClass * @param string $defaultScope * @param array $xpath - * @param LayoutCache|null $layoutCache - * @param SerializerInterface|null $serializer */ public function __construct( FileResolverInterface $fileResolver, @@ -61,13 +44,10 @@ public function __construct( $idAttributes = [], $domDocumentClass = \Magento\Framework\Config\Dom::class, $defaultScope = 'global', - $xpath = [], - LayoutCache $layoutCache = null, - SerializerInterface $serializer = null + $xpath = [] ) { $this->xpath = $xpath; $idAttributes = $this->getIdAttributes(); - parent::__construct( $fileResolver, $converter, @@ -78,8 +58,6 @@ public function __construct( $domDocumentClass, $defaultScope ); - $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); - $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); } /** @@ -212,18 +190,11 @@ protected function getItems() * Initialize data array * * @return void - * @throws \InvalidArgumentException */ protected function initData() { if ($this->data === null) { - $layoutCacheKey = __CLASS__; - if ($data = $this->layoutCache->load($layoutCacheKey)) { - $this->data = $this->serializer->unserialize($data); - } else { - $this->data = $this->read(); - $this->layoutCache->save($this->serializer->serialize($this->data), $layoutCacheKey); - } + $this->data = $this->read(); } } From 5994f8e1b3aa40a4320ae4a634cdfa3da42183b6 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Tue, 20 Nov 2018 10:49:55 -0600 Subject: [PATCH 1288/1415] MAGETWO-96463: Add caching to improve admin performance - refactor fix in \Magento\Framework\Config\View --- .../Magento/Framework/Config/View.php | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 05863caeec2b6..6ae6556a8d2b6 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -5,6 +5,11 @@ */ namespace Magento\Framework\Config; +use Magento\Framework\App\Cache\Type\Layout as LayoutCache; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Serialize\Serializer\Json; + /** * View configuration files handler * @@ -24,6 +29,21 @@ class View extends \Magento\Framework\Config\Reader\Filesystem */ protected $data; + /** + * @var LayoutCache + */ + private $layoutCache; + + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @var array + */ + private $scopedLayoutCache; + /** * @param FileResolverInterface $fileResolver * @param ConverterInterface $converter @@ -34,6 +54,8 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param string $domDocumentClass * @param string $defaultScope * @param array $xpath + * @param LayoutCache|null $layoutCache + * @param SerializerInterface|null $serializer */ public function __construct( FileResolverInterface $fileResolver, @@ -44,10 +66,13 @@ public function __construct( $idAttributes = [], $domDocumentClass = \Magento\Framework\Config\Dom::class, $defaultScope = 'global', - $xpath = [] + $xpath = [], + LayoutCache $layoutCache = null, + SerializerInterface $serializer = null ) { $this->xpath = $xpath; $idAttributes = $this->getIdAttributes(); + parent::__construct( $fileResolver, $converter, @@ -58,6 +83,8 @@ public function __construct( $domDocumentClass, $defaultScope ); + $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); + $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); } /** @@ -200,21 +227,34 @@ protected function initData() /** * {@inheritdoc} + * @throws \InvalidArgumentException * @since 100.1.0 */ public function read($scope = null) { $scope = $scope ?: $this->_defaultScope; - $result = []; + $layoutCacheKey = __CLASS__ . '-'. $scope . '-' . $this->_fileName; + if (!isset($this->scopedLayoutCache[$layoutCacheKey])) { + if ($data = $this->layoutCache->load($layoutCacheKey)) { + $this->scopedLayoutCache[$layoutCacheKey] = $this->serializer->unserialize($data); + } else { + $result = []; - $parents = (array)$this->_fileResolver->getParents($this->_fileName, $scope); - // Sort parents desc - krsort($parents); + $parents = (array)$this->_fileResolver->getParents($this->_fileName, $scope); + // Sort parents desc + krsort($parents); - foreach ($parents as $parent) { - $result = array_replace_recursive($result, $this->_readFiles([$parent])); - } + foreach ($parents as $parent) { + $result = array_replace_recursive($result, $this->_readFiles([$parent])); + } - return array_replace_recursive($result, parent::read($scope)); + $this->scopedLayoutCache[$layoutCacheKey] = array_replace_recursive($result, parent::read($scope)); + $this->layoutCache->save( + $this->serializer->serialize($this->scopedLayoutCache[$layoutCacheKey]), + $layoutCacheKey + ); + } + } + return $this->scopedLayoutCache[$layoutCacheKey]; } } From 915e27335f3ff3efa2b72ab23ed268460452eff7 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 14:11:48 -0600 Subject: [PATCH 1289/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 --- app/code/Magento/Config/App/Config/Type/System.php | 2 ++ .../tests/app/Magento/Install/Test/TestCase/InstallTest.xml | 2 +- lib/internal/Magento/Framework/Config/View.php | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index c692017573fba..ce02a5271c456 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -23,6 +23,7 @@ * * @api * @since 100.1.2 + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class System implements ConfigTypeInterface { @@ -88,6 +89,7 @@ class System implements ConfigTypeInterface * @param Encryptor|null $encryptorFilter * * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ public function __construct( ConfigSourceInterface $source, diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml index 2b407e3d39200..647e610b02221 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml +++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml @@ -17,7 +17,7 @@ <variation name="InstallTestVariation2" firstConstraint="Magento\Install\Test\Constraint\AssertSuccessInstall" summary="Install with custom encryption key and changed currency and locale"> <data name="user/dataset" xsi:type="string">default</data> <data name="install/keyOwn" xsi:type="string">I want to use my own encryption key</data> - <data name="install/keyValue" xsi:type="string">123123qa</data> + <data name="install/keyValue" xsi:type="string">I_want_to_use_my_own_encryption_key</data> <data name="install/storeLanguage" xsi:type="string">German (Germany)</data> <data name="install/storeCurrency" xsi:type="string">Euro (EUR)</data> <data name="currencySymbol" xsi:type="string">€</data> diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 6ae6556a8d2b6..1dc96e2bde8a1 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -226,7 +226,8 @@ protected function initData() } /** - * {@inheritdoc} + * @inheritdoc + * * @throws \InvalidArgumentException * @since 100.1.0 */ From 7d32216f650fd8d957400af722a8d3bb43206e1c Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 14:19:48 -0600 Subject: [PATCH 1290/1415] MAGETWO-96463: Add caching of View Configuration --- .../Product/Type/Configurable/Product/Collection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php index 1460cc516811e..98e3f3e876dd0 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php @@ -73,9 +73,9 @@ public function setProductFilter($product) * * @return $this */ - protected function _beforeLoad() + protected function _renderFilters() { - parent::_beforeLoad(); + parent::_renderFilters(); $metadata = $this->getProductEntityMetadata(); $parentIds = []; foreach ($this->products as $product) { From d32b641bf970ead159561d782ed1b0069ac052ff Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 14:53:00 -0600 Subject: [PATCH 1291/1415] MAGETWO-96463: Add caching of View Configuration --- .../Product/Type/Configurable/Product/Collection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php index 98e3f3e876dd0..3124a3b8cf0ed 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Product/Collection.php @@ -41,6 +41,7 @@ protected function _construct() /** * Init select + * * @return $this|\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection */ protected function _initSelect() @@ -88,8 +89,7 @@ protected function _renderFilters() } /** - * Retrieve is flat enabled flag - * Return always false if magento run admin + * Retrieve is flat enabled flag. Return always false if magento run admin * * @return bool */ From d791b361c6f108b583eacfa4ca1e9ba9f72a1646 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Tue, 20 Nov 2018 15:14:32 -0600 Subject: [PATCH 1292/1415] MC-5318: Create tax rate, all postcodes - addressing code review comments --- .../Mftf/Section/AdminTaxRateFormSection.xml | 9 ++++--- .../Mftf/Section/AdminTaxRateGridSection.xml | 1 + .../Mftf/Section/AdminTaxRulesSection.xml | 2 -- .../AdminCreateTaxRateAllPostCodesTest.xml | 25 +++++++++---------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml index 580ce8cb485fb..53a3393ceb43d 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml @@ -9,13 +9,16 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminTaxRateFormSection"> - <element name="taxIdentifier" type="input" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> - <element name="labelForZipCode" type="text" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> + <element name="taxIdentifier" type="input" selector="#code" /> + <element name="labelForZipCode" type="text" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> <element name="deleteRate" type="button" selector="#delete"/> <element name="ok" type="button" selector="button.action-primary.action-accept"/> - + <element name="save" type="button" selector="#save"/> <element name="country" type="select" selector="#tax_country_id"/> <element name="state" type="select" selector="#tax_region_id"/> <element name="rate" type="text" selector="#rate"/> + <element name="success" type="text" selector="#messages-message-success"/> + <element name="successMessage" type="text" selector=".message-success"/> + <element name="errorMessage" type="text" selector=".message.message-error.error"/> </section> </sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml index daa86c5216219..5df1f9c4ba245 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml @@ -17,5 +17,6 @@ <element name="filterByPostCode" type="input" selector="#tax_rate_grid_filter_tax_postcode"/> <element name="nthRow" type="block" selector="tr[data-role='row']:nth-of-type({{var}})" parameterized="true" timeout="30"/> <element name="country" type="select" selector="#tax_country_id"/> + <element name="zipCode" type="input" selector="#tax_postcode"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml index 04d0d7f766eef..8eb2a111446ca 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml @@ -9,14 +9,12 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminTaxRulesSection"> - <!-- on page /admin/tax/rule/new/ --> <element name="ruleName" type="input" selector="#anchor-content #code"/> <element name="addNewTaxRate" type="block" selector="//*[text()='Add New Tax Rate']" timeout="30"/> <element name="taxIdentifier" type="input" selector="aside #code"/> <element name="zipIsRange" type="checkbox" selector="#zip_is_range"/> <element name="zipCode" type="input" selector="#tax_postcode"/> <element name="state" type="select" selector="#tax_region_id"/> - <element name="country" type="select" selector="#tax_country_id"/> <element name="rate" type="input" selector="#rate"/> <element name="save" type="button" selector=".action-save" timeout="30"/> <element name="saveRule" type="button" selector="#save" timeout="30"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml index 40146a8632368..cc1482a077f9b 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml @@ -13,6 +13,7 @@ <stories value="Create tax rate"/> <title value="Create tax rate, all postcodes"/> <description value="Tests log into Create tax rate and create all postcodes"/> + <testCaseId value="MC-5318"/> <severity value="CRITICAL"/> <group value="tax"/> <group value="mtf_migrated"/> @@ -23,25 +24,23 @@ </before> <after> <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> - <click selector="{{AdminTaxRateGridSection.clearFilters}}" stepKey="clickClearFilters2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> - <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the tax rate." stepKey="seeSuccess"/> </after> <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> <waitForPageLoad stepKey="waitForTaxRateIndex1"/> - <!-- Create a tax rate with * for postcodes --> - <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddButton"/> - <fillField selector="{{AdminTaxRateFormSection.ruleName}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> - <fillField selector="{{AdminTaxRateSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> - <selectOption selector="{{AdminTaxRateSection.country}}" userInput="Australia" stepKey="selectCountry"/> - <fillField selector="{{AdminTaxRateSection.rate}}" userInput="20" stepKey="fillRate"/> - <click selector="{{AdminTaxRateSection.saveRule}}" stepKey="clickSave"/> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> + <fillField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="Australia" stepKey="selectCountry1"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="20" stepKey="fillRate"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> <!-- Verify the tax rate grid page shows the tax rate we just created --> @@ -65,10 +64,10 @@ <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> <!-- Verify we see expected values on the tax rate edit page --> - <seeInField selector="{{AdminTaxRateFormSection.ruleName}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRuleName2"/> - <seeInField selector="{{AdminTaxRateSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> - <seeOptionIsSelected selector="{{AdminTaxRateSection.country}}" userInput="Australia" stepKey="seeCountry2"/> - <seeInField selector="{{AdminTaxRateSection.rate}}" userInput="20" stepKey="seeRate"/> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRuleName2"/> + <seeInField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> + <seeOptionIsSelected selector="{{AdminTaxRateGridSection.country}}" userInput="Australia" stepKey="seeCountry2"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="20" stepKey="seeRate"/> <!-- Go to the tax rule grid page and verify our tax rate can be used in the rule --> <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> From 273bb398250433bc6302e033690d389f8e6a6515 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 15:23:14 -0600 Subject: [PATCH 1293/1415] MAGETWO-96463: Add caching of View Configuration --- app/code/Magento/Config/App/Config/Type/System.php | 2 +- lib/internal/Magento/Framework/Config/View.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index ce02a5271c456..c8d322b678460 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -89,7 +89,7 @@ class System implements ConfigTypeInterface * @param Encryptor|null $encryptorFilter * * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( ConfigSourceInterface $source, diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 1dc96e2bde8a1..a39750a562f00 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -56,6 +56,7 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param array $xpath * @param LayoutCache|null $layoutCache * @param SerializerInterface|null $serializer + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( FileResolverInterface $fileResolver, From 658526798b773cbbf485276a3e6bf3dc7c86b230 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Tue, 20 Nov 2018 15:35:29 -0600 Subject: [PATCH 1294/1415] MC-5318: Create tax rate, all postcodes - addressing code review comments --- .../Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml | 4 ---- .../Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml | 1 - 2 files changed, 5 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml index 53a3393ceb43d..913d8135762bb 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml @@ -10,15 +10,11 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminTaxRateFormSection"> <element name="taxIdentifier" type="input" selector="#code" /> - <element name="labelForZipCode" type="text" selector="//*[@id = 'rate-form']//*[@name = 'code']" /> <element name="deleteRate" type="button" selector="#delete"/> <element name="ok" type="button" selector="button.action-primary.action-accept"/> <element name="save" type="button" selector="#save"/> <element name="country" type="select" selector="#tax_country_id"/> <element name="state" type="select" selector="#tax_region_id"/> <element name="rate" type="text" selector="#rate"/> - <element name="success" type="text" selector="#messages-message-success"/> - <element name="successMessage" type="text" selector=".message-success"/> - <element name="errorMessage" type="text" selector=".message.message-error.error"/> </section> </sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml index cc1482a077f9b..f4b1066dae2e2 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml @@ -17,7 +17,6 @@ <severity value="CRITICAL"/> <group value="tax"/> <group value="mtf_migrated"/> - <group value="banana"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 1be3e83d60efe7e4dbc998b1024340853fd559cb Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 20 Nov 2018 15:46:13 -0600 Subject: [PATCH 1295/1415] MQE-1187: Fix MFTF skipped tests - Added to PageBuilderDisabled suite --- .../Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml index 53a4ccb608a6d..32bea8b604cf8 100644 --- a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml @@ -17,6 +17,7 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-94479"/> <group value="CatalogWidget"/> + <group value="WYSIWYGDisabled"/> </annotations> <before> From a903e8c6caad41a1d76b39f2288c8034089de9a7 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Tue, 20 Nov 2018 16:30:10 -0600 Subject: [PATCH 1296/1415] MAGETWO-96463: Add caching to improve admin performance - refactor fix in \Magento\Framework\Config\View --- lib/internal/Magento/Framework/Config/View.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index a39750a562f00..1cb008dc8fed8 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -9,6 +9,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Serialize\Serializer\Json; +use Magento\Framework\View\DesignInterface; /** * View configuration files handler @@ -44,6 +45,11 @@ class View extends \Magento\Framework\Config\Reader\Filesystem */ private $scopedLayoutCache; + /** + * @var DesignInterface + */ + private $design; + /** * @param FileResolverInterface $fileResolver * @param ConverterInterface $converter @@ -56,6 +62,7 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param array $xpath * @param LayoutCache|null $layoutCache * @param SerializerInterface|null $serializer + * @param DesignInterface|null $design * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -69,7 +76,8 @@ public function __construct( $defaultScope = 'global', $xpath = [], LayoutCache $layoutCache = null, - SerializerInterface $serializer = null + SerializerInterface $serializer = null, + DesignInterface $design = null ) { $this->xpath = $xpath; $idAttributes = $this->getIdAttributes(); @@ -86,6 +94,7 @@ public function __construct( ); $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); + $this->design = $design ?? ObjectManager::getInstance()->get(DesignInterface::class); } /** @@ -235,7 +244,7 @@ protected function initData() public function read($scope = null) { $scope = $scope ?: $this->_defaultScope; - $layoutCacheKey = __CLASS__ . '-'. $scope . '-' . $this->_fileName; + $layoutCacheKey = __CLASS__ . '-'. $scope . '-' . $this->_fileName . '-' . $this->design->getArea(); if (!isset($this->scopedLayoutCache[$layoutCacheKey])) { if ($data = $this->layoutCache->load($layoutCacheKey)) { $this->scopedLayoutCache[$layoutCacheKey] = $this->serializer->unserialize($data); From a730682c4c19932737fe51ea5355aa6068ed6ce0 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 16:36:32 -0600 Subject: [PATCH 1297/1415] MC-5538: Search terms are not cached in case of form_key present in the request --- .../Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml | 1 + lib/web/mage/common.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml index 7ca86b8b14a4d..ac399b2a16292 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml @@ -16,6 +16,7 @@ <submitForm selector="#search_mini_form" parameterArray="['q' => '{{phrase}}']" stepKey="fillQuickSearch" /> <seeInCurrentUrl url="{{StorefrontCatalogSearchPage.url}}" stepKey="checkUrl"/> <seeInTitle userInput="Search results for: '{{phrase}}'" stepKey="assertQuickSearchTitle"/> + <dontSeeInCurrentUrl url="form_key=" stepKey="checkUrlFormKey"/> <see userInput="Search results for: '{{phrase}}'" selector="{{StorefrontCatalogSearchMainSection.SearchTitle}}" stepKey="assertQuickSearchName"/> </actionGroup> diff --git a/lib/web/mage/common.js b/lib/web/mage/common.js index 4742c77ea8627..01f696ec1b7fc 100644 --- a/lib/web/mage/common.js +++ b/lib/web/mage/common.js @@ -21,7 +21,7 @@ define([ form = $(e.target), formKey = $('input[name="form_key"]').val(); - if (formKey && !form.find('input[name="form_key"]').length) { + if (formKey && !form.find('input[name="form_key"]').length && form[0].method !== 'get') { formKeyElement = document.createElement('input'); formKeyElement.setAttribute('type', 'hidden'); formKeyElement.setAttribute('name', 'form_key'); From f24b02f24fd875b44180d1e385a256e40e40e512 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 16:49:59 -0600 Subject: [PATCH 1298/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 - fix sample data tests --- .../tests/app/Magento/Install/Test/TestCase/InstallTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml index 647e610b02221..520bd41f82e10 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml +++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml @@ -17,7 +17,7 @@ <variation name="InstallTestVariation2" firstConstraint="Magento\Install\Test\Constraint\AssertSuccessInstall" summary="Install with custom encryption key and changed currency and locale"> <data name="user/dataset" xsi:type="string">default</data> <data name="install/keyOwn" xsi:type="string">I want to use my own encryption key</data> - <data name="install/keyValue" xsi:type="string">I_want_to_use_my_own_encryption_key</data> + <data name="install/keyValue" xsi:type="string">I_want_to_use_my_own_encryption</data> <data name="install/storeLanguage" xsi:type="string">German (Germany)</data> <data name="install/storeCurrency" xsi:type="string">Euro (EUR)</data> <data name="currencySymbol" xsi:type="string">€</data> From 2d27feea97ce1ce741be77ca4dbf5ee9adf333cf Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 18:04:47 -0600 Subject: [PATCH 1299/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 --- .../Model/Product/Attribute/Source/Layout.php | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php index caae962cc309e..d757044cc2a72 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php @@ -7,8 +7,6 @@ use Magento\Framework\App\Cache\Type\Layout as LayoutCache; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Json; /** * Catalog product landing page attribute source @@ -25,44 +23,36 @@ class Layout extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ private $layoutCache; - /** - * @var SerializerInterface - */ - private $serializer; - /** * @param \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder * @param LayoutCache|null $layoutCache - * @param SerializerInterface|null $serializer */ public function __construct( \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder, - LayoutCache $layoutCache = null, - SerializerInterface $serializer = null + LayoutCache $layoutCache = null ) { $this->pageLayoutBuilder = $pageLayoutBuilder; $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); - $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); } /** * Get list of available layouts * * @return array - * @throws \InvalidArgumentException */ public function getAllOptions() { if (!$this->_options) { $layoutCacheKey = __CLASS__; if ($data = $this->layoutCache->load($layoutCacheKey)) { - return $this->_options = $this->serializer->unserialize($data); + return $this->_options = unserialize($data); } else { $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); - $this->layoutCache->save($this->serializer->serialize($this->_options), $layoutCacheKey); + array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); + $this->layoutCache->save(serialize($this->_options), $layoutCacheKey); } + } - array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); return $this->_options; } } From 42a857a696d28e97c9ecdf03d8b15a64f189b349 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Tue, 20 Nov 2018 20:17:55 -0600 Subject: [PATCH 1300/1415] MAGETWO-96463: Add caching to improve admin performance - remove caching \Magento\Catalog\Model\Product\Attribute\Source\Layout --- .../Model/Product/Attribute/Source/Layout.php | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php index d757044cc2a72..63b1444d1db07 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Layout.php @@ -5,11 +5,10 @@ */ namespace Magento\Catalog\Model\Product\Attribute\Source; -use Magento\Framework\App\Cache\Type\Layout as LayoutCache; -use Magento\Framework\App\ObjectManager; - /** * Catalog product landing page attribute source + * + * @author Magento Core Team <core@magentocommerce.com> */ class Layout extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource { @@ -18,40 +17,22 @@ class Layout extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource */ protected $pageLayoutBuilder; - /** - * @var LayoutCache - */ - private $layoutCache; - /** * @param \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder - * @param LayoutCache|null $layoutCache */ - public function __construct( - \Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder, - LayoutCache $layoutCache = null - ) { + public function __construct(\Magento\Framework\View\Model\PageLayout\Config\BuilderInterface $pageLayoutBuilder) + { $this->pageLayoutBuilder = $pageLayoutBuilder; - $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); } /** - * Get list of available layouts - * * @return array */ public function getAllOptions() { if (!$this->_options) { - $layoutCacheKey = __CLASS__; - if ($data = $this->layoutCache->load($layoutCacheKey)) { - return $this->_options = unserialize($data); - } else { - $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); - array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); - $this->layoutCache->save(serialize($this->_options), $layoutCacheKey); - } - + $this->_options = $this->pageLayoutBuilder->getPageLayoutsConfig()->toOptionArray(); + array_unshift($this->_options, ['value' => '', 'label' => __('No layout updates')]); } return $this->_options; } From fe971c2480bab0a75134fb3cb286694a3b3c193d Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 20 Nov 2018 21:34:49 -0600 Subject: [PATCH 1301/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 --- .../Magento/Config/App/Config/Type/System.php | 8 +++---- .../Framework/Encryption/Encryptor.php | 21 +++++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index c8d322b678460..9be3205b6f8e7 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -267,12 +267,12 @@ private function loadScopeData($scopeType, $scopeId) private function cacheData(array $data) { $this->cache->save( - $this->encriptFilter->encrypt($this->serializer->serialize($data)), + $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data)), $this->configType, [self::CACHE_TAG] ); $this->cache->save( - $this->encriptFilter->encrypt($this->serializer->serialize($data['default'])), + $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data['default'])), $this->configType . '_default', [self::CACHE_TAG] ); @@ -281,14 +281,14 @@ private function cacheData(array $data) foreach ($data[$curScopeType] ?? [] as $curScopeId => $curScopeData) { $scopes[$curScopeType][$curScopeId] = 1; $this->cache->save( - $this->encriptFilter->encrypt($this->serializer->serialize($curScopeData)), + $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($curScopeData)), $this->configType . '_' . $curScopeType . '_' . $curScopeId, [self::CACHE_TAG] ); } } $this->cache->save( - $this->encriptFilter->encrypt($this->serializer->serialize($scopes)), + $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($scopes)), $this->configType . '_scopes', [self::CACHE_TAG] ); diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index a7d649894d6d5..8d46ee542b9ec 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -281,6 +281,21 @@ private function getPasswordVersion() * @return string */ public function encrypt($data) + { + $crypt = new SodiumChachaIetf($this->keys[$this->keyVersion]); + + return $this->keyVersion . + ':' . self::CIPHER_AEAD_CHACHA20POLY1305 . + ':' . base64_encode($crypt->encrypt($data)); + } + + /** + * Encrypt data using the fastest available algorithm + * + * @param string $data + * @return string + */ + public function encryptWithFastestAlgorithm($data) { $crypt = $this->getCrypt(); if (null === $crypt) { @@ -290,7 +305,6 @@ public function encrypt($data) ':' . $this->getCipherVersion() . ':' . base64_encode($crypt->encrypt($data)); } - /** * Look for key and crypt versions in encrypted data before decrypting * @@ -423,13 +437,16 @@ private function getCrypt( if ($cipherVersion === self::CIPHER_RIJNDAEL_128) { $cipher = MCRYPT_RIJNDAEL_128; + $mode = MCRYPT_MODE_ECB; } elseif ($cipherVersion === self::CIPHER_RIJNDAEL_256) { $cipher = MCRYPT_RIJNDAEL_256; + $mode = MCRYPT_MODE_CBC; } else { $cipher = MCRYPT_BLOWFISH; + $mode = MCRYPT_MODE_ECB; } - return new Mcrypt($key, $cipher, MCRYPT_MODE_ECB, $initVector); + return new Mcrypt($key, $cipher, $mode, $initVector); } /** From a35c21f4e2341ce938ef02eafe11f8365a5c98ef Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Wed, 21 Nov 2018 12:14:10 +0200 Subject: [PATCH 1302/1415] Merge branch '2.3-develop' of https://github.com/magento/magento2ce into MAGETWO-96024 # Conflicts: # app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml --- .../Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml index 8109230a364ad..fd1b6add8391f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml @@ -234,6 +234,7 @@ <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickChangeStatusAction"/> <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled" parameterized="true"/> <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> + <waitForLoadingMaskToDisappear stepKey="waitForMaskToDisappear"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> </actionGroup> </actionGroups> From bf64a3a810c96531caec423e80a1b0c99ccbdc2e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Wed, 21 Nov 2018 14:53:14 +0300 Subject: [PATCH 1303/1415] MAGETWO-91530: Expose Authorize.net Response Codes in Checkout - Fix static tests --- .../Payment/view/frontend/templates/transparent/iframe.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml index 35dbfe9622bea..afa71fe591495 100644 --- a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml @@ -40,7 +40,7 @@ $params = $block->getParams(); $(parent).trigger('clearTimeout'); fullScreenLoader.stopLoader(); globalMessageList.addErrorMessage({ - message: $t(<?=json_encode($params['error_msg'])?>) + message: $t(<?= /* @escapeNotVerified */ json_encode($params['error_msg'])?>) }); } ); From 969f2c2ddb2998c8ecf1cea312e3c483e3549e5c Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Wed, 21 Nov 2018 14:39:46 +0200 Subject: [PATCH 1304/1415] Fix the issue with repetitive "tbody" tag for order items table --- .../Magento/Sales/view/frontend/templates/order/items.phtml | 5 +++-- .../Magento/luma/Magento_Sales/web/css/source/_module.less | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml index e43d32760febb..dc179b6ee4ac1 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml @@ -29,9 +29,10 @@ </thead> <?php $items = $block->getItems(); ?> <?php $giftMessage = ''?> + <tbody> <?php foreach ($items as $item): ?> <?php if ($item->getParentItem()) continue; ?> - <tbody> + <?= $block->getItemHtml($item) ?> <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $item) && $item->getGiftMessageId()): ?> <?php $giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($item); ?> @@ -62,8 +63,8 @@ </td> </tr> <?php endif ?> - </tbody> <?php endforeach; ?> + </tbody> <tfoot> <?php if($block->isPagerDisplayed()): ?> <tr> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index a0f734b05cbd1..1e4a92fa0701f 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -612,10 +612,6 @@ padding: 25px; .col { - &.name { - padding-left: 0; - } - &.price { text-align: center; } From d445e48ecbec6d7288bd013c116f96d88610df05 Mon Sep 17 00:00:00 2001 From: Kajal Solanki <kajal.solanki@krishtechnolabs.com> Date: Wed, 21 Nov 2018 18:14:07 +0530 Subject: [PATCH 1305/1415] fix-issue-19286 in 2.3-develop branch --- app/design/frontend/Magento/luma/web/css/source/_extends.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/design/frontend/Magento/luma/web/css/source/_extends.less b/app/design/frontend/Magento/luma/web/css/source/_extends.less index 7c9f5b7a65ab4..ad677b45e52db 100644 --- a/app/design/frontend/Magento/luma/web/css/source/_extends.less +++ b/app/design/frontend/Magento/luma/web/css/source/_extends.less @@ -1506,6 +1506,10 @@ position: relative; z-index: 1; } + .limiter { + display: inline-block; + float: right; + } .toolbar-amount { .lib-css(line-height, @pager__line-height); From e940298f04b0dfbef5bb9efa1123ece974c32248 Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rain2o@gmail.com> Date: Wed, 21 Nov 2018 13:45:10 +0100 Subject: [PATCH 1306/1415] Fixed invalid reference to --- .../Model/ResourceModel/Product/Indexer/Eav/Source.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index f9fb8ec3bb338..b7489bff18a1f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -319,7 +319,7 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu /** * Get options for multiselect attributes using custom source models - * Based on @maderlock's fix from: + * Based on @maderlock's fix from: * https://github.com/magento/magento2/issues/417#issuecomment-265146285 * * @param array $attrIds @@ -334,7 +334,7 @@ private function getMultiSelectAttributeWithSourceModels($attrIds, $options) ->addFilter('attribute_id', $attrIds, 'in') ->addFilter('source_model', true, 'notnull'); $criteria = $this->criteriaBuilder->create(); - $attributes = $this->_attributeRepository->getList( + $attributes = $this->attributeRepository->getList( ProductAttributeInterface::ENTITY_TYPE_CODE, $criteria )->getItems(); From 6578102b6ed3ed60d03dbb0368b80321d35106cc Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Wed, 21 Nov 2018 08:46:57 -0600 Subject: [PATCH 1307/1415] MQE-1214: Investigate skipped AdminBasicBundleProductAttributesTest - Unskip the test --- .../Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml index 3a70b189b4dce..c6a07f7ed95c3 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml @@ -15,9 +15,6 @@ <description value="Admin should be able to set/edit all the basic product attributes when creating/editing a bundle product"/> <severity value="CRITICAL"/> <testCaseId value="MC-222"/> - <skip> - <issueId value="MQE-1214"/> - </skip> <group value="Bundle"/> </annotations> <before> From e8df41540b938b6bcb6fde3612d3262c8b2a7abe Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 21 Nov 2018 09:43:56 -0600 Subject: [PATCH 1308/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 --- .../tests/app/Magento/Install/Test/TestCase/InstallTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml index 520bd41f82e10..86906d4c09406 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml +++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml @@ -17,7 +17,7 @@ <variation name="InstallTestVariation2" firstConstraint="Magento\Install\Test\Constraint\AssertSuccessInstall" summary="Install with custom encryption key and changed currency and locale"> <data name="user/dataset" xsi:type="string">default</data> <data name="install/keyOwn" xsi:type="string">I want to use my own encryption key</data> - <data name="install/keyValue" xsi:type="string">I_want_to_use_my_own_encryption</data> + <data name="install/keyValue" xsi:type="string">I_want_to_use_my_own__encryption</data> <data name="install/storeLanguage" xsi:type="string">German (Germany)</data> <data name="install/storeCurrency" xsi:type="string">Euro (EUR)</data> <data name="currencySymbol" xsi:type="string">€</data> From 1dc10a9920ed39b69cf79450e845f2baf43e4e86 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Wed, 21 Nov 2018 09:53:46 -0600 Subject: [PATCH 1309/1415] MAGETWO-96463: Add caching to improve admin performance - fix integration test --- .../testsuite/Magento/Theme/Model/View/DesignTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php index dce99d05416d0..bd9af4c213e3e 100644 --- a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php @@ -203,6 +203,8 @@ public function testGetConfigCustomized() <view><vars module="Namespace_Module"><var name="customVar">custom value</var></vars></view>' ); + \Magento\TestFramework\Helper\CacheCleaner::cleanAll(); + $config = $this->_viewConfig->getViewConfig(); $this->assertInstanceOf(\Magento\Framework\Config\View::class, $config); $this->assertEquals(['customVar' => 'custom value'], $config->getVars('Namespace_Module')); From f8609953c3e5e0de7fdd408c3640c66192ba8796 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <kopylova@adobe.com> Date: Wed, 21 Nov 2018 08:39:33 -0800 Subject: [PATCH 1310/1415] MAGETWO-96314: Fix performance on MAGETWO-81469 - fixed unit test --- .../Encryption/Test/Unit/EncryptorTest.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php index 3c1b4395bd064..f2f9f16068174 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php @@ -109,6 +109,7 @@ public function validateHashDataProvider() * @param mixed $key * * @dataProvider encryptWithEmptyKeyDataProvider + * @expectedException \SodiumException */ public function testEncryptWithEmptyKey($key) { @@ -161,8 +162,14 @@ public function testEncrypt() $data = 'Mares eat oats and does eat oats, but little lambs eat ivy.'; $actual = $this->_model->encrypt($data); + + // Extract the initialization vector and encrypted data + $parts = explode(':', $actual, 3); + list(, , $encryptedData) = $parts; + + $crypt = new SodiumChachaIetf(self::CRYPT_KEY_1); // Verify decrypted matches original data - $this->assertEquals($data, $this->_model->decrypt($actual)); + $this->assertEquals($data, $crypt->decrypt(base64_decode((string)$encryptedData))); } public function testDecrypt() @@ -186,7 +193,7 @@ public function testLegacyDecrypt() list(, , $iv, $encrypted) = $parts; // Decrypt returned data with RIJNDAEL_256 cipher, cbc mode - $crypt = new Crypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB, $iv); + $crypt = new Crypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC, $iv); // Verify decrypted matches original data $this->assertEquals($encrypted, base64_encode($crypt->encrypt($actual))); } @@ -217,7 +224,7 @@ public function testEncryptDecryptNewKeyAdded() public function testValidateKey() { - $this->assertNull($this->_model->validateKey(self::CRYPT_KEY_1)); + $this->_model->validateKey(self::CRYPT_KEY_1); } /** @@ -259,3 +266,4 @@ public function testGetHashMustUseSpecifiedHashingAlgo($password, $salt, $hashAl $this->assertEquals($expected, $hash); } } + From ba006c02d3bc7dc0dc71553c991f66b6364f138d Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Wed, 21 Nov 2018 18:02:08 +0100 Subject: [PATCH 1311/1415] Removed $this->setShowGlobalIcon(); --- app/code/Magento/Backend/Block/Widget/Form.php | 1 - .../Product/Edit/Action/Attribute/Tab/Attributes.php | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/app/code/Magento/Backend/Block/Widget/Form.php b/app/code/Magento/Backend/Block/Widget/Form.php index 59b5cc060cc05..38d5d90a22d15 100644 --- a/app/code/Magento/Backend/Block/Widget/Form.php +++ b/app/code/Magento/Backend/Block/Widget/Form.php @@ -59,7 +59,6 @@ protected function _construct() parent::_construct(); $this->setDestElementId('edit_form'); - $this->setShowGlobalIcon(false); } /** diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Attributes.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Attributes.php index a08142c10be5e..2df0ff0b6cd7c 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Attributes.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Attributes.php @@ -64,17 +64,6 @@ public function __construct( parent::__construct($context, $registry, $formFactory, $data); } - /** - * Construct block - * - * @return void - */ - protected function _construct() - { - parent::_construct(); - $this->setShowGlobalIcon(true); - } - /** * Prepares form * From 2cf2d99245703dc7336429da642eed5001bf9b10 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Wed, 21 Nov 2018 11:09:18 -0600 Subject: [PATCH 1312/1415] MQE-1187: Fix MFTF skipped tests - Change DEVOPS ticket to MQE-1328 due to incorrect skip tagging. --- .../Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml | 10 +++++----- .../Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml | 2 +- .../Mftf/Test/StorefrontInactiveCatalogRuleTest.xml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml index 716a363ec5d78..c8f42213b094c 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml @@ -17,7 +17,7 @@ <testCaseId value="MC-74"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml index 072385c46645a..6302ae20407ac 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-65"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> @@ -78,7 +78,7 @@ <testCaseId value="MC-93"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> @@ -104,7 +104,7 @@ <testCaseId value="MC-69"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> @@ -130,7 +130,7 @@ <testCaseId value="MC-60"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> @@ -156,7 +156,7 @@ <testCaseId value="MC-71"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml index 83770ffff5eab..ca14315300dbb 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-160"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index 55f775e40feaa..aa424b735b179 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-79"/> <group value="CatalogRule"/> <skip> - <issueId value="DEVOPS-3618"/> + <issueId value="MQE-1328"/> </skip> </annotations> <before> From 6bc291d5bbe7f9a4bd2717088c3d62b198c5fbe0 Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Wed, 21 Nov 2018 11:22:53 -0600 Subject: [PATCH 1313/1415] MAGETWO-96463: Add caching to improve admin performance - make cache key more unique --- lib/internal/Magento/Framework/Config/View.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 1cb008dc8fed8..5bfaeab2e37ad 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -244,7 +244,16 @@ protected function initData() public function read($scope = null) { $scope = $scope ?: $this->_defaultScope; - $layoutCacheKey = __CLASS__ . '-'. $scope . '-' . $this->_fileName . '-' . $this->design->getArea(); + $layoutCacheKey = implode( + '-', + [ + __CLASS__, + $scope, + $this->_fileName, + $this->design->getArea(), + $this->serializer->serialize($this->xpath) + ] + ); if (!isset($this->scopedLayoutCache[$layoutCacheKey])) { if ($data = $this->layoutCache->load($layoutCacheKey)) { $this->scopedLayoutCache[$layoutCacheKey] = $this->serializer->unserialize($data); From 312cd809b49b569ad0b5900504c4dec76c573cbd Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Thu, 15 Nov 2018 15:03:44 -0600 Subject: [PATCH 1314/1415] MAGETWO-96385: Deleting address on frontend redirects to 404 Page --- app/code/Magento/Customer/Controller/Address/Delete.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php index a4a0944137e1b..a30e15db4b3f8 100644 --- a/app/code/Magento/Customer/Controller/Address/Delete.php +++ b/app/code/Magento/Customer/Controller/Address/Delete.php @@ -6,11 +6,16 @@ */ namespace Magento\Customer\Controller\Address; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Action\HttpPostActionInterface; -class Delete extends \Magento\Customer\Controller\Address implements HttpPostActionInterface +/** + * Delete customer address controller action. + */ +class Delete extends \Magento\Customer\Controller\Address implements HttpPostActionInterface, HttpGetActionInterface { /** + * @inheritdoc * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() From 61cff0630764413173286f3423ba905184a8e1a2 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Tue, 20 Nov 2018 15:29:34 -0600 Subject: [PATCH 1315/1415] MAGETWO-96385: Deleting address on frontend redirects to 404 Page - added test to cover bug fix --- .../StorefrontCustomerAddressModalSection.xml | 15 +++++++ .../StorefrontCustomerAddressSection.xml | 14 +++++++ .../StorefrontDeleteCustomerAddressTest.xml | 42 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml new file mode 100644 index 0000000000000..5cdf7dfea5483 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCustomerAddressConfirmationModalSection"> + <element name="message" type="text" selector="aside.confirm div.modal-content"/> + <element name="ok" type="button" selector="aside.confirm .modal-footer .action-primary"/> + <element name="cancel" type="button" selector="aside.confirm .modal-footer .action-secondary"/> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml new file mode 100644 index 0000000000000..02ff60dc2c169 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="StorefrontCustomerAddressSection"> + <element name="deleteAdditionalAddress" type="button" selector=".action.delete" timeout="30"/> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml new file mode 100644 index 0000000000000..59f945c917420 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontDeleteCustomerAddressTest"> + <annotations> + <stories value="Delete customer address from storefront"/> + <title value="User should be able to delete Customer address successfully from storefront"/> + <description value="Admin should be able to reset customer password"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-5713"/> + <group value="Customer"/> + </annotations> + <before> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + </before> + <after> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage stepKey="amOnSignInPage" url="{{StorefrontCustomerSignInPage.url}}"/> + <fillField stepKey="fillEmail" userInput="$$createCustomer.email$$" selector="{{StorefrontCustomerSignInFormSection.emailField}}"/> + <fillField stepKey="fillPassword" userInput="$$createCustomer.password$$" selector="{{StorefrontCustomerSignInFormSection.passwordField}}"/> + <click stepKey="clickSignInAccountButton" selector="{{StorefrontCustomerSignInFormSection.signInAccountButton}}"/> + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + <see userInput="You saved the address." stepKey="verifyAddressCreated"/> + <click selector="{{StorefrontCustomerAddressSection.deleteAdditionalAddress}}" stepKey="deleteAdditionalAddress"/> + <waitForElementVisible selector="{{StorefrontCustomerAddressConfirmationModalSection.message}}" stepKey="waitFortheConfirmationModal"/> + <see selector="{{StorefrontCustomerAddressConfirmationModalSection.message}}" userInput="Are you sure you want to delete this address?" stepKey="seeAddressDeleteConfirmationMessage"/> + <click selector="{{StorefrontCustomerAddressConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="waitForDeleteToFinish"/> + <see userInput="You deleted the address." stepKey="verifyDeleteAddress"/> + </test> +</tests> From 2702e23c36aa7dcf24da56a47074f944046069e6 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Tue, 20 Nov 2018 15:31:36 -0600 Subject: [PATCH 1316/1415] MAGETWO-96385: Deleting address on frontend redirects to 404 Page - fixed annotation --- .../Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml index 59f945c917420..db560773a87f6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml @@ -12,7 +12,7 @@ <annotations> <stories value="Delete customer address from storefront"/> <title value="User should be able to delete Customer address successfully from storefront"/> - <description value="Admin should be able to reset customer password"/> + <description value="User should be able to delete Customer address successfully from storefront"/> <severity value="CRITICAL"/> <testCaseId value="MC-5713"/> <group value="Customer"/> From 1ac809fc72d5e0b0b85fe639d55eb95feb422890 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 21 Nov 2018 13:43:25 -0600 Subject: [PATCH 1317/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 --- .../Magento/Config/App/Config/Type/System.php | 20 +++++++++---------- .../Patch/Data/SodiumChachaPatchTest.php | 15 +------------- .../Encryption/Test/Unit/EncryptorTest.php | 1 - 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 9be3205b6f8e7..bf93bb581d5b4 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -74,7 +74,7 @@ class System implements ConfigTypeInterface /** * @var \Magento\Framework\Filter\Encrypt\AdapterInterface */ - private $encriptFilter; + private $encryptorFilter; /** * @param ConfigSourceInterface $source @@ -108,7 +108,7 @@ public function __construct( $this->serializer = $serializer; $this->configType = $configType; $this->reader = $reader ?: ObjectManager::getInstance()->get(Reader::class); - $this->encriptFilter = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); + $this->encryptorFilter = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); } /** @@ -198,7 +198,7 @@ private function loadAllData() if ($cachedData === false) { $data = $this->readData(); } else { - $data = $this->serializer->unserialize($this->encriptFilter->decrypt($cachedData)); + $data = $this->serializer->unserialize($this->encryptorFilter->decrypt($cachedData)); } return $data; @@ -218,7 +218,7 @@ private function loadDefaultScopeData($scopeType) $data = $this->readData(); $this->cacheData($data); } else { - $data = [$scopeType => $this->serializer->unserialize($this->encriptFilter->decrypt($cachedData))]; + $data = [$scopeType => $this->serializer->unserialize($this->encryptorFilter->decrypt($cachedData))]; } return $data; @@ -239,7 +239,7 @@ private function loadScopeData($scopeType, $scopeId) if ($this->availableDataScopes === null) { $cachedScopeData = $this->cache->load($this->configType . '_scopes'); if ($cachedScopeData !== false) { - $serializedCachedData = $this->encriptFilter->decrypt($cachedScopeData); + $serializedCachedData = $this->encryptorFilter->decrypt($cachedScopeData); $this->availableDataScopes = $this->serializer->unserialize($serializedCachedData); } } @@ -249,7 +249,7 @@ private function loadScopeData($scopeType, $scopeId) $data = $this->readData(); $this->cacheData($data); } else { - $serializedCachedData = $this->encriptFilter->decrypt($cachedData); + $serializedCachedData = $this->encryptorFilter->decrypt($cachedData); $data = [$scopeType => [$scopeId => $this->serializer->unserialize($serializedCachedData)]]; } @@ -267,12 +267,12 @@ private function loadScopeData($scopeType, $scopeId) private function cacheData(array $data) { $this->cache->save( - $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data)), + $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data)), $this->configType, [self::CACHE_TAG] ); $this->cache->save( - $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data['default'])), + $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data['default'])), $this->configType . '_default', [self::CACHE_TAG] ); @@ -281,14 +281,14 @@ private function cacheData(array $data) foreach ($data[$curScopeType] ?? [] as $curScopeId => $curScopeData) { $scopes[$curScopeType][$curScopeId] = 1; $this->cache->save( - $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($curScopeData)), + $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($curScopeData)), $this->configType . '_' . $curScopeType . '_' . $curScopeId, [self::CACHE_TAG] ); } } $this->cache->save( - $this->encriptFilter->encryptWithFastestAlgorithm($this->serializer->serialize($scopes)), + $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($scopes)), $this->configType . '_scopes', [self::CACHE_TAG] ); diff --git a/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php b/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php index 8843f3ce7236e..3a47692bdb932 100644 --- a/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php +++ b/dev/tests/integration/testsuite/Magento/EncryptionKey/Setup/Patch/Data/SodiumChachaPatchTest.php @@ -93,19 +93,6 @@ private function legacyEncrypt(string $data): string @mcrypt_module_close($handle); // @codingStandardsIgnoreEnd - return '0:' . $this->getCipherVersion() . ':' . base64_encode($encrpted); - } - - /** - * Get cipher version - * - * @return int - */ - private function getCipherVersion() - { - if (extension_loaded('sodium')) { - return Encryptor::CIPHER_LATEST; - } - return Encryptor::CIPHER_RIJNDAEL_256; + return '0:' . Encryptor::CIPHER_RIJNDAEL_256 . ':' . base64_encode($encrpted); } } diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php index f2f9f16068174..98bb1c5676d6c 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php @@ -266,4 +266,3 @@ public function testGetHashMustUseSpecifiedHashingAlgo($password, $salt, $hashAl $this->assertEquals($expected, $hash); } } - From b916baecc30639837df2df31a7e0c8e14a9a03da Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Wed, 21 Nov 2018 14:04:25 -0600 Subject: [PATCH 1318/1415] MAGETWO-96463: Add caching to improve admin performance - remove caching in view config --- .../Magento/Theme/Model/View/DesignTest.php | 2 - .../Magento/Framework/Config/View.php | 80 +++---------------- 2 files changed, 10 insertions(+), 72 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php index bd9af4c213e3e..dce99d05416d0 100644 --- a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php @@ -203,8 +203,6 @@ public function testGetConfigCustomized() <view><vars module="Namespace_Module"><var name="customVar">custom value</var></vars></view>' ); - \Magento\TestFramework\Helper\CacheCleaner::cleanAll(); - $config = $this->_viewConfig->getViewConfig(); $this->assertInstanceOf(\Magento\Framework\Config\View::class, $config); $this->assertEquals(['customVar' => 'custom value'], $config->getVars('Namespace_Module')); diff --git a/lib/internal/Magento/Framework/Config/View.php b/lib/internal/Magento/Framework/Config/View.php index 5bfaeab2e37ad..05863caeec2b6 100644 --- a/lib/internal/Magento/Framework/Config/View.php +++ b/lib/internal/Magento/Framework/Config/View.php @@ -5,12 +5,6 @@ */ namespace Magento\Framework\Config; -use Magento\Framework\App\Cache\Type\Layout as LayoutCache; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\Serialize\Serializer\Json; -use Magento\Framework\View\DesignInterface; - /** * View configuration files handler * @@ -30,26 +24,6 @@ class View extends \Magento\Framework\Config\Reader\Filesystem */ protected $data; - /** - * @var LayoutCache - */ - private $layoutCache; - - /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @var array - */ - private $scopedLayoutCache; - - /** - * @var DesignInterface - */ - private $design; - /** * @param FileResolverInterface $fileResolver * @param ConverterInterface $converter @@ -60,10 +34,6 @@ class View extends \Magento\Framework\Config\Reader\Filesystem * @param string $domDocumentClass * @param string $defaultScope * @param array $xpath - * @param LayoutCache|null $layoutCache - * @param SerializerInterface|null $serializer - * @param DesignInterface|null $design - * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( FileResolverInterface $fileResolver, @@ -74,14 +44,10 @@ public function __construct( $idAttributes = [], $domDocumentClass = \Magento\Framework\Config\Dom::class, $defaultScope = 'global', - $xpath = [], - LayoutCache $layoutCache = null, - SerializerInterface $serializer = null, - DesignInterface $design = null + $xpath = [] ) { $this->xpath = $xpath; $idAttributes = $this->getIdAttributes(); - parent::__construct( $fileResolver, $converter, @@ -92,9 +58,6 @@ public function __construct( $domDocumentClass, $defaultScope ); - $this->layoutCache = $layoutCache ?? ObjectManager::getInstance()->get(LayoutCache::class); - $this->serializer = $serializer ?? ObjectManager::getInstance()->get(Json::class); - $this->design = $design ?? ObjectManager::getInstance()->get(DesignInterface::class); } /** @@ -236,45 +199,22 @@ protected function initData() } /** - * @inheritdoc - * - * @throws \InvalidArgumentException + * {@inheritdoc} * @since 100.1.0 */ public function read($scope = null) { $scope = $scope ?: $this->_defaultScope; - $layoutCacheKey = implode( - '-', - [ - __CLASS__, - $scope, - $this->_fileName, - $this->design->getArea(), - $this->serializer->serialize($this->xpath) - ] - ); - if (!isset($this->scopedLayoutCache[$layoutCacheKey])) { - if ($data = $this->layoutCache->load($layoutCacheKey)) { - $this->scopedLayoutCache[$layoutCacheKey] = $this->serializer->unserialize($data); - } else { - $result = []; - - $parents = (array)$this->_fileResolver->getParents($this->_fileName, $scope); - // Sort parents desc - krsort($parents); + $result = []; - foreach ($parents as $parent) { - $result = array_replace_recursive($result, $this->_readFiles([$parent])); - } + $parents = (array)$this->_fileResolver->getParents($this->_fileName, $scope); + // Sort parents desc + krsort($parents); - $this->scopedLayoutCache[$layoutCacheKey] = array_replace_recursive($result, parent::read($scope)); - $this->layoutCache->save( - $this->serializer->serialize($this->scopedLayoutCache[$layoutCacheKey]), - $layoutCacheKey - ); - } + foreach ($parents as $parent) { + $result = array_replace_recursive($result, $this->_readFiles([$parent])); } - return $this->scopedLayoutCache[$layoutCacheKey]; + + return array_replace_recursive($result, parent::read($scope)); } } From e9e8b673d5c7b494df01650433f6a7d6986eebbd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 21 Nov 2018 14:32:10 -0600 Subject: [PATCH 1319/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 - fix arch review --- .../Magento/Config/App/Config/Type/System.php | 22 +++++++++---------- .../Framework/Encryption/Encryptor.php | 2 +- .../Magento/Setup/Model/CryptKeyGenerator.php | 2 +- .../Test/Unit/Model/CryptKeyGeneratorTest.php | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index bf93bb581d5b4..99d85e0a10a32 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -72,9 +72,9 @@ class System implements ConfigTypeInterface private $availableDataScopes; /** - * @var \Magento\Framework\Filter\Encrypt\AdapterInterface + * @var Encryptor */ - private $encryptorFilter; + private $encryptor; /** * @param ConfigSourceInterface $source @@ -108,7 +108,7 @@ public function __construct( $this->serializer = $serializer; $this->configType = $configType; $this->reader = $reader ?: ObjectManager::getInstance()->get(Reader::class); - $this->encryptorFilter = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); + $this->encryptor = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); } /** @@ -198,7 +198,7 @@ private function loadAllData() if ($cachedData === false) { $data = $this->readData(); } else { - $data = $this->serializer->unserialize($this->encryptorFilter->decrypt($cachedData)); + $data = $this->serializer->unserialize($this->encryptor->decrypt($cachedData)); } return $data; @@ -218,7 +218,7 @@ private function loadDefaultScopeData($scopeType) $data = $this->readData(); $this->cacheData($data); } else { - $data = [$scopeType => $this->serializer->unserialize($this->encryptorFilter->decrypt($cachedData))]; + $data = [$scopeType => $this->serializer->unserialize($this->encryptor->decrypt($cachedData))]; } return $data; @@ -239,7 +239,7 @@ private function loadScopeData($scopeType, $scopeId) if ($this->availableDataScopes === null) { $cachedScopeData = $this->cache->load($this->configType . '_scopes'); if ($cachedScopeData !== false) { - $serializedCachedData = $this->encryptorFilter->decrypt($cachedScopeData); + $serializedCachedData = $this->encryptor->decrypt($cachedScopeData); $this->availableDataScopes = $this->serializer->unserialize($serializedCachedData); } } @@ -249,7 +249,7 @@ private function loadScopeData($scopeType, $scopeId) $data = $this->readData(); $this->cacheData($data); } else { - $serializedCachedData = $this->encryptorFilter->decrypt($cachedData); + $serializedCachedData = $this->encryptor->decrypt($cachedData); $data = [$scopeType => [$scopeId => $this->serializer->unserialize($serializedCachedData)]]; } @@ -267,12 +267,12 @@ private function loadScopeData($scopeType, $scopeId) private function cacheData(array $data) { $this->cache->save( - $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data)), + $this->encryptor->encryptWithFastestAvailableAlgorithm($this->serializer->serialize($data)), $this->configType, [self::CACHE_TAG] ); $this->cache->save( - $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($data['default'])), + $this->encryptor->encryptWithFastestAvailableAlgorithm($this->serializer->serialize($data['default'])), $this->configType . '_default', [self::CACHE_TAG] ); @@ -281,14 +281,14 @@ private function cacheData(array $data) foreach ($data[$curScopeType] ?? [] as $curScopeId => $curScopeData) { $scopes[$curScopeType][$curScopeId] = 1; $this->cache->save( - $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($curScopeData)), + $this->encryptor->encryptWithFastestAvailableAlgorithm($this->serializer->serialize($curScopeData)), $this->configType . '_' . $curScopeType . '_' . $curScopeId, [self::CACHE_TAG] ); } } $this->cache->save( - $this->encryptorFilter->encryptWithFastestAlgorithm($this->serializer->serialize($scopes)), + $this->encryptor->encryptWithFastestAvailableAlgorithm($this->serializer->serialize($scopes)), $this->configType . '_scopes', [self::CACHE_TAG] ); diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index 8d46ee542b9ec..192782e0a1f6f 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -295,7 +295,7 @@ public function encrypt($data) * @param string $data * @return string */ - public function encryptWithFastestAlgorithm($data) + public function encryptWithFastestAvailableAlgorithm($data) { $crypt = $this->getCrypt(); if (null === $crypt) { diff --git a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php index da5cb8b4d918a..df72dc4c6b8bb 100644 --- a/setup/src/Magento/Setup/Model/CryptKeyGenerator.php +++ b/setup/src/Magento/Setup/Model/CryptKeyGenerator.php @@ -37,7 +37,7 @@ public function __construct(Random $random) */ public function generate() { - return $this->getRandomString(); + return md5($this->getRandomString()); } /** diff --git a/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php index e367747fc92c1..d7a4d477de7b0 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/CryptKeyGeneratorTest.php @@ -54,6 +54,6 @@ public function testReturnsMd5OfRandomString() $actual = $this->cryptKeyGenerator->generate(); - $this->assertEquals($expected, md5($actual)); + $this->assertEquals($expected, $actual); } } From 6f7e4de04a9e8275de729cff8be2d364286326af Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Wed, 21 Nov 2018 15:14:28 -0600 Subject: [PATCH 1320/1415] MC-5319: Create tax rate, zip code range MC-5318: Create tax rate, all postcodes --- .../Mftf/Section/AdminTaxRateFormSection.xml | 10 ++- .../Mftf/Section/AdminTaxRateGridSection.xml | 4 +- .../Mftf/Section/AdminTaxRuleFormSection.xml | 14 ++++ .../Mftf/Section/AdminTaxRuleGridSection.xml | 16 +++++ .../Mftf/Section/AdminTaxRulesSection.xml | 1 + .../AdminCreateTaxRateAllPostCodesTest.xml | 6 +- .../Test/AdminCreateTaxRateZipCodeRange.xml | 71 +++++++++++++++++++ 7 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleFormSection.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleGridSection.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml index 913d8135762bb..b2efe5c47b0c0 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateFormSection.xml @@ -10,11 +10,15 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminTaxRateFormSection"> <element name="taxIdentifier" type="input" selector="#code" /> - <element name="deleteRate" type="button" selector="#delete"/> - <element name="ok" type="button" selector="button.action-primary.action-accept"/> - <element name="save" type="button" selector="#save"/> + <element name="deleteRate" type="button" selector="#delete" timeout="30"/> + <element name="ok" type="button" selector="button.action-primary.action-accept" timeout="30"/> + <element name="save" type="button" selector="#save" timeout="30"/> <element name="country" type="select" selector="#tax_country_id"/> <element name="state" type="select" selector="#tax_region_id"/> <element name="rate" type="text" selector="#rate"/> + <element name="zipRange" type="checkbox" selector="#zip_is_range"/> + <element name="rangeFrom" type="text" selector="#zip_from"/> + <element name="rangeTo" type="text" selector="#zip_to"/> + <element name="zipCode" type="input" selector="#tax_postcode"/> </section> </sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml index 5df1f9c4ba245..61999f3e2ea33 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml @@ -16,7 +16,7 @@ <element name="filterByCountry" type="input" selector="#tax_rate_grid_filter_tax_country_id"/> <element name="filterByPostCode" type="input" selector="#tax_rate_grid_filter_tax_postcode"/> <element name="nthRow" type="block" selector="tr[data-role='row']:nth-of-type({{var}})" parameterized="true" timeout="30"/> - <element name="country" type="select" selector="#tax_country_id"/> - <element name="zipCode" type="input" selector="#tax_postcode"/> + <element name="country" type="select" selector="#tax_rate_grid_filter_tax_country_id"/> + <element name="zipCode" type="text" selector="#tax_rate_grid_filter_tax_postcode"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleFormSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleFormSection.xml new file mode 100644 index 0000000000000..37a0467089011 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleFormSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminTaxRuleFormSection"> + <element name="taxIdentifier" type="input" selector="input.admin__control-text admin__action-multiselect-search"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleGridSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleGridSection.xml new file mode 100644 index 0000000000000..b76a60cfd6699 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRuleGridSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminTaxRuleGridSection"> + <element name="add" type="button" selector="#add" timeout="30"/> + </section> +</sections> + + diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml index 8eb2a111446ca..3d58238c96ff9 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml @@ -15,6 +15,7 @@ <element name="zipIsRange" type="checkbox" selector="#zip_is_range"/> <element name="zipCode" type="input" selector="#tax_postcode"/> <element name="state" type="select" selector="#tax_region_id"/> + <element name="country" type="select" selector="#tax_country_id"/> <element name="rate" type="input" selector="#rate"/> <element name="save" type="button" selector=".action-save" timeout="30"/> <element name="saveRule" type="button" selector="#save" timeout="30"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml index f4b1066dae2e2..b63ca1953157f 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateAllPostCodesTest.xml @@ -36,7 +36,7 @@ <!-- Create a tax rate with * for postcodes --> <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> - <fillField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="Australia" stepKey="selectCountry1"/> <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="20" stepKey="fillRate"/> <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> @@ -64,8 +64,8 @@ <!-- Verify we see expected values on the tax rate edit page --> <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRuleName2"/> - <seeInField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> - <seeOptionIsSelected selector="{{AdminTaxRateGridSection.country}}" userInput="Australia" stepKey="seeCountry2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="Australia" stepKey="seeCountry2"/> <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="20" stepKey="seeRate"/> <!-- Go to the tax rule grid page and verify our tax rate can be used in the rule --> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml new file mode 100644 index 0000000000000..c4abd856354c0 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateTaxRateZipCodeRange"> + <annotations> + <stories value="Create Tax Rate"/> + <title value="Create Tax Rate,zip code range"/> + <description value="Test log in to Create Tax Rate and Create Zip Code Range"/> + <testCaseId value="MC-5319"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> + <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> + </after> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <!-- Create a tax rate with range from 90001-96162 for zipCodes --> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> + <checkOption selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="checkZipRange" /> + <fillField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="90001" stepKey="fillZipFrom"/> + <fillField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="96162" stepKey="fillZipTo"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="selectState" /> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput='15.5' stepKey="seeRate"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex3"/> + <!-- Create a tax rate for zipCodeRange and verify we see expected values on the tax rate grid page --> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateGridSection.country}}" userInput="United States" stepKey="selectCountry2" /> + <fillField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="90001-96162" stepKey="seeTaxPostCode1"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow3"/> + <!-- Verify we see expected values on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxIdentifierField2"/> + <seeCheckboxIsChecked selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="clickZipRange"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="90001" stepKey="seeTaxPostCode2"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="96162" stepKey="seeTaxPostCode3"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="seeState"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="seeCountry2"/> + + <!-- Verify we see expected values on the tax rule form page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex4"/> + <click selector="{{AdminTaxRuleGridSection.add}}" stepKey="clickAdd"/> + <see selector="{{AdminTaxRulesSection.taxRateMultiSelectItems}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxRateOnNewTaxRulePage"/> + </test> +</tests> From 3005e0ea0cf617b04d51e73d14f84a3d6cb1179b Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 21 Nov 2018 15:27:36 -0600 Subject: [PATCH 1321/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 --- .../src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php index e05c6667e6a6c..65fe4a5f47711 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php @@ -64,7 +64,7 @@ public function testCreateCryptConfigWithoutInput() { $returnValue = $this->configGeneratorObject->createCryptConfig([]); $this->assertEquals(ConfigFilePool::APP_ENV, $returnValue->getFileKey()); - $this->assertEquals(['crypt' => ['key' => ('key')]], $returnValue->getData()); + $this->assertEquals(['crypt' => ['key' => md5('key')]], $returnValue->getData()); } public function testCreateSessionConfigWithInput() From ae93b349a9f0d96b8dcfa6da94bb8f4948bf6fba Mon Sep 17 00:00:00 2001 From: Igor Melnykov <melnykov@adobe.com> Date: Wed, 21 Nov 2018 16:04:53 -0600 Subject: [PATCH 1322/1415] MAGETWO-96459: Fix performance on MAGETWO-83832 - address code review feedback --- app/code/Magento/Config/App/Config/Type/System.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 99d85e0a10a32..c237d0ea9963a 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -86,7 +86,7 @@ class System implements ConfigTypeInterface * @param int $cachingNestedLevel * @param string $configType * @param Reader|null $reader - * @param Encryptor|null $encryptorFilter + * @param Encryptor|null $encryptor * * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -101,14 +101,14 @@ public function __construct( $cachingNestedLevel = 1, $configType = self::CONFIG_TYPE, Reader $reader = null, - Encryptor $encryptorFilter = null + Encryptor $encryptor = null ) { $this->postProcessor = $postProcessor; $this->cache = $cache; $this->serializer = $serializer; $this->configType = $configType; $this->reader = $reader ?: ObjectManager::getInstance()->get(Reader::class); - $this->encryptor = ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); + $this->encryptor = $encryptor ?: ObjectManager::getInstance()->get(\Magento\Framework\Encryption\Encryptor::class); } /** From bf346d176cdebdb3bb98c8248eb56787c110bbda Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Thu, 22 Nov 2018 00:11:58 +0200 Subject: [PATCH 1323/1415] Changed schema input and output, fixed bug with uniq type --- .../SendFriendGraphQl/etc/schema.graphqls | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 3915d48681ab1..14f73a034a7ea 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -2,27 +2,38 @@ # See COPYING.txt for license details. type Mutation { - sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"Recommends Product by Sending Single/Multiple Email") + sendEmailToFriend (input: SendEmailToFriendInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"Recommends Product by Sending Single/Multiple Email") +} + +input SendEmailToFriendInput { + product_id: Int! + sender: SendEmailToFriendSenderInput! + recipients: [SendEmailToFriendRecipientInput!]! } input SendEmailToFriendSenderInput { - product_id: Int! - sender: Sender! - recipients: [Recipient!]! + name: String! + email: String! + message: String! } -type Sender { +input SendEmailToFriendRecipientInput { + name: String! + email: String! +} + +type SendEmailToFriendSender { name: String! email: String! message: String! } -type Recipient { +type SendEmailToFriendRecipient { name: String! email: String! } type SendEmailToFriendOutput { - sender: Sender - recipients: [Recipient] -} + sender: SendEmailToFriendSender + recipients: [SendEmailToFriendRecipient] +} \ No newline at end of file From 7e78060c166672fbbd069875812856856d6815f8 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sun, 2 Sep 2018 16:11:02 +0200 Subject: [PATCH 1324/1415] Fixed child items showing on My Account order view --- app/code/Magento/Sales/Block/Order/Items.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Block/Order/Items.php b/app/code/Magento/Sales/Block/Order/Items.php index 028544cd56219..0b67e9a0746d3 100644 --- a/app/code/Magento/Sales/Block/Order/Items.php +++ b/app/code/Magento/Sales/Block/Order/Items.php @@ -71,7 +71,6 @@ protected function _prepareLayout() $this->itemCollection = $this->itemCollectionFactory->create(); $this->itemCollection->setOrderFilter($this->getOrder()); - $this->itemCollection->filterByParent(null); /** @var \Magento\Theme\Block\Html\Pager $pagerBlock */ $pagerBlock = $this->getChildBlock('sales_order_item_pager'); From ada1c5f1387d0dc504a6c4f9e7ce7cd836a44504 Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Thu, 22 Nov 2018 11:14:43 +0530 Subject: [PATCH 1325/1415] Fixed configurable product widget issue --- .../templates/product/widget/new/column/new_default_list.phtml | 2 +- .../templates/product/widget/new/content/new_grid.phtml | 2 +- .../templates/product/widget/new/content/new_list.phtml | 2 +- .../view/frontend/templates/product/widget/content/grid.phtml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml index a4ae3ba907988..b658851e6a4db 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml @@ -33,7 +33,7 @@ <div class="product-item-actions"> <div class="actions-primary"> <?php if ($_product->isSaleable()): ?> - <?php if ($_product->getTypeInstance()->hasRequiredOptions($_product)): ?> + <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?> <button type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>" class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_product) ?>"}}'> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_grid.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_grid.phtml index 11bbfea1ac8ec..93542c4c9095c 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_grid.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_grid.phtml @@ -66,7 +66,7 @@ if ($exist = ($block->getProductCollection() && $block->getProductCollection()-> <?php if ($showCart): ?> <div class="actions-primary"> <?php if ($_item->isSaleable()): ?> - <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> + <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?> <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_item) ?>"}}' type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>"> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_list.phtml index 615cd13fb6d38..ad75a3a6f0743 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/content/new_list.phtml @@ -65,7 +65,7 @@ if ($exist = ($block->getProductCollection() && $block->getProductCollection()-> <?php if ($showCart): ?> <div class="actions-primary"> <?php if ($_item->isSaleable()): ?> - <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> + <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?> <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_item) ?>"}}' type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>"> diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml index f2273f7d44ff3..6789ace243b84 100644 --- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml +++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml @@ -61,7 +61,7 @@ <?php if ($showCart): ?> <div class="actions-primary"> <?php if ($_item->isSaleable()): ?> - <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> + <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?> <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>"> <span><?= $block->escapeHtml(__('Add to Cart')) ?></span> </button> From 9d08ae0a6fd49092ba2922f63d36160a1ac89637 Mon Sep 17 00:00:00 2001 From: Bartosz Kubicki <bartosz.kubicki@lizardmedia.pl> Date: Sun, 23 Sep 2018 10:32:06 +0200 Subject: [PATCH 1326/1415] Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Fix for not added attribute, while added it dynamically from product form. Merge remote-tracking branch 'origin/adding-attribute-to-product-in-product-form-fix' into adding-attribute-to-product-in-product-form-fix Conflicts: app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php Fix for not added attribute, while added it dynamically from product form. Fix for static code analysis errors. --- .../Product/AddAttributeToTemplate.php | 86 ++++++++++++------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php index bbef1de28e5b6..09eacbbf0731c 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php @@ -6,8 +6,10 @@ namespace Magento\Catalog\Controller\Adminhtml\Product; +use Magento\Backend\App\Action\Context; use Magento\Catalog\Api\AttributeSetRepositoryInterface; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Controller\Adminhtml\Product; use Magento\Eav\Api\AttributeGroupRepositoryInterface; use Magento\Eav\Api\AttributeManagementInterface; use Magento\Eav\Api\AttributeRepositoryInterface; @@ -16,8 +18,14 @@ use Magento\Eav\Api\Data\AttributeInterface; use Magento\Eav\Api\Data\AttributeSetInterface; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\Controller\Result\Json; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\ObjectManager; use Psr\Log\LoggerInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Api\ExtensionAttributesFactory; /** @@ -25,10 +33,10 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Product +class AddAttributeToTemplate extends Product implements HttpPostActionInterface { /** - * @var \Magento\Framework\Controller\Result\JsonFactory + * @var JsonFactory */ protected $resultJsonFactory; @@ -75,33 +83,34 @@ class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Produ /** * Constructor * - * @param \Magento\Backend\App\Action\Context $context + * @param Context $context * @param Builder $productBuilder - * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory - * @param \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory|null $attributeGroupFactory + * @param JsonFactory $resultJsonFactory + * @param AttributeGroupInterfaceFactory|null $attributeGroupFactory * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @SuppressWarnings(PHPMD.LongVariable) */ public function __construct( - \Magento\Backend\App\Action\Context $context, - \Magento\Catalog\Controller\Adminhtml\Product\Builder $productBuilder, - \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory $attributeGroupFactory = null + Context $context, + Builder $productBuilder, + JsonFactory $resultJsonFactory, + AttributeGroupInterfaceFactory $attributeGroupFactory = null ) { parent::__construct($context, $productBuilder); $this->resultJsonFactory = $resultJsonFactory; - $this->attributeGroupFactory = $attributeGroupFactory ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Eav\Api\Data\AttributeGroupInterfaceFactory::class); + $this->attributeGroupFactory = $attributeGroupFactory ?: ObjectManager::getInstance() + ->get(AttributeGroupInterfaceFactory::class); } /** * Add attribute to attribute set * - * @return \Magento\Framework\Controller\Result\Json + * @return Json */ public function execute() { $request = $this->getRequest(); - $response = new \Magento\Framework\DataObject(); + $response = new DataObject(); $response->setError(false); try { @@ -124,12 +133,12 @@ public function execute() ->getItems(); if (!$attributeGroupItems) { - throw new \Magento\Framework\Exception\NoSuchEntityException; + throw new NoSuchEntityException; } /** @var AttributeGroupInterface $attributeGroup */ $attributeGroup = reset($attributeGroupItems); - } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + } catch (NoSuchEntityException $e) { /** @var AttributeGroupInterface $attributeGroup */ $attributeGroup = $this->attributeGroupFactory->create(); } @@ -176,101 +185,114 @@ public function execute() * Adding basic filters * * @return SearchCriteriaBuilder - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ private function getBasicAttributeSearchCriteriaBuilder() { - $attributeIds = (array)$this->getRequest()->getParam('attributeIds', []); + $attributeIds = (array) $this->getRequest()->getParam('attributeIds', []); if (empty($attributeIds['selected'])) { throw new LocalizedException(__('Attributes were missing and must be specified.')); } return $this->getSearchCriteriaBuilder() - ->addFilter('attribute_set_id', new \Zend_Db_Expr('null'), 'is') ->addFilter('attribute_id', [$attributeIds['selected']], 'in'); } /** + * Get AttributeRepositoryInterface + * * @return AttributeRepositoryInterface */ private function getAttributeRepository() { if (null === $this->attributeRepository) { - $this->attributeRepository = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Eav\Api\AttributeRepositoryInterface::class); + $this->attributeRepository = ObjectManager::getInstance() + ->get(AttributeRepositoryInterface::class); } return $this->attributeRepository; } /** + * Get AttributeSetRepositoryInterface + * * @return AttributeSetRepositoryInterface */ private function getAttributeSetRepository() { if (null === $this->attributeSetRepository) { - $this->attributeSetRepository = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Catalog\Api\AttributeSetRepositoryInterface::class); + $this->attributeSetRepository = ObjectManager::getInstance() + ->get(AttributeSetRepositoryInterface::class); } return $this->attributeSetRepository; } /** + * Get AttributeGroupInterface + * * @return AttributeGroupRepositoryInterface */ private function getAttributeGroupRepository() { if (null === $this->attributeGroupRepository) { - $this->attributeGroupRepository = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Eav\Api\AttributeGroupRepositoryInterface::class); + $this->attributeGroupRepository = ObjectManager::getInstance() + ->get(AttributeGroupRepositoryInterface::class); } return $this->attributeGroupRepository; } /** + * Get SearchCriteriaBuilder + * * @return SearchCriteriaBuilder */ private function getSearchCriteriaBuilder() { if (null === $this->searchCriteriaBuilder) { - $this->searchCriteriaBuilder = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Api\SearchCriteriaBuilder::class); + $this->searchCriteriaBuilder = ObjectManager::getInstance() + ->get(SearchCriteriaBuilder::class); } return $this->searchCriteriaBuilder; } /** + * Get AttributeManagementInterface + * * @return AttributeManagementInterface */ private function getAttributeManagement() { if (null === $this->attributeManagement) { - $this->attributeManagement = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Eav\Api\AttributeManagementInterface::class); + $this->attributeManagement = ObjectManager::getInstance() + ->get(AttributeManagementInterface::class); } return $this->attributeManagement; } /** + * Get LoggerInterface + * * @return LoggerInterface */ private function getLogger() { if (null === $this->logger) { - $this->logger = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Psr\Log\LoggerInterface::class); + $this->logger = ObjectManager::getInstance() + ->get(LoggerInterface::class); } return $this->logger; } /** + * Get ExtensionAttributesFactory. + * * @return ExtensionAttributesFactory */ private function getExtensionAttributesFactory() { if (null === $this->extensionAttributesFactory) { - $this->extensionAttributesFactory = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Api\ExtensionAttributesFactory::class); + $this->extensionAttributesFactory = ObjectManager::getInstance() + ->get(ExtensionAttributesFactory::class); } return $this->extensionAttributesFactory; } From 180de0ab6d6e29deee123baed1d8f20f2324180a Mon Sep 17 00:00:00 2001 From: Tomas Votruba <tomas.vot@gmail.com> Date: Thu, 22 Nov 2018 09:19:06 +0100 Subject: [PATCH 1327/1415] correct param, var and return annotation values --- .../Magento/Framework/Acl/Loader/ResourceLoader.php | 2 +- lib/internal/Magento/Framework/Amqp/Queue.php | 2 +- .../SearchCriteria/CollectionProcessor/JoinProcessor.php | 2 +- .../Unit/ExtensionAttribute/Config/SchemaLocatorTest.php | 2 +- lib/internal/Magento/Framework/App/ResourceConnection.php | 2 +- .../Magento/Framework/App/Test/Unit/Request/HttpTest.php | 8 ++++---- .../Unit/ResourceConnection/Config/SchemaLocatorTest.php | 2 +- .../App/Test/Unit/Route/Config/SchemaLocatorTest.php | 4 ++-- lib/internal/Magento/Framework/App/Utility/Classes.php | 2 +- .../Test/Unit/Backend/Decorator/DecoratorAbstractTest.php | 2 +- .../Magento/Framework/Composer/ComposerJsonFinder.php | 2 +- .../Magento/Framework/Config/Test/Unit/ThemeTest.php | 4 ++-- .../Unit/PreProcessor/File/Collector/AggregatedTest.php | 6 +++--- .../Test/Unit/PreProcessor/File/Collector/LibraryTest.php | 4 ++-- lib/internal/Magento/Framework/DataObject/Copy.php | 6 +++--- .../EntityManager/Test/Unit/TypeResolverTest.php | 2 +- .../Event/Test/Unit/Config/SchemaLocatorTest.php | 4 ++-- .../Magento/Framework/Exception/BulkException.php | 2 +- lib/internal/Magento/Framework/File/Mime.php | 2 +- lib/internal/Magento/Framework/Filesystem/Io/Sftp.php | 2 +- .../Indexer/Test/Unit/Config/SchemaLocatorTest.php | 4 ++-- lib/internal/Magento/Framework/Lock/Backend/Database.php | 2 +- .../Framework/Lock/Test/Unit/Backend/DatabaseTest.php | 2 +- lib/internal/Magento/Framework/Logger/Handler/Base.php | 2 +- lib/internal/Magento/Framework/Logger/Handler/System.php | 2 +- lib/internal/Magento/Framework/Message/Manager.php | 2 +- lib/internal/Magento/Framework/Model/AbstractModel.php | 2 +- lib/internal/Magento/Framework/Module/Setup/Context.php | 2 +- .../Magento/Framework/ObjectManager/Profiler/Log.php | 2 +- .../ObjectManager/Test/Unit/Config/SchemaLocatorTest.php | 4 ++-- .../Search/Test/Unit/Adapter/Mysql/Filter/BuilderTest.php | 2 +- .../Framework/Session/SaveHandler/Redis/Config.php | 2 +- lib/internal/Magento/Framework/Test/Unit/UrlTest.php | 6 +++--- lib/internal/Magento/Framework/Translate.php | 2 +- .../Framework/Translate/Inline/ParserInterface.php | 2 +- .../Magento/Framework/View/Design/Theme/ThemeList.php | 2 +- .../View/Element/UiComponent/Config/DomMerger.php | 2 +- lib/internal/Magento/Framework/Webapi/ErrorProcessor.php | 2 +- 38 files changed, 53 insertions(+), 53 deletions(-) diff --git a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php index 8a4ad39d78570..afcd1d82bb8d7 100644 --- a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php +++ b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php @@ -17,7 +17,7 @@ class ResourceLoader implements \Magento\Framework\Acl\LoaderInterface /** * Acl resource config * - * @var ProviderInterface $resourceProvider + * @var ProviderInterface */ protected $_resourceProvider; diff --git a/lib/internal/Magento/Framework/Amqp/Queue.php b/lib/internal/Magento/Framework/Amqp/Queue.php index edd57339b842b..0587d5a592746 100644 --- a/lib/internal/Magento/Framework/Amqp/Queue.php +++ b/lib/internal/Magento/Framework/Amqp/Queue.php @@ -37,7 +37,7 @@ class Queue implements QueueInterface private $envelopeFactory; /** - * @var LoggerInterface $logger + * @var LoggerInterface */ private $logger; diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php index 207325042c737..34f16212c829b 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php @@ -28,7 +28,7 @@ class JoinProcessor implements CollectionProcessorInterface private $appliedFields = []; /** - * @param CustomJoinInterface[] $customFilters + * @param CustomJoinInterface[] $customJoins * @param array $fieldMapping */ public function __construct( diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/SchemaLocatorTest.php index d874f155b16fb..972b165d8f31a 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/Api/Test/Unit/ExtensionAttribute/Config/SchemaLocatorTest.php @@ -15,7 +15,7 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $model; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; protected function setUp() diff --git a/lib/internal/Magento/Framework/App/ResourceConnection.php b/lib/internal/Magento/Framework/App/ResourceConnection.php index 148053fa44e08..4652d2aaf6d30 100644 --- a/lib/internal/Magento/Framework/App/ResourceConnection.php +++ b/lib/internal/Magento/Framework/App/ResourceConnection.php @@ -53,7 +53,7 @@ class ResourceConnection protected $connectionFactory; /** - * @var DeploymentConfig $deploymentConfig + * @var DeploymentConfig */ private $deploymentConfig; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php index 535e74e9a3bdb..81805e2df9690 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php @@ -246,8 +246,8 @@ public function testIsAjax() } /** - * @param $serverVariables array - * @param $expectedResult string + * @param array $serverVariables + * @param string $expectedResult * @dataProvider serverVariablesProvider */ public function testGetDistroBaseUrl($serverVariables, $expectedResult) @@ -374,7 +374,7 @@ public function testIsSecure($isSecure, $serverHttps, $headerOffloadKey, $header /** * @dataProvider httpSafeMethodProvider * @backupGlobals enabled - * @param string $method value of $_SERVER['REQUEST_METHOD'] + * @param string $httpMethod value of $_SERVER['REQUEST_METHOD'] */ public function testIsSafeMethodTrue($httpMethod) { @@ -386,7 +386,7 @@ public function testIsSafeMethodTrue($httpMethod) /** * @dataProvider httpNotSafeMethodProvider * @backupGlobals enabled - * @param string $method value of $_SERVER['REQUEST_METHOD'] + * @param string $httpMethod value of $_SERVER['REQUEST_METHOD'] */ public function testIsSafeMethodFalse($httpMethod) { diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/Config/SchemaLocatorTest.php index 8a5c071e8c4ee..921fcf2e61e6d 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/Config/SchemaLocatorTest.php @@ -13,7 +13,7 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $model; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; protected function setUp() diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Route/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Route/Config/SchemaLocatorTest.php index 143de5ee47fae..61938b455295e 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Route/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Route/Config/SchemaLocatorTest.php @@ -12,10 +12,10 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $config; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolverMock; protected function setUp() diff --git a/lib/internal/Magento/Framework/App/Utility/Classes.php b/lib/internal/Magento/Framework/App/Utility/Classes.php index 7cd36f0e37fc8..289fc8fc8c88a 100644 --- a/lib/internal/Magento/Framework/App/Utility/Classes.php +++ b/lib/internal/Magento/Framework/App/Utility/Classes.php @@ -236,7 +236,7 @@ public static function getVirtualClasses() /** * Check if instance is virtual type * - * @param $className string + * @param string $className * @return bool */ public static function isVirtual($className) diff --git a/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/Decorator/DecoratorAbstractTest.php b/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/Decorator/DecoratorAbstractTest.php index ba75b7eed52ca..03ce339e90ba1 100644 --- a/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/Decorator/DecoratorAbstractTest.php +++ b/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/Decorator/DecoratorAbstractTest.php @@ -54,7 +54,7 @@ public function testConstructor() } /** - * @param array options + * @param array $options * @expectedException \Zend_Cache_Exception * @dataProvider constructorExceptionDataProvider */ diff --git a/lib/internal/Magento/Framework/Composer/ComposerJsonFinder.php b/lib/internal/Magento/Framework/Composer/ComposerJsonFinder.php index 259fcd323b38b..2a641a41377a7 100644 --- a/lib/internal/Magento/Framework/Composer/ComposerJsonFinder.php +++ b/lib/internal/Magento/Framework/Composer/ComposerJsonFinder.php @@ -13,7 +13,7 @@ class ComposerJsonFinder { /** - * @var DirectoryList $directoryList + * @var DirectoryList */ private $directoryList; diff --git a/lib/internal/Magento/Framework/Config/Test/Unit/ThemeTest.php b/lib/internal/Magento/Framework/Config/Test/Unit/ThemeTest.php index 17fa89068362e..4966a45c7b479 100644 --- a/lib/internal/Magento/Framework/Config/Test/Unit/ThemeTest.php +++ b/lib/internal/Magento/Framework/Config/Test/Unit/ThemeTest.php @@ -7,10 +7,10 @@ class ThemeTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolverMock; protected function setUp() diff --git a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/AggregatedTest.php b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/AggregatedTest.php index c1c2a4f4a1d18..cdf7a1ec3734d 100644 --- a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/AggregatedTest.php +++ b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/AggregatedTest.php @@ -98,9 +98,9 @@ public function testGetFilesEmpty() * * @dataProvider getFilesDataProvider * - * @param $libraryFiles array Files in lib directory - * @param $baseFiles array Files in base directory - * @param $themeFiles array Files in theme + * @param array $libraryFiles Files in lib directory + * @param array $baseFiles Files in base directory + * @param array $themeFiles Files in theme * * * @return void */ diff --git a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/LibraryTest.php b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/LibraryTest.php index 962734feea18a..6080652a4ad35 100644 --- a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/LibraryTest.php +++ b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/File/Collector/LibraryTest.php @@ -129,8 +129,8 @@ public function testGetFilesEmpty() * * @dataProvider getFilesDataProvider * - * @param $libraryFiles array Files in lib directory - * @param $themeFiles array Files in theme + * @param array $libraryFiles Files in lib directory + * @param array $themeFiles Files in theme * * * @return void */ diff --git a/lib/internal/Magento/Framework/DataObject/Copy.php b/lib/internal/Magento/Framework/DataObject/Copy.php index 728f72e713d7f..f4e733feb0bed 100644 --- a/lib/internal/Magento/Framework/DataObject/Copy.php +++ b/lib/internal/Magento/Framework/DataObject/Copy.php @@ -123,7 +123,7 @@ protected function dispatchCopyFieldSetEvent($fieldset, $aspect, $source, $targe * @param string $aspect a field name * @param array|\Magento\Framework\DataObject $source * @param string $root - * @return array $data + * @return array * * @api */ @@ -232,7 +232,7 @@ protected function _setFieldsetFieldValue($target, $targetCode, $value) /** * Access the extension get method * - * @param \Magento\Framework\Api\ExtensibleDataInterface $object + * @param \Magento\Framework\Api\ExtensibleDataInterface $source * @param string $code * * @return mixed @@ -265,7 +265,7 @@ protected function getAttributeValueFromExtensibleDataObject($source, $code) /** * Access the extension set method * - * @param \Magento\Framework\Api\ExtensibleDataInterface $object + * @param \Magento\Framework\Api\ExtensibleDataInterface $target * @param string $code * @param mixed $value * diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/TypeResolverTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/TypeResolverTest.php index 1ab6074d6a36b..9b90e373de852 100644 --- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/TypeResolverTest.php +++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/TypeResolverTest.php @@ -32,7 +32,7 @@ public function setUp() /** * @param object $dataObject - * @param string $interfaceNames + * @param string $interfaceName * @dataProvider resolveDataProvider */ public function testResolve($dataObject, $interfaceName) diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/Event/Test/Unit/Config/SchemaLocatorTest.php index cd8a16b5c2c4f..66651174a87cf 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/Event/Test/Unit/Config/SchemaLocatorTest.php @@ -12,10 +12,10 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $model; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolverMock; protected function setUp() diff --git a/lib/internal/Magento/Framework/Exception/BulkException.php b/lib/internal/Magento/Framework/Exception/BulkException.php index b2e91da211fed..9ee43bce2b913 100644 --- a/lib/internal/Magento/Framework/Exception/BulkException.php +++ b/lib/internal/Magento/Framework/Exception/BulkException.php @@ -39,7 +39,7 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** - * @param $data array + * @param array $data */ public function addData($data) { diff --git a/lib/internal/Magento/Framework/File/Mime.php b/lib/internal/Magento/Framework/File/Mime.php index d42b536f450ce..f235d5765c780 100644 --- a/lib/internal/Magento/Framework/File/Mime.php +++ b/lib/internal/Magento/Framework/File/Mime.php @@ -61,7 +61,7 @@ class Mime /** * List of mime types that can be defined by file extension. * - * @var array $defineByExtensionList + * @var array */ private $defineByExtensionList = [ 'txt' => 'text/plain', diff --git a/lib/internal/Magento/Framework/Filesystem/Io/Sftp.php b/lib/internal/Magento/Framework/Filesystem/Io/Sftp.php index a04e4fcbb12d0..119c89f033480 100644 --- a/lib/internal/Magento/Framework/Filesystem/Io/Sftp.php +++ b/lib/internal/Magento/Framework/Filesystem/Io/Sftp.php @@ -17,7 +17,7 @@ class Sftp extends AbstractIo const SSH2_PORT = 22; /** - * @var \phpseclib\Net\SFTP $_connection + * @var \phpseclib\Net\SFTP */ protected $_connection = null; diff --git a/lib/internal/Magento/Framework/Indexer/Test/Unit/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/Indexer/Test/Unit/Config/SchemaLocatorTest.php index ee193da3f0bfe..5b09c558a9002 100644 --- a/lib/internal/Magento/Framework/Indexer/Test/Unit/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/Indexer/Test/Unit/Config/SchemaLocatorTest.php @@ -13,10 +13,10 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $model; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolverMock; protected function setUp() diff --git a/lib/internal/Magento/Framework/Lock/Backend/Database.php b/lib/internal/Magento/Framework/Lock/Backend/Database.php index dbc6a97ce60cd..ce6aeca66d657 100644 --- a/lib/internal/Magento/Framework/Lock/Backend/Database.php +++ b/lib/internal/Magento/Framework/Lock/Backend/Database.php @@ -139,7 +139,7 @@ public function isLocked(string $name): bool * Limited to 64 characters in MySQL. * * @param string $name - * @return string $name + * @return string * @throws InputException */ private function addPrefix(string $name): string diff --git a/lib/internal/Magento/Framework/Lock/Test/Unit/Backend/DatabaseTest.php b/lib/internal/Magento/Framework/Lock/Test/Unit/Backend/DatabaseTest.php index 616597a8838a2..db3add62ff550 100644 --- a/lib/internal/Magento/Framework/Lock/Test/Unit/Backend/DatabaseTest.php +++ b/lib/internal/Magento/Framework/Lock/Test/Unit/Backend/DatabaseTest.php @@ -32,7 +32,7 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * @var Database $database + * @var Database */ private $database; diff --git a/lib/internal/Magento/Framework/Logger/Handler/Base.php b/lib/internal/Magento/Framework/Logger/Handler/Base.php index 46c707a9254cf..84109b7b26325 100644 --- a/lib/internal/Magento/Framework/Logger/Handler/Base.php +++ b/lib/internal/Magento/Framework/Logger/Handler/Base.php @@ -73,7 +73,7 @@ private function sanitizeFileName($fileName) /** * {@inheritDoc} * - * @param $record array + * @param array $record * * @return void */ diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php index b30195e979712..f2de01d0745c4 100644 --- a/lib/internal/Magento/Framework/Logger/Handler/System.php +++ b/lib/internal/Magento/Framework/Logger/Handler/System.php @@ -43,7 +43,7 @@ public function __construct( /** * Writes formatted record through the handler. * - * @param $record array The record metadata + * @param array $record The record metadata * @return void */ public function write(array $record) diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php index f31892a938fb1..2b1b60bf76a46 100644 --- a/lib/internal/Magento/Framework/Message/Manager.php +++ b/lib/internal/Magento/Framework/Message/Manager.php @@ -67,7 +67,7 @@ class Manager implements ManagerInterface * @param Event\ManagerInterface $eventManager * @param LoggerInterface $logger * @param string $defaultGroup - * @param ExceptionMessageFactoryInterface|null exceptionMessageFactory + * @param ExceptionMessageFactoryInterface|null $exceptionMessageFactory exceptionMessageFactory */ public function __construct( Session $session, diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index d8a7c96c63915..c1a597e13714b 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -42,7 +42,7 @@ abstract class AbstractModel extends \Magento\Framework\DataObject /** * Data changes flag (true after setData|unsetData call) - * @var $_hasDataChange bool + * @var bool */ protected $_hasDataChanges = false; diff --git a/lib/internal/Magento/Framework/Module/Setup/Context.php b/lib/internal/Magento/Framework/Module/Setup/Context.php index 81b93ac447cc0..81dcb08e95cad 100644 --- a/lib/internal/Magento/Framework/Module/Setup/Context.php +++ b/lib/internal/Magento/Framework/Module/Setup/Context.php @@ -107,7 +107,7 @@ public function getEventManager() } /** - * @return \Psr\Log\LoggerInterface $logger + * @return \Psr\Log\LoggerInterface */ public function getLogger() { diff --git a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php index 9221dad9090c4..79f014d896478 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php +++ b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php @@ -11,7 +11,7 @@ class Log { /** - * @var $this + * @var self */ protected static $instance; diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/SchemaLocatorTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/SchemaLocatorTest.php index 1a653992e1e35..65018bcd87374 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/SchemaLocatorTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/SchemaLocatorTest.php @@ -12,10 +12,10 @@ class SchemaLocatorTest extends \PHPUnit\Framework\TestCase */ protected $model; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolver; - /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */ + /** @var \Magento\Framework\Config\Dom\UrnResolver */ protected $urnResolverMock; protected function setUp() diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/Filter/BuilderTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/Filter/BuilderTest.php index 2a7aa8561b27d..26e6aba1d33bf 100644 --- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/Filter/BuilderTest.php +++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/Filter/BuilderTest.php @@ -29,7 +29,7 @@ class BuilderTest extends \PHPUnit\Framework\TestCase private $preprocessor; /** - * @var ConditionManager|\PHPUnit_Framework_MockObject_MockObject $conditionManager + * @var ConditionManager|\PHPUnit_Framework_MockObject_MockObject */ private $conditionManager; diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index 5a4ed1700da55..a5eddb402a1d4 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -143,7 +143,7 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface /** * Deployment config * - * @var DeploymentConfig $deploymentConfig + * @var DeploymentConfig */ private $deploymentConfig; diff --git a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php index 3713978d0f74e..046a9d63fc8f4 100644 --- a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php @@ -149,8 +149,8 @@ protected function getUrlModel($arguments = []) } /** - * @param $httpHost string - * @param $url string + * @param string $httpHost + * @param string $url * @dataProvider getCurrentUrlProvider */ public function testGetCurrentUrl($httpHost, $url) @@ -435,7 +435,7 @@ public function testGetDirectUrl() } /** - * @param string $url + * @param string $inputUrl * @dataProvider getRebuiltUrlDataProvider */ public function testGetRebuiltUrl($inputUrl, $outputUrl) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index dae3f73e8fc79..e992482609a87 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -60,7 +60,7 @@ class Translate implements \Magento\Framework\TranslateInterface protected $_viewDesign; /** - * @var \Magento\Framework\Cache\FrontendInterface $cache + * @var \Magento\Framework\Cache\FrontendInterface */ protected $_cache; diff --git a/lib/internal/Magento/Framework/Translate/Inline/ParserInterface.php b/lib/internal/Magento/Framework/Translate/Inline/ParserInterface.php index e8905f71ea732..4c3bfc1a1964b 100644 --- a/lib/internal/Magento/Framework/Translate/Inline/ParserInterface.php +++ b/lib/internal/Magento/Framework/Translate/Inline/ParserInterface.php @@ -43,7 +43,7 @@ public function getContent(); /** * Sets the body content that is being parsed passed upon the passed in string. * - * @param $content string + * @param string $content * @return void */ public function setContent($content); diff --git a/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php b/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php index 000fba24f0822..0d6ed2f98b522 100644 --- a/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php +++ b/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php @@ -40,7 +40,7 @@ class ThemeList extends \Magento\Framework\Data\Collection implements ListInterf protected $_itemObjectClass = ThemeInterface::class; /** - * @var \Magento\Framework\Config\ThemeFactory $themeConfigFactory + * @var \Magento\Framework\Config\ThemeFactory */ protected $themeConfigFactory; diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php index b20726b79589f..015ecf403b3ec 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php @@ -341,7 +341,7 @@ public function createDomDocument($xml) * Validate dom document * * @param \DOMDocument $domDocument - * @param string|null $schemaFilePath + * @param string|null $schema * @return array of errors * @throws \Exception */ diff --git a/lib/internal/Magento/Framework/Webapi/ErrorProcessor.php b/lib/internal/Magento/Framework/Webapi/ErrorProcessor.php index 6fc5b284b7563..6ffcaa0676a0a 100644 --- a/lib/internal/Magento/Framework/Webapi/ErrorProcessor.php +++ b/lib/internal/Magento/Framework/Webapi/ErrorProcessor.php @@ -195,7 +195,7 @@ public function renderException(\Exception $exception, $httpCode = self::DEFAULT * Log information about exception to exception log. * * @param \Exception $exception - * @return string $reportId + * @return string */ protected function _critical(\Exception $exception) { From 38c1c330b9e55c6f098c40b642343b8dd39179e7 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Thu, 22 Nov 2018 09:50:38 +0100 Subject: [PATCH 1328/1415] fix: remove old code in tabs, always set tabindex to 0 when tabs are initialized --- lib/web/mage/tabs.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index e7e04a26b29c1..b441477ab8d8a 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -83,7 +83,7 @@ define([ /** * When the widget gets instantiated, the first tab that is not disabled receive focusable property - * Updated: for accessibility all tabs receive tabIndex 0 + * All tabs receive tabIndex 0 * @private */ _processTabIndex: function () { @@ -91,17 +91,8 @@ define([ self.triggers.attr('tabIndex', 0); $.each(this.collapsibles, function (i) { - if (!$(this).collapsible('option', 'disabled')) { - self.triggers.eq(i).attr('tabIndex', 0); - - return false; - } - }); - $.each(this.collapsibles, function (i) { - $(this).on('beforeOpen', function () { - self.triggers.attr('tabIndex', 0); - self.triggers.eq(i).attr('tabIndex', 0); - }); + self.triggers.attr('tabIndex', 0); + self.triggers.eq(i).attr('tabIndex', 0); }); }, From a65b64adb0f57e77fa46aabe0dba32ceb2385067 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Thu, 22 Nov 2018 10:12:54 +0100 Subject: [PATCH 1329/1415] chore: remove unused code in admin view of catalog --- .../catalog/product/composite/configure.js | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index 6903a17bcdcca..a2804a8723ce0 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -469,26 +469,6 @@ define([ } }, - /** - * toggles Selects states (for IE) except those to be shown in popup - */ - /*_toggleSelectsExceptBlock: function(flag) { - if(Prototype.Browser.IE){ - if (this.blockForm) { - var states = new Array; - var selects = this.blockForm.getElementsByTagName("select"); - for(var i=0; i<selects.length; i++){ - states[i] = selects[i].style.visibility - } - } - if (this.blockForm) { - for(i=0; i<selects.length; i++){ - selects[i].style.visibility = states[i] - } - } - } - },*/ - /** * Close configuration window */ From 486aeadf01fedab8853fd515c88116282185f58d Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Thu, 22 Nov 2018 10:14:33 +0100 Subject: [PATCH 1330/1415] chore: remove old code for IE9 --- lib/web/varien/js.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/web/varien/js.js b/lib/web/varien/js.js index 55e41a1652cb8..45032829f2fd8 100644 --- a/lib/web/varien/js.js +++ b/lib/web/varien/js.js @@ -607,17 +607,11 @@ if (!("console" in window) || !("firebug" in console)) * @example fireEvent($('my-input', 'click')); */ function fireEvent(element, event) { - if (document.createEvent) { - // dispatch for all browsers except IE before version 9 - var evt = document.createEvent('HTMLEvents'); + // dispatch event + var evt = document.createEvent('HTMLEvents'); - evt.initEvent(event, true, true); // event type, bubbling, cancelable - return element.dispatchEvent(evt); - } - // dispatch for IE before version 9 - var evt = document.createEventObject(); - - return element.fireEvent('on' + event, evt); + evt.initEvent(event, true, true); // event type, bubbling, cancelable + return element.dispatchEvent(evt); } From c8d4c2e808ed57a7eb8b1369b3a74f25aa722516 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Thu, 22 Nov 2018 10:16:32 +0100 Subject: [PATCH 1331/1415] chore: remove old CSS fixes for IE --- .../fileUploader/css/jquery.fileupload-ui.css | 11 - lib/web/prototype/windows/themes/darkX.css | 20 -- lib/web/prototype/windows/themes/lighting.css | 293 +----------------- lib/web/prototype/windows/themes/mac_os_x.css | 112 ------- .../windows/themes/mac_os_x_dialog.css | 50 --- lib/web/prototype/windows/themes/nuncio.css | 67 ---- 6 files changed, 1 insertion(+), 552 deletions(-) diff --git a/lib/web/jquery/fileUploader/css/jquery.fileupload-ui.css b/lib/web/jquery/fileUploader/css/jquery.fileupload-ui.css index e36a93df36b57..44b628efb481c 100644 --- a/lib/web/jquery/fileUploader/css/jquery.fileupload-ui.css +++ b/lib/web/jquery/fileUploader/css/jquery.fileupload-ui.css @@ -52,17 +52,6 @@ display: block; } -/* Fix for IE 6: */ -*html .fileinput-button { - line-height: 22px; - margin: 1px -3px 0 0; -} - -/* Fix for IE 7: */ -*+html .fileinput-button { - margin: 1px 0 0 0; -} - @media (max-width: 480px) { .files .btn span { display: none; diff --git a/lib/web/prototype/windows/themes/darkX.css b/lib/web/prototype/windows/themes/darkX.css index 2f83cfd46addb..1d964b1376d53 100644 --- a/lib/web/prototype/windows/themes/darkX.css +++ b/lib/web/prototype/windows/themes/darkX.css @@ -99,23 +99,3 @@ font-size: 14px; background:#5E5148; } - - -/* FOR IE */ -* html .darkX_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-minimize-focused.png", sizingMethod="crop"); -} - -* html .darkX_maximize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-maximize-focused.png", sizingMethod="scale"); -} - -* html .darkX_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-close-focused.png", sizingMethod="crop"); -} diff --git a/lib/web/prototype/windows/themes/lighting.css b/lib/web/prototype/windows/themes/lighting.css index 95ec287a9276f..60fed4aaa2d69 100644 --- a/lib/web/prototype/windows/themes/lighting.css +++ b/lib/web/prototype/windows/themes/lighting.css @@ -185,79 +185,6 @@ background:transparent url('lighting/spinner.gif') no-repeat center center } -/* FOR IE */ -* html .bluelighting_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-blue.png", sizingMethod="scale"); -} - -* html .bluelighting_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-blue.png", sizingMethod="scale"); -} - -* html .bluelighting_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-blue.png", sizingMethod="scale"); -} - -* html .bluelighting_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-blue.png", sizingMethod="scale"); -} - -* html .bluelighting_se, * html .bluelighting_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_maximize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-blue.png", sizingMethod="crop"); -} - -* html .bluelighting_content { - background:#B8D7FF; -} - - - .overlay_greylighting { background-color:#FFF; filter:alpha(opacity=60); @@ -419,79 +346,6 @@ background:transparent url('lighting/spinner.gif') no-repeat center center } -/* FOR IE */ -* html .greylighting_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-grey.png", sizingMethod="crop"); -} - -* html .greylighting_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-grey.png", sizingMethod="scale"); -} - -* html .greylighting_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-grey.png", sizingMethod="crop"); -} - -* html .greylighting_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-grey.png", sizingMethod="scale"); -} - -* html .greylighting_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-grey.png", sizingMethod="scale"); -} - -* html .greylighting_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-grey.png", sizingMethod="crop"); -} - -* html .greylighting_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-grey.png", sizingMethod="scale"); -} - -* html greylighting_se, * html .greylighting_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-grey.png", sizingMethod="crop"); -} - -* html .greylighting_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-grey.png", sizingMethod="crop"); -} - -* html .greylighting_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-grey.png", sizingMethod="crop"); -} - -* html .greylighting_maximize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-grey.png", sizingMethod="crop"); -} - -* html .greylighting_content { - background:#C7C7C7; -} - - - .overlay_greenlighting { background-color:#FFF; filter:alpha(opacity=60); @@ -653,79 +507,6 @@ background:transparent url('lighting/spinner.gif') no-repeat center center } -/* FOR IE */ -* html .greenlighting_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-green.png", sizingMethod="crop"); -} - -* html .greenlighting_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-green.png", sizingMethod="scale"); -} - -* html .greenlighting_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-green.png", sizingMethod="crop"); -} - -* html .greenlighting_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-green.png", sizingMethod="scale"); -} - -* html .greenlighting_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-green.png", sizingMethod="scale"); -} - -* html .greenlighting_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-green.png", sizingMethod="crop"); -} - -* html .greenlighting_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-green.png", sizingMethod="scale"); -} - -* html greenlighting_se, * html .greenlighting_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-green.png", sizingMethod="crop"); -} - -* html .greenlighting_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-green.png", sizingMethod="crop"); -} - -* html .greenlighting_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-green.png", sizingMethod="crop"); -} - -* html .greenlighting_maximize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-green.png", sizingMethod="crop"); -} - -* html .greenlighting_content { - background:#A4FCA7; -} - - - .overlay_darkbluelighting { background-color:#FFF; filter:alpha(opacity=60); @@ -885,76 +666,4 @@ width:100%; height:16px; background:transparent url('lighting/spinner.gif') no-repeat center center -} - -/* FOR IE */ -* html .darkbluelighting_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-darkblue.png", sizingMethod="scale"); -} - -* html .darkbluelighting_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-darkblue.png", sizingMethod="scale"); -} - -* html .darkbluelighting_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-darkblue.png", sizingMethod="scale"); -} - -* html .darkbluelighting_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-darkblue.png", sizingMethod="scale"); -} - -* html darkbluelighting_se, * html .darkbluelighting_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_maximize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-darkblue.png", sizingMethod="crop"); -} - -* html .darkbluelighting_content { - background:#020EBA; -} - +} \ No newline at end of file diff --git a/lib/web/prototype/windows/themes/mac_os_x.css b/lib/web/prototype/windows/themes/mac_os_x.css index 24751f8688833..d2f556b876e52 100644 --- a/lib/web/prototype/windows/themes/mac_os_x.css +++ b/lib/web/prototype/windows/themes/mac_os_x.css @@ -109,62 +109,6 @@ padding-bottom:24px; } -/* FOR IE */ -* html .mac_os_x_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/TL_Main.png", sizingMethod="crop"); -} - -* html .mac_os_x_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/T_Main.png", sizingMethod="scale"); -} - -* html .mac_os_x_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/TR_Main.png", sizingMethod="crop"); -} - -* html .mac_os_x_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/L_Main.png", sizingMethod="scale"); -} - -* html .mac_os_x_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/R_Main.png", sizingMethod="scale"); -} - -* html .mac_os_x_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BL_Main.png", sizingMethod="crop"); -} - -* html .mac_os_x_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/B_Main.png", sizingMethod="scale"); -} - -* html .mac_os_x_se { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BR_Main.png", sizingMethod="crop"); -} - -* html .mac_os_x_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BR_Main.png", sizingMethod="crop"); -} - - /* Focused windows */ .overlay_blur_os_x { background-color: #85BBEF; @@ -275,59 +219,3 @@ .blur_os_x_s .status_bar { padding-bottom:24px; } - -/* FOR IE */ -* html .blur_os_x_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/TL.png", sizingMethod="crop"); -} - -* html .blur_os_x_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/T.png", sizingMethod="scale"); -} - -* html .blur_os_x_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/TR.png", sizingMethod="crop"); -} - -* html .blur_os_x_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/L.png", sizingMethod="scale"); -} - -* html .blur_os_x_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/R.png", sizingMethod="scale"); -} - -* html .blur_os_x_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BL.png", sizingMethod="crop"); -} - -* html .blur_os_x_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/B.png", sizingMethod="scale"); -} - -* html .blur_os_x_se { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BR.png", sizingMethod="crop"); -} - -* html .blur_os_x_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x/BR.png", sizingMethod="crop"); -} - diff --git a/lib/web/prototype/windows/themes/mac_os_x_dialog.css b/lib/web/prototype/windows/themes/mac_os_x_dialog.css index e663e3c5e2512..5aff20203d0f2 100644 --- a/lib/web/prototype/windows/themes/mac_os_x_dialog.css +++ b/lib/web/prototype/windows/themes/mac_os_x_dialog.css @@ -108,53 +108,3 @@ .mac_os_x_dialog_buttons { text-align: center; } -/* FOR IE */ -* html .mac_os_x_dialog_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/L.png", sizingMethod="scale"); -} - - -* html .mac_os_x_dialog_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/R.png", sizingMethod="scale"); -} - -* html .mac_os_x_dialog_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/L.png", sizingMethod="scale"); -} - -* html .mac_os_x_dialog_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/R.png", sizingMethod="scale"); -} - -* html .mac_os_x_dialog_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/BL.png", sizingMethod="crop"); -} - -* html .mac_os_x_dialog_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/B.png", sizingMethod="scale"); -} - -* html .mac_os_x_dialog_se { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/BR.png", sizingMethod="crop"); -} - -* html .mac_os_x_dialog_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/mac_os_x_dialog/BR.png", sizingMethod="crop"); -} - diff --git a/lib/web/prototype/windows/themes/nuncio.css b/lib/web/prototype/windows/themes/nuncio.css index 2c439bd0019a9..275ba53436f40 100644 --- a/lib/web/prototype/windows/themes/nuncio.css +++ b/lib/web/prototype/windows/themes/nuncio.css @@ -95,70 +95,3 @@ .top_draggable, .bottom_draggable { cursor:move } -/* FOR IE */ -* html .nuncio_nw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/top_left.png", sizingMethod="crop"); -} - -* html .nuncio_n { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/top_mid.png", sizingMethod="scale"); -} - -* html .nuncio_ne { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/top_right.png", sizingMethod="crop"); -} - -* html .nuncio_w { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/center_left.png", sizingMethod="scale"); -} - -* html .nuncio_e { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/center_right.png", sizingMethod="scale"); -} - -* html .nuncio_sw { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/bottom_left.png", sizingMethod="crop"); -} - -* html .nuncio_s { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/bottom_mid.png", sizingMethod="scale"); -} - -* html .nuncio_se { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/bottom_right.png", sizingMethod="crop"); -} - -* html .nuncio_sizer { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/bottom_right.png", sizingMethod="crop"); -} - -* html .nuncio_close { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/close.png", sizingMethod="crop"); -} - -* html .nuncio_minimize { - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/nuncio/minimize.png", sizingMethod="crop"); -} - From bf831c6031464b2ba0d07ff053b3b14d7a0ba1e0 Mon Sep 17 00:00:00 2001 From: Tomas Votruba <tomas.vot@gmail.com> Date: Thu, 22 Nov 2018 11:19:02 +0100 Subject: [PATCH 1332/1415] fixup --- lib/internal/Magento/Framework/Message/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php index 2b1b60bf76a46..1138cf4f8f7fb 100644 --- a/lib/internal/Magento/Framework/Message/Manager.php +++ b/lib/internal/Magento/Framework/Message/Manager.php @@ -67,7 +67,7 @@ class Manager implements ManagerInterface * @param Event\ManagerInterface $eventManager * @param LoggerInterface $logger * @param string $defaultGroup - * @param ExceptionMessageFactoryInterface|null $exceptionMessageFactory exceptionMessageFactory + * @param ExceptionMessageFactoryInterface|null $exceptionMessageFactory */ public function __construct( Session $session, From 922d398fdbaba69ad54ace1d3291f851e6f33aa7 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 22 Nov 2018 15:14:22 +0200 Subject: [PATCH 1333/1415] GraphQL-176: Show only active CMS Blocks --- .../CmsGraphQl/Model/Resolver/Blocks.php | 27 +++++-------------- .../Model/Resolver/DataProvider/Block.php | 4 ++- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php index fabb479763e60..2f1c84848eb52 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php @@ -14,7 +14,6 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Psr\Log\LoggerInterface; /** * CMS blocks field resolver, used for GraphQL request processing @@ -26,20 +25,13 @@ class Blocks implements ResolverInterface */ private $blockDataProvider; - /** - * @var LoggerInterface - */ - private $logger; - /** * @param BlockDataProvider $blockDataProvider */ public function __construct( - BlockDataProvider $blockDataProvider, - LoggerInterface $logger + BlockDataProvider $blockDataProvider ) { $this->blockDataProvider = $blockDataProvider; - $this->logger = $logger; } /** @@ -84,19 +76,12 @@ private function getBlockIdentifiers(array $args): array private function getBlocksData(array $blockIdentifiers): array { $blocksData = []; - try { - foreach ($blockIdentifiers as $blockIdentifier) { - $blockData = $this->blockDataProvider->getData($blockIdentifier); - if (!empty($blockData)) { - $blocksData[$blockIdentifier] = $blockData; - } else { - $this->logger->warning( - sprintf('The CMS block with the "%s" Identifier is disabled.', $blockIdentifier) - ); - } + foreach ($blockIdentifiers as $blockIdentifier) { + try { + $blocksData[$blockIdentifier] = $this->blockDataProvider->getData($blockIdentifier); + } catch (NoSuchEntityException $e) { + $blocksData[$blockIdentifier] = new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } - } catch (NoSuchEntityException $e) { - throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } return $blocksData; } diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index d47a0dca27157..c1a694dcd73b7 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -49,7 +49,9 @@ public function getData(string $blockIdentifier): array $block = $this->blockRepository->getById($blockIdentifier); if (false === $block->isActive()) { - return []; + throw new NoSuchEntityException( + __('The CMS block with the "%1" ID doesn\'t exist.', $blockIdentifier) + ); } $renderedContent = $this->widgetFilter->filter($block->getContent()); From 500fd029b14978707acca6830c08d65108e16f73 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Thu, 22 Nov 2018 17:24:46 +0300 Subject: [PATCH 1334/1415] MAGETWO-96125: Points not added with New Account Email Confirmation enabled - Change template functionality --- app/code/Magento/Customer/Api/AccountManagementInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php index 6c1a24d5029ac..e84da5b9fcd57 100644 --- a/app/code/Magento/Customer/Api/AccountManagementInterface.php +++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php @@ -31,7 +31,7 @@ interface AccountManagementInterface * @param \Magento\Customer\Api\Data\CustomerInterface $customer * @param string $password * @param string $redirectUrl - * @param array $extensions + * @param string[] $extensions * @return \Magento\Customer\Api\Data\CustomerInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -50,7 +50,7 @@ public function createAccount( * @param string $hash Password hash that we can save directly * @param string $redirectUrl URL fed to welcome email templates. Can be used by templates to, for example, direct * the customer to a product they were looking at after pressing confirmation link. - * @param array $extensions + * @param string[] $extensions * @return \Magento\Customer\Api\Data\CustomerInterface * @throws \Magento\Framework\Exception\InputException If bad input is provided * @throws \Magento\Framework\Exception\State\InputMismatchException If the provided email is already used From 6d984eb0ff9d596ece553ff50d77d68c6749ff33 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 22 Nov 2018 16:29:17 +0200 Subject: [PATCH 1335/1415] GraphQL-176: Show only active CMS Blocks --- .../TestFramework/TestCase/GraphQl/Client.php | 5 +- .../ResponseContainsErrorsException.php | 41 +++++++ .../Magento/GraphQl/Cms/CmsBlockTest.php | 116 +++++++++++------- .../testsuite/Magento/Cms/_files/blocks.php | 52 ++++++++ .../Magento/Cms/_files/blocks_rollback.php | 23 ++++ 5 files changed, 192 insertions(+), 45 deletions(-) create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php create mode 100644 dev/tests/integration/testsuite/Magento/Cms/_files/blocks.php create mode 100644 dev/tests/integration/testsuite/Magento/Cms/_files/blocks_rollback.php diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index 64ad44528572d..d34a72707b89e 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -102,7 +102,10 @@ private function processErrors($responseBodyArray) } } - throw new \Exception('GraphQL response contains errors: ' . $errorMessage); + throw new ResponseContainsErrorsException( + 'GraphQL response contains errors: ' . $errorMessage, + $responseBodyArray + ); } throw new \Exception('GraphQL responded with an unknown error: ' . json_encode($responseBodyArray)); } diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php new file mode 100644 index 0000000000000..568de57543d84 --- /dev/null +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/ResponseContainsErrorsException.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\TestFramework\TestCase\GraphQl; + +/** + * Response contains errors exception + */ +class ResponseContainsErrorsException extends \Exception +{ + /** + * @var array + */ + private $responseData; + + /** + * @param string $message + * @param array $responseData + * @param \Exception|null $cause + * @param int $code + */ + public function __construct(string $message, array $responseData, \Exception $cause = null, int $code = 0) + { + parent::__construct($message, $code, $cause); + $this->responseData = $responseData; + } + + /** + * Get response data + * + * @return array + */ + public function getResponseData(): array + { + return $this->responseData; + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php index d8e06fd08385c..57f526b1cb2f7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Cms/CmsBlockTest.php @@ -7,43 +7,45 @@ namespace Magento\GraphQl\Cms; -use Magento\Cms\Model\Block; -use Magento\Cms\Model\GetBlockByIdentifier; -use Magento\Store\Model\StoreManagerInterface; +use Magento\Cms\Api\BlockRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Widget\Model\Template\FilterEmulate; class CmsBlockTest extends GraphQlAbstract { /** - * @var \Magento\TestFramework\ObjectManager + * @var BlockRepositoryInterface */ - private $objectManager; + private $blockRepository; + + /** + * @var FilterEmulate + */ + private $filterEmulate; protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->blockRepository = Bootstrap::getObjectManager()->get(BlockRepositoryInterface::class); + $this->filterEmulate = Bootstrap::getObjectManager()->get(FilterEmulate::class); } /** * Verify the fields of CMS Block selected by identifiers * - * @magentoApiDataFixture Magento/Cms/_files/block.php + * @magentoApiDataFixture Magento/Cms/_files/blocks.php */ - public function testGetCmsBlocksByIdentifiers() + public function testGetCmsBlock() { - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $storeId = (int)$storeManager->getStore()->getId(); - $cmsBlock = $this->objectManager->get(GetBlockByIdentifier::class)->execute("fixture_block", $storeId); + $cmsBlock = $this->blockRepository->getById('enabled_block'); $cmsBlockData = $cmsBlock->getData(); - /** @var FilterEmulate $widgetFilter */ - $widgetFilter = $this->objectManager->get(FilterEmulate::class); - $renderedContent = $widgetFilter->setUseSessionInUrl(false)->filter($cmsBlock->getContent()); + $renderedContent = $this->filterEmulate->setUseSessionInUrl(false)->filter($cmsBlock->getContent()); + $query = <<<QUERY { - cmsBlocks(identifiers: "fixture_block") { + cmsBlocks(identifiers: "enabled_block") { items { identifier title @@ -52,34 +54,30 @@ public function testGetCmsBlocksByIdentifiers() } } QUERY; - $response = $this->graphQlQuery($query); - $this->assertArrayHasKey('cmsBlocks', $response); - $this->assertArrayHasKey('items', $response['cmsBlocks']); - $this->assertArrayHasKey('content', $response['cmsBlocks']['items'][0]); - $this->assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); - $this->assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); - $this->assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); + + self::assertArrayHasKey('cmsBlocks', $response); + self::assertArrayHasKey('items', $response['cmsBlocks']); + + self::assertEquals($cmsBlockData['identifier'], $response['cmsBlocks']['items'][0]['identifier']); + self::assertEquals($cmsBlockData['title'], $response['cmsBlocks']['items'][0]['title']); + self::assertEquals($renderedContent, $response['cmsBlocks']['items'][0]['content']); } /** * Verify the message when CMS Block is disabled * - * @magentoApiDataFixture Magento/Cms/_files/block.php + * @expectedException \Exception + * @expectedExceptionMessage The CMS block with the "disabled_block" ID doesn't exist + * + * @magentoApiDataFixture Magento/Cms/_files/blocks.php */ - public function testGetDisabledCmsBlockByIdentifiers() + public function testGetDisabledCmsBlock() { - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $storeId = (int)$storeManager->getStore()->getId(); - $cmsBlockId = $this->objectManager->get(GetBlockByIdentifier::class) - ->execute("fixture_block", $storeId) - ->getId(); - $this->objectManager->get(Block::class)->load($cmsBlockId)->setIsActive(0)->save(); $query = <<<QUERY { - cmsBlocks(identifiers: "fixture_block") { + cmsBlocks(identifiers: "disabled_block") { items { identifier title @@ -88,16 +86,16 @@ public function testGetDisabledCmsBlockByIdentifiers() } } QUERY; - - $this->expectException(\Exception::class); - $this->expectExceptionMessage('No such entity.'); $this->graphQlQuery($query); } /** * Verify the message when identifiers were not specified + * + * @expectedException \Exception + * @expectedExceptionMessage "identifiers" of CMS blocks should be specified */ - public function testGetCmsBlockBypassingIdentifiers() + public function testGetCmsBlocksWithoutIdentifiers() { $query = <<<QUERY @@ -111,21 +109,21 @@ public function testGetCmsBlockBypassingIdentifiers() } } QUERY; - - $this->expectException(\Exception::class); - $this->expectExceptionMessage('"identifiers" of CMS blocks should be specified'); $this->graphQlQuery($query); } /** * Verify the message when CMS Block with such identifiers does not exist + * + * @expectedException \Exception + * @expectedExceptionMessage The CMS block with the "nonexistent_id" ID doesn't exist. */ public function testGetCmsBlockByNonExistentIdentifier() { $query = <<<QUERY { - cmsBlocks(identifiers: "0") { + cmsBlocks(identifiers: "nonexistent_id") { items { identifier title @@ -134,9 +132,39 @@ public function testGetCmsBlockByNonExistentIdentifier() } } QUERY; - - $this->expectException(\Exception::class); - $this->expectExceptionMessage('The CMS block with the "0" ID doesn\'t exist.'); $this->graphQlQuery($query); } + + /** + * Verify the fields of CMS Block selected by identifiers + * + * @magentoApiDataFixture Magento/Cms/_files/blocks.php + */ + public function testGetEnabledAndDisabledCmsBlockInOneRequest() + { + $query = + <<<QUERY +{ + cmsBlocks(identifiers: ["enabled_block", "disabled_block"]) { + items { + identifier + } + } +} +QUERY; + + try { + $this->graphQlQuery($query); + self::fail('Response should contains errors.'); + } catch (ResponseContainsErrorsException $e) { + $responseData = $e->getResponseData(); + } + + self::assertNotEmpty($responseData); + self::assertEquals('enabled_block', $responseData['data']['cmsBlocks']['items'][0]['identifier']); + self::assertEquals( + 'The CMS block with the "disabled_block" ID doesn\'t exist.', + $responseData['errors'][0]['message'] + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/Cms/_files/blocks.php b/dev/tests/integration/testsuite/Magento/Cms/_files/blocks.php new file mode 100644 index 0000000000000..bbdc697645a42 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Cms/_files/blocks.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Cms\Api\BlockRepositoryInterface; +use Magento\Cms\Api\Data\BlockInterface; +use Magento\Cms\Api\Data\BlockInterfaceFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var BlockRepositoryInterface $blockRepository */ +$blockRepository = Bootstrap::getObjectManager()->get(BlockRepositoryInterface::class); +/** @var BlockInterfaceFactory $blockFactory */ +$blockFactory = Bootstrap::getObjectManager()->get(BlockInterfaceFactory::class); +$storeId = Bootstrap::getObjectManager()->get(StoreManagerInterface::class)->getStore()->getId(); + +/** @var BlockInterface $block */ +$block = $blockFactory->create([ + 'data' => [ + BlockInterface::IDENTIFIER => 'enabled_block', + BlockInterface::TITLE => 'Enabled CMS Block Title', + BlockInterface::CONTENT => ' + <h1>Enabled Block</h1> + <a href="{{store url=""}}">store url</a> + <p>Config value: "{{config path="web/unsecure/base_url"}}".</p> + <p>Custom variable: "{{customvar code="variable_code"}}".</p> + ', + BlockInterface::IS_ACTIVE => 1, + 'store_id' => [$storeId], + ] +]); +$blockRepository->save($block); + +/** @var BlockInterface $block */ +$block = $blockFactory->create([ + 'data' => [ + BlockInterface::IDENTIFIER => 'disabled_block', + BlockInterface::TITLE => 'Disabled CMS Block Title', + BlockInterface::CONTENT => ' + <h1>Disabled Block</h1> + <a href="{{store url=""}}">store url</a> + <p>Config value: "{{config path="web/unsecure/base_url"}}".</p> + <p>Custom variable: "{{customvar code="variable_code"}}".</p> + ', + BlockInterface::IS_ACTIVE => 0, + 'store_id' => [$storeId], + ] +]); +$blockRepository->save($block); diff --git a/dev/tests/integration/testsuite/Magento/Cms/_files/blocks_rollback.php b/dev/tests/integration/testsuite/Magento/Cms/_files/blocks_rollback.php new file mode 100644 index 0000000000000..a7a2a51524cf0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Cms/_files/blocks_rollback.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Cms\Api\BlockRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var BlockRepositoryInterface $blockRepository */ +$blockRepository = Bootstrap::getObjectManager()->get(BlockRepositoryInterface::class); + +foreach (['enabled_block', 'disabled_block'] as $blockId) { + try { + $blockRepository->deleteById($blockId); + } catch (NoSuchEntityException $e) { + /** + * Tests which are wrapped with MySQL transaction clear all data by transaction rollback. + */ + } +} From 6e32307e48656413d3f396db180e92288ce7a017 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 22 Nov 2018 16:43:01 +0200 Subject: [PATCH 1336/1415] GraphQL-260: Fixed bug with uniq type --- app/code/Magento/SendFriendGraphQl/etc/schema.graphqls | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 14f73a034a7ea..1234b65a7b910 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -22,6 +22,11 @@ input SendEmailToFriendRecipientInput { email: String! } +type SendEmailToFriendOutput { + sender: SendEmailToFriendSender + recipients: [SendEmailToFriendRecipient] +} + type SendEmailToFriendSender { name: String! email: String! @@ -32,8 +37,3 @@ type SendEmailToFriendRecipient { name: String! email: String! } - -type SendEmailToFriendOutput { - sender: SendEmailToFriendSender - recipients: [SendEmailToFriendRecipient] -} \ No newline at end of file From d3a22e9e7a10f069989b633f3b5fffe09b6ec8d2 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 22 Nov 2018 16:48:53 +0200 Subject: [PATCH 1337/1415] GraphQL-176: Show only active CMS Blocks -- Fix static tests --- app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php | 4 ++++ .../Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php | 2 ++ .../Magento/TestFramework/TestCase/GraphQl/Client.php | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php index 2f1c84848eb52..e55db2a3fa42a 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/Blocks.php @@ -55,6 +55,8 @@ public function resolve( } /** + * Get block identifiers + * * @param array $args * @return string[] * @throws GraphQlInputException @@ -69,6 +71,8 @@ private function getBlockIdentifiers(array $args): array } /** + * Get blocks data + * * @param array $blockIdentifiers * @return array * @throws GraphQlNoSuchEntityException diff --git a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php index c1a694dcd73b7..47a2439c4fad0 100644 --- a/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php +++ b/app/code/Magento/CmsGraphQl/Model/Resolver/DataProvider/Block.php @@ -40,6 +40,8 @@ public function __construct( } /** + * Get block data + * * @param string $blockIdentifier * @return array * @throws NoSuchEntityException diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index d34a72707b89e..e94cc9613b1c9 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -29,8 +29,6 @@ class Client private $json; /** - * CurlClient constructor. - * * @param CurlClient|null $curlClient * @param JsonSerializer|null $json */ @@ -81,6 +79,8 @@ public function postQuery(string $query, array $variables = [], string $operatio } /** + * Process errors + * * @param array $responseBodyArray * @throws \Exception */ From 772d4da83ee63044a64ad49e19c8052f6f54e109 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 22 Nov 2018 16:58:41 +0200 Subject: [PATCH 1338/1415] GraphQL-176: Show only active CMS Blocks -- Fix static tests --- .../framework/Magento/TestFramework/TestCase/GraphQl/Client.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index e94cc9613b1c9..5458b5cfbb731 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -112,6 +112,8 @@ private function processErrors($responseBodyArray) } /** + * Get endpoint url + * * @return string resource URL * @throws \Exception */ From 492e26426d89d139c2e565f4cf095ff7afeb651d Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 22 Nov 2018 17:53:23 +0200 Subject: [PATCH 1339/1415] magento-engcom/magento2ce#2354: Fixed Code Style Issues --- .../Block/Product/ProductList/Crosssell.php | 4 ++++ .../Block/Product/ProductList/Related.php | 6 ++++++ .../Block/Product/ProductList/Upsell.php | 21 +++++++++++++++++++ .../Controller/Adminhtml/History/Download.php | 4 +++- .../Model/Plugin/CustomerPlugin.php | 3 +++ .../Review/Model/ResourceModel/Rating.php | 9 ++++++++ .../header/actions-group/_notifications.less | 4 ++-- 7 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php index 043704a9f2bca..596cd7cc5bdce 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php @@ -9,6 +9,9 @@ */ namespace Magento\Catalog\Block\Product\ProductList; +/** + * Crosssell block for product + */ class Crosssell extends \Magento\Catalog\Block\Product\AbstractProduct { /** @@ -43,6 +46,7 @@ protected function _prepareData() /** * Before rendering html process + * * Prepare items collection * * @return \Magento\Catalog\Block\Product\ProductList\Crosssell diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 91e4161ce53b1..6de70bb971367 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -77,6 +77,8 @@ public function __construct( } /** + * Prepare data + * * @return $this */ protected function _prepareData() @@ -103,6 +105,8 @@ protected function _prepareData() } /** + * Before to html handler + * * @return $this */ protected function _beforeToHtml() @@ -112,6 +116,8 @@ protected function _beforeToHtml() } /** + * Get collection items + * * @return Collection */ public function getItems() diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index ef38693a5454c..24822447ae915 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -91,6 +91,8 @@ public function __construct( } /** + * Prepare data + * * @return $this */ protected function _prepareData() @@ -121,6 +123,8 @@ protected function _prepareData() } /** + * Before to html handler + * * @return $this */ protected function _beforeToHtml() @@ -130,6 +134,8 @@ protected function _beforeToHtml() } /** + * Get items collection + * * @return Collection */ public function getItemCollection() @@ -145,6 +151,8 @@ public function getItemCollection() } /** + * Get collection items + * * @return \Magento\Framework\DataObject[] */ public function getItems() @@ -156,6 +164,8 @@ public function getItems() } /** + * Get row count + * * @return float */ public function getRowCount() @@ -164,6 +174,8 @@ public function getRowCount() } /** + * Set column count + * * @param string $columns * @return $this */ @@ -176,6 +188,8 @@ public function setColumnCount($columns) } /** + * Get column count + * * @return int */ public function getColumnCount() @@ -184,6 +198,8 @@ public function getColumnCount() } /** + * Reset items iterator + * * @return void */ public function resetItemsIterator() @@ -193,6 +209,8 @@ public function resetItemsIterator() } /** + * Get iterable item + * * @return mixed */ public function getIterableItem() @@ -204,6 +222,7 @@ public function getIterableItem() /** * Set how many items we need to show in upsell block + * * Notice: this parameter will be also applied * * @param string $type @@ -219,6 +238,8 @@ public function setItemLimit($type, $limit) } /** + * Get item limit + * * @param string $type * @return array|int */ diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php index d46fda9a1c0ef..ba37cc8aacff9 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -9,6 +8,9 @@ use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; +/** + * Download history controller + */ class Download extends \Magento\ImportExport\Controller\Adminhtml\History implements HttpGetActionInterface { /** diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index 7c8a92397d8c5..035013e572833 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -14,6 +14,9 @@ use Magento\Newsletter\Model\SubscriberFactory; use Magento\Store\Model\StoreManagerInterface; +/** + * Newsletter Plugin for customer + */ class CustomerPlugin { /** diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 9cd9b0650a278..78020ce3f8184 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -178,6 +178,8 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) } /** + * Process rating codes + * * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ @@ -201,6 +203,8 @@ protected function processRatingCodes(\Magento\Framework\Model\AbstractModel $ob } /** + * Process rating stores + * * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ @@ -224,6 +228,8 @@ protected function processRatingStores(\Magento\Framework\Model\AbstractModel $o } /** + * Delete rating data + * * @param int $ratingId * @param string $table * @param array $storeIds @@ -247,6 +253,8 @@ protected function deleteRatingData($ratingId, $table, array $storeIds) } /** + * Insert rating data + * * @param string $table * @param array $data * @return void @@ -269,6 +277,7 @@ protected function insertRatingData($table, array $data) /** * Perform actions after object delete + * * Prepare rating data for reaggregate all data for reviews * * @param \Magento\Framework\Model\AbstractModel $object diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index ceeb8d8eeb2b3..40ebb6f3c4569 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -97,14 +97,14 @@ display: inline-block; font-size: @notifications__font-size; font-weight: @font-weight__bold; + height: 18px; left: 50%; margin-left: .3em; margin-top: -1.1em; + min-width: 18px; padding: .3em .5em; position: absolute; top: 50%; - min-width: 18px; - height: 18px; } } From adb97a3efda543e0985a178b91b1fc6d9e1efa71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torben=20Ho=CC=88hn?= <torhoehn@gmail.com> Date: Thu, 22 Nov 2018 19:42:10 +0100 Subject: [PATCH 1340/1415] local themes should be added to git repo --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8831ad0a17c39..68d38d9ca7817 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,6 @@ atlassian* /.php_cs /.php_cs.cache /grunt-config.json -/dev/tools/grunt/configs/local-themes.js /pub/media/*.* !/pub/media/.htaccess /pub/media/attribute/* From d2dd7b39772a7c0a8a2cca2fea4925d033536a1a Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Thu, 22 Nov 2018 21:24:58 +0200 Subject: [PATCH 1341/1415] Code style fixes --- .../Framework/Acl/Loader/ResourceLoader.php | 3 ++ lib/internal/Magento/Framework/Amqp/Queue.php | 10 ++-- .../CollectionProcessor/JoinProcessor.php | 3 ++ .../Framework/App/ResourceConnection.php | 1 + .../Magento/Framework/App/Utility/Classes.php | 3 ++ .../Magento/Framework/DataObject/Copy.php | 7 ++- .../Framework/Exception/BulkException.php | 4 ++ lib/internal/Magento/Framework/File/Mime.php | 3 ++ .../Magento/Framework/Logger/Handler/Base.php | 10 ++-- .../Framework/Logger/Handler/System.php | 3 ++ .../Magento/Framework/Message/Manager.php | 4 +- .../Magento/Framework/Model/AbstractModel.php | 8 +++- .../Framework/Module/Setup/Context.php | 18 ++++++++ .../Framework/ObjectManager/Profiler/Log.php | 4 +- .../Session/SaveHandler/Redis/Config.php | 46 +++++++++---------- 15 files changed, 85 insertions(+), 42 deletions(-) diff --git a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php index afcd1d82bb8d7..af781e19d045d 100644 --- a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php +++ b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php @@ -12,6 +12,9 @@ use Magento\Framework\Acl\AclResource\ProviderInterface; use Magento\Framework\Acl\AclResourceFactory; +/** + * ACL Loader + */ class ResourceLoader implements \Magento\Framework\Acl\LoaderInterface { /** diff --git a/lib/internal/Magento/Framework/Amqp/Queue.php b/lib/internal/Magento/Framework/Amqp/Queue.php index 0587d5a592746..ff5bae5017fb9 100644 --- a/lib/internal/Magento/Framework/Amqp/Queue.php +++ b/lib/internal/Magento/Framework/Amqp/Queue.php @@ -63,7 +63,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.0.0 */ public function dequeue() @@ -98,7 +98,7 @@ public function dequeue() } /** - * {@inheritdoc} + * @inheritdoc * @since 100.0.0 */ public function acknowledge(EnvelopeInterface $envelope) @@ -119,7 +119,7 @@ public function acknowledge(EnvelopeInterface $envelope) } /** - * {@inheritdoc} + * @inheritdoc * @since 100.0.0 */ public function subscribe($callback) @@ -153,7 +153,7 @@ public function subscribe($callback) } /** - * (@inheritdoc) + * @inheritdoc * @since 100.0.0 */ public function reject(EnvelopeInterface $envelope, $requeue = true, $rejectionMessage = null) @@ -172,7 +172,7 @@ public function reject(EnvelopeInterface $envelope, $requeue = true, $rejectionM } /** - * (@inheritdoc) + * @inheritdoc * @since 100.0.0 */ public function push(EnvelopeInterface $envelope) diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php index 34f16212c829b..29029ab6efac5 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php @@ -10,6 +10,9 @@ use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\Collection\AbstractDb; +/** + * Search criteria join processor + */ class JoinProcessor implements CollectionProcessorInterface { /** diff --git a/lib/internal/Magento/Framework/App/ResourceConnection.php b/lib/internal/Magento/Framework/App/ResourceConnection.php index 4652d2aaf6d30..3dbe5f2db54c6 100644 --- a/lib/internal/Magento/Framework/App/ResourceConnection.php +++ b/lib/internal/Magento/Framework/App/ResourceConnection.php @@ -12,6 +12,7 @@ /** * Application provides ability to configure multiple connections to persistent storage. * This class provides access to all these connections. + * * @api */ class ResourceConnection diff --git a/lib/internal/Magento/Framework/App/Utility/Classes.php b/lib/internal/Magento/Framework/App/Utility/Classes.php index 289fc8fc8c88a..3518264e1ab3b 100644 --- a/lib/internal/Magento/Framework/App/Utility/Classes.php +++ b/lib/internal/Magento/Framework/App/Utility/Classes.php @@ -9,6 +9,9 @@ use Magento\Framework\Component\ComponentRegistrar; +/** + * Utility for class names processing + */ class Classes { /** diff --git a/lib/internal/Magento/Framework/DataObject/Copy.php b/lib/internal/Magento/Framework/DataObject/Copy.php index f4e733feb0bed..8d8896c6cb62a 100644 --- a/lib/internal/Magento/Framework/DataObject/Copy.php +++ b/lib/internal/Magento/Framework/DataObject/Copy.php @@ -4,11 +4,11 @@ * See COPYING.txt for license details. */ +namespace Magento\Framework\DataObject; + /** * Utility class for copying data sets between objects */ -namespace Magento\Framework\DataObject; - class Copy { /** @@ -116,8 +116,7 @@ protected function dispatchCopyFieldSetEvent($fieldset, $aspect, $source, $targe } /** - * Get data from object|array to object|array containing fields - * from fieldset matching an aspect. + * Get data from object|array to object|array containing fields from fieldset matching an aspect. * * @param string $fieldset * @param string $aspect a field name diff --git a/lib/internal/Magento/Framework/Exception/BulkException.php b/lib/internal/Magento/Framework/Exception/BulkException.php index 9ee43bce2b913..168e910e0d375 100644 --- a/lib/internal/Magento/Framework/Exception/BulkException.php +++ b/lib/internal/Magento/Framework/Exception/BulkException.php @@ -39,6 +39,8 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** + * Add data + * * @param array $data */ public function addData($data) @@ -47,6 +49,8 @@ public function addData($data) } /** + * Retrieve data + * * @return array */ public function getData() diff --git a/lib/internal/Magento/Framework/File/Mime.php b/lib/internal/Magento/Framework/File/Mime.php index f235d5765c780..9d768915868e2 100644 --- a/lib/internal/Magento/Framework/File/Mime.php +++ b/lib/internal/Magento/Framework/File/Mime.php @@ -6,6 +6,9 @@ namespace Magento\Framework\File; +/** + * Utility for mime type retrieval + */ class Mime { /** diff --git a/lib/internal/Magento/Framework/Logger/Handler/Base.php b/lib/internal/Magento/Framework/Logger/Handler/Base.php index 84109b7b26325..5ae38101a7e0f 100644 --- a/lib/internal/Magento/Framework/Logger/Handler/Base.php +++ b/lib/internal/Magento/Framework/Logger/Handler/Base.php @@ -11,6 +11,9 @@ use Monolog\Handler\StreamHandler; use Monolog\Logger; +/** + * Base stream handler + */ class Base extends StreamHandler { /** @@ -32,6 +35,7 @@ class Base extends StreamHandler * @param DriverInterface $filesystem * @param string $filePath * @param string $fileName + * @throws \Exception */ public function __construct( DriverInterface $filesystem, @@ -71,11 +75,7 @@ private function sanitizeFileName($fileName) } /** - * {@inheritDoc} - * - * @param array $record - * - * @return void + * @inheritDoc */ public function write(array $record) { diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php index f2de01d0745c4..c519e320a254d 100644 --- a/lib/internal/Magento/Framework/Logger/Handler/System.php +++ b/lib/internal/Magento/Framework/Logger/Handler/System.php @@ -9,6 +9,9 @@ use Magento\Framework\Filesystem\DriverInterface; use Monolog\Logger; +/** + * System stream handler + */ class System extends Base { /** diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php index 1138cf4f8f7fb..c3b5701057d73 100644 --- a/lib/internal/Magento/Framework/Message/Manager.php +++ b/lib/internal/Magento/Framework/Message/Manager.php @@ -89,7 +89,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getDefaultGroup() { @@ -110,8 +110,8 @@ protected function prepareGroup($group) /** * @inheritdoc * - * @param string|null $group * @param bool $clear + * @param string|null $group * @return Collection */ public function getMessages($clear = false, $group = null) diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index c1a597e13714b..78275a8134633 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -216,6 +216,8 @@ protected function _init($resourceModel) } /** + * Remove unneeded properties from serialization + * * @return string[] */ public function __sleep() @@ -337,8 +339,8 @@ public function hasDataChanges() * * If $key is an array, it will overwrite all the data in the object. * - * @param string|array $key - * @param mixed $value + * @param string|array $key + * @param mixed $value * @return $this */ public function setData($key, $value = null) @@ -616,6 +618,8 @@ protected function _hasModelChanged() } /** + * Check if save is allowed + * * @return bool */ public function isSaveAllowed() diff --git a/lib/internal/Magento/Framework/Module/Setup/Context.php b/lib/internal/Magento/Framework/Module/Setup/Context.php index 81dcb08e95cad..4c6240e4c82d4 100644 --- a/lib/internal/Magento/Framework/Module/Setup/Context.php +++ b/lib/internal/Magento/Framework/Module/Setup/Context.php @@ -99,6 +99,8 @@ public function __construct( } /** + * Retrieve event manager + * * @return \Magento\Framework\Event\ManagerInterface */ public function getEventManager() @@ -107,6 +109,8 @@ public function getEventManager() } /** + * Retrieve logger + * * @return \Psr\Log\LoggerInterface */ public function getLogger() @@ -115,6 +119,8 @@ public function getLogger() } /** + * Retrieve module list + * * @return \Magento\Framework\Module\ModuleListInterface */ public function getModuleList() @@ -123,6 +129,8 @@ public function getModuleList() } /** + * Retrieve modules reader + * * @return \Magento\Framework\Module\Dir\Reader */ public function getModulesReader() @@ -131,6 +139,8 @@ public function getModulesReader() } /** + * Retrieve resource model + * * @return \Magento\Framework\App\ResourceConnection */ public function getResourceModel() @@ -139,6 +149,8 @@ public function getResourceModel() } /** + * Retrieve migration factory + * * @return \Magento\Framework\Module\Setup\MigrationFactory */ public function getMigrationFactory() @@ -147,6 +159,8 @@ public function getMigrationFactory() } /** + * Retrieve resource + * * @return \Magento\Framework\Module\ResourceInterface */ public function getResource() @@ -155,6 +169,8 @@ public function getResource() } /** + * Retrieve encryptor + * * @return \Magento\Framework\Encryption\EncryptorInterface */ public function getEncryptor() @@ -163,6 +179,8 @@ public function getEncryptor() } /** + * Retrieve filesystem + * * @return \Magento\Framework\Filesystem */ public function getFilesystem() diff --git a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php index 79f014d896478..c1c1e7c17709a 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php +++ b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,9 @@ use Magento\Framework\ObjectManager\Profiler\Tree\Item as Item; +/** + * Class Log + */ class Log { /** diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index a5eddb402a1d4..70b666f8a4e6b 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -173,7 +173,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getLogLevel() { @@ -181,7 +181,7 @@ public function getLogLevel() } /** - * {@inheritdoc} + * @inheritdoc */ public function getHost() { @@ -189,7 +189,7 @@ public function getHost() } /** - * {@inheritdoc} + * @inheritdoc */ public function getPort() { @@ -197,7 +197,7 @@ public function getPort() } /** - * {@inheritdoc} + * @inheritdoc */ public function getDatabase() { @@ -205,7 +205,7 @@ public function getDatabase() } /** - * {@inheritdoc} + * @inheritdoc */ public function getPassword() { @@ -213,7 +213,7 @@ public function getPassword() } /** - * {@inheritdoc} + * @inheritdoc */ public function getTimeout() { @@ -221,7 +221,7 @@ public function getTimeout() } /** - * {@inheritdoc} + * @inheritdoc */ public function getPersistentIdentifier() { @@ -229,7 +229,7 @@ public function getPersistentIdentifier() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompressionThreshold() { @@ -237,7 +237,7 @@ public function getCompressionThreshold() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompressionLibrary() { @@ -245,7 +245,7 @@ public function getCompressionLibrary() } /** - * {@inheritdoc} + * @inheritdoc */ public function getMaxConcurrency() { @@ -253,7 +253,7 @@ public function getMaxConcurrency() } /** - * {@inheritdoc} + * @inheritdoc */ public function getMaxLifetime() { @@ -261,7 +261,7 @@ public function getMaxLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getMinLifetime() { @@ -269,7 +269,7 @@ public function getMinLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getDisableLocking() { @@ -277,7 +277,7 @@ public function getDisableLocking() } /** - * {@inheritdoc} + * @inheritdoc */ public function getBotLifetime() { @@ -285,7 +285,7 @@ public function getBotLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getBotFirstLifetime() { @@ -293,7 +293,7 @@ public function getBotFirstLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getFirstLifetime() { @@ -301,7 +301,7 @@ public function getFirstLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getBreakAfter() { @@ -309,7 +309,7 @@ public function getBreakAfter() } /** - * {@inheritdoc} + * @inheritdoc */ public function getLifetime() { @@ -320,7 +320,7 @@ public function getLifetime() } /** - * {@inheritdoc} + * @inheritdoc */ public function getSentinelServers() { @@ -328,7 +328,7 @@ public function getSentinelServers() } /** - * {@inheritdoc} + * @inheritdoc */ public function getSentinelMaster() { @@ -336,7 +336,7 @@ public function getSentinelMaster() } /** - * {@inheritdoc} + * @inheritdoc */ public function getSentinelVerifyMaster() { @@ -344,7 +344,7 @@ public function getSentinelVerifyMaster() } /** - * {@inheritdoc} + * @inheritdoc */ public function getSentinelConnectRetries() { @@ -352,7 +352,7 @@ public function getSentinelConnectRetries() } /** - * {@inheritdoc} + * @inheritdoc */ public function getFailAfter() { From 8b1afea641b2ac327a16ed948c18b31f23c9ab18 Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Fri, 23 Nov 2018 07:08:39 +0530 Subject: [PATCH 1342/1415] Update new_default_list.phtml --- .../templates/product/widget/new/column/new_default_list.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml index b658851e6a4db..45a206f3f92bf 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/widget/new/column/new_default_list.phtml @@ -33,7 +33,7 @@ <div class="product-item-actions"> <div class="actions-primary"> <?php if ($_product->isSaleable()): ?> - <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?> + <?php if (!$_product->getTypeInstance()->isPossibleBuyFromList($_product)): ?> <button type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>" class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_product) ?>"}}'> From 329c5900fe75878f38f37945b41f5c4e76974dc5 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 23 Nov 2018 09:34:01 +0200 Subject: [PATCH 1343/1415] MAGETWO-96308: Configurable "As low As" Product Price Not Updating Correctly --- .../Catalog/view/base/web/js/price-box.js | 6 +- .../view/frontend/web/js/configurable.js | 65 ++++++++++++++++++- .../view/frontend/web/js/swatch-renderer.js | 45 ++++++++++++- 3 files changed, 112 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index 783d39cddbc76..a179fe2202865 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -78,7 +78,11 @@ define([ pricesCode = [], priceValue, origin, finalPrice; - this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; + if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty("prices")) { + this.cache.additionalPriceObject = {}; + } else { + this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; + } if (newPrices) { $.extend(this.cache.additionalPriceObject, newPrices); diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 6b6c1762fadd9..ed735df1b297b 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -477,7 +477,9 @@ define([ _getPrices: function () { var prices = {}, elements = _.toArray(this.options.settings), - hasProductPrice = false; + hasProductPrice = false, + optionPriceDiff = 0, + allowedProduct, optionPrices, basePrice, optionFinalPrice; _.each(elements, function (element) { var selected = element.options[element.selectedIndex], @@ -485,8 +487,22 @@ define([ priceValue = {}; if (config && config.allowedProducts.length === 1 && !hasProductPrice) { + prices = {}; priceValue = this._calculatePrice(config); hasProductPrice = true; + } else if (element.value) { + allowedProduct = this._getAllowedProductWithMinPrice(config.allowedProducts); + optionPrices = this.options.spConfig.optionPrices; + basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount); + + if (!_.isEmpty(allowedProduct)) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + } + if (optionPriceDiff !== 0) { + prices = {}; + priceValue = this._calculatePriceDifference(allowedProduct); + } } prices[element.attributeId] = priceValue; @@ -495,6 +511,53 @@ define([ return prices; }, + /** + * Get product with minimum price from selected options. + * + * @param {Array} allowedProducts + * @returns {String} + * @private + */ + _getAllowedProductWithMinPrice: function (allowedProducts) { + var optionPrices = this.options.spConfig.optionPrices, + product = {}, + optionMinPrice, optionFinalPrice; + + _.each(allowedProducts, function (allowedProduct) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + + if (_.isEmpty(product)) { + optionMinPrice = optionFinalPrice; + product = allowedProduct; + } + if (optionFinalPrice < optionMinPrice) { + product = allowedProduct; + } + }, this); + + return product; + }, + + /** + * Calculate price difference for allowed product + * + * @param {*} allowedProduct - Product + * @returns {*} + * @private + */ + _calculatePriceDifference: function (allowedProduct) { + var displayPrices = $(this.options.priceHolderSelector).priceBox('option').prices, + newPrices = this.options.spConfig.optionPrices[allowedProduct]; + + _.each(displayPrices, function (price, code) { + if (newPrices[code]) { + displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount; + } + }); + + return displayPrices; + }, + /** * Returns prices for configured products * diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 63dbd31751e85..5f5bdcb6aa289 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -968,10 +968,24 @@ define([ * @private */ _getPrices: function (newPrices, displayPrices) { - var $widget = this; + var $widget = this, + optionPriceDiff = 0, + allowedProduct, optionPrices, basePrice, optionFinalPrice; if (_.isEmpty(newPrices)) { - newPrices = $widget.options.jsonConfig.prices; + allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()); + optionPrices = this.options.jsonConfig.optionPrices; + basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount); + + if (!_.isEmpty(allowedProduct)) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + } + if (optionPriceDiff !== 0) { + newPrices = this.options.jsonConfig.optionPrices[allowedProduct]; + } else { + newPrices = $widget.options.jsonConfig.prices; + } } _.each(displayPrices, function (price, code) { @@ -983,6 +997,33 @@ define([ return displayPrices; }, + /** + * Get product with minimum price from selected options. + * + * @param {Array} allowedProducts + * @returns {String} + * @private + */ + _getAllowedProductWithMinPrice: function (allowedProducts) { + var optionPrices = this.options.jsonConfig.optionPrices, + product = {}, + optionFinalPrice, optionMinPrice; + + _.each(allowedProducts, function (allowedProduct) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + + if (_.isEmpty(product)) { + optionMinPrice = optionFinalPrice; + product = allowedProduct; + } + if (optionFinalPrice < optionMinPrice) { + product = allowedProduct; + } + }, this); + + return product; + }, + /** * Gets all product media and change current to the needed one * From dc900b96054a4a318ee708e4d868bc0ac7e1aefd Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 23 Nov 2018 12:00:23 +0200 Subject: [PATCH 1344/1415] MAGETWO-96308: Configurable "As low As" Product Price Not Updating Correctly --- app/code/Magento/Catalog/view/base/web/js/price-box.js | 2 +- .../Magento/Swatches/view/frontend/web/js/swatch-renderer.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index a179fe2202865..de68d769885fd 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -78,7 +78,7 @@ define([ pricesCode = [], priceValue, origin, finalPrice; - if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty("prices")) { + if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty('prices')) { this.cache.additionalPriceObject = {}; } else { this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 5f5bdcb6aa289..19eb532d5649b 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -976,7 +976,6 @@ define([ allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()); optionPrices = this.options.jsonConfig.optionPrices; basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount); - if (!_.isEmpty(allowedProduct)) { optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); optionPriceDiff = optionFinalPrice - basePrice; From c7ac6a063cb0cdca45bab973fe99609bd60f350b Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Fri, 23 Nov 2018 13:08:45 +0200 Subject: [PATCH 1345/1415] Code style fixes --- lib/internal/Magento/Framework/App/ResourceConnection.php | 1 + lib/internal/Magento/Framework/File/Mime.php | 1 + lib/internal/Magento/Framework/Logger/Handler/Base.php | 3 ++- lib/internal/Magento/Framework/Model/AbstractModel.php | 5 +++++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/ResourceConnection.php b/lib/internal/Magento/Framework/App/ResourceConnection.php index 3dbe5f2db54c6..b543cc970f640 100644 --- a/lib/internal/Magento/Framework/App/ResourceConnection.php +++ b/lib/internal/Magento/Framework/App/ResourceConnection.php @@ -11,6 +11,7 @@ /** * Application provides ability to configure multiple connections to persistent storage. + * * This class provides access to all these connections. * * @api diff --git a/lib/internal/Magento/Framework/File/Mime.php b/lib/internal/Magento/Framework/File/Mime.php index 9d768915868e2..ed370b1beae54 100644 --- a/lib/internal/Magento/Framework/File/Mime.php +++ b/lib/internal/Magento/Framework/File/Mime.php @@ -109,6 +109,7 @@ public function getMimeType($file) /** * Get mime type by the native mime_content_type function. + * * Search for extended mime type if mime_content_type() returned 'application/octet-stream' or 'text/plain' * * @param string $file diff --git a/lib/internal/Magento/Framework/Logger/Handler/Base.php b/lib/internal/Magento/Framework/Logger/Handler/Base.php index 5ae38101a7e0f..4c136fd65a553 100644 --- a/lib/internal/Magento/Framework/Logger/Handler/Base.php +++ b/lib/internal/Magento/Framework/Logger/Handler/Base.php @@ -55,8 +55,9 @@ public function __construct( } /** - * @param string $fileName + * Remove dots from file name * + * @param string $fileName * @return string * @throws \InvalidArgumentException */ diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index 78275a8134633..1c3e67281c192 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -628,6 +628,8 @@ public function isSaveAllowed() } /** + * Set flag property _hasDataChanges + * * @param bool $flag * @return void */ @@ -723,6 +725,7 @@ public function validateBeforeSave() /** * Returns validator, which contains all rules to validate this model. + * * Returns FALSE, if no validation rules exist. * * @return \Zend_Validate_Interface|false @@ -737,6 +740,7 @@ protected function _getValidatorBeforeSave() /** * Creates validator for the model with all validation rules in it. + * * Returns FALSE, if no validation rules exist. * * @return \Zend_Validate_Interface|bool @@ -774,6 +778,7 @@ protected function _getValidationRulesBeforeSave() /** * Get list of cache tags applied to model object. + * * Return false if cache tags are not supported by model * * @return array|false From 1a1081095721c7332ae2b7e65800c7139109038f Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 23 Nov 2018 14:17:15 +0200 Subject: [PATCH 1346/1415] MAGETWO-96308: Configurable "As low As" Product Price Not Updating Correctly --- .../ConfigurableProduct/view/frontend/web/js/configurable.js | 3 +++ .../Magento/Swatches/view/frontend/web/js/swatch-renderer.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index ed735df1b297b..78974877dd90d 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -499,6 +499,7 @@ define([ optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); optionPriceDiff = optionFinalPrice - basePrice; } + if (optionPriceDiff !== 0) { prices = {}; priceValue = this._calculatePriceDifference(allowedProduct); @@ -530,6 +531,7 @@ define([ optionMinPrice = optionFinalPrice; product = allowedProduct; } + if (optionFinalPrice < optionMinPrice) { product = allowedProduct; } @@ -550,6 +552,7 @@ define([ newPrices = this.options.spConfig.optionPrices[allowedProduct]; _.each(displayPrices, function (price, code) { + if (newPrices[code]) { displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount; } diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 19eb532d5649b..d942fd7766a20 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -976,10 +976,12 @@ define([ allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()); optionPrices = this.options.jsonConfig.optionPrices; basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount); + if (!_.isEmpty(allowedProduct)) { optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); optionPriceDiff = optionFinalPrice - basePrice; } + if (optionPriceDiff !== 0) { newPrices = this.options.jsonConfig.optionPrices[allowedProduct]; } else { @@ -988,6 +990,7 @@ define([ } _.each(displayPrices, function (price, code) { + if (newPrices[code]) { displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount; } @@ -1015,6 +1018,7 @@ define([ optionMinPrice = optionFinalPrice; product = allowedProduct; } + if (optionFinalPrice < optionMinPrice) { product = allowedProduct; } From 89bd63aa8dfd18b43d4744b4c8778e1c805bb4c0 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Fri, 23 Nov 2018 17:48:08 +0200 Subject: [PATCH 1347/1415] MAGETWO-96024: PR stabilization --- ...dPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index a8b2df1fcfa67..f283a040ced41 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -59,6 +59,7 @@ <!--Step5. Open *Advanced Inventory* pop-up. Set *Enable Qty Increments* to *Yes*. Fill *.5* in *Qty Increments*--> <click selector="{{AdminProductFormSection.advancedInventoryLink}}" stepKey="clickOnAdvancedInventoryLink2"/> + <waitForPageLoad stepKey="waitForPageLoad"/> <scrollTo selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="scrollToEnableQtyIncrements"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsUseConfigSettings}}" stepKey="clickOnEnableQtyIncrementsUseConfigSettingsCheckbox"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="clickOnEnableQtyIncrements"/> From e12ebf1ddcb0c568986d1dff881ce50e13995068 Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rain2o@gmail.com> Date: Fri, 23 Nov 2018 17:45:49 +0100 Subject: [PATCH 1348/1415] Added integration tests for multiselect source model indexing --- .../Product/Indexer/Eav/SourceTest.php | 47 ++++++++++++++++ .../Catalog/_files/MultiselectSourceMock.php | 25 +++++++++ ...ultiselect_attribute_with_source_model.php | 46 +++++++++++++++ ...t_attribute_with_source_model_rollback.php | 18 ++++++ ...ultiselect_attribute_with_source_model.php | 56 +++++++++++++++++++ ...t_attribute_with_source_model_rollback.php | 32 +++++++++++ 6 files changed, 224 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/MultiselectSourceMock.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php index 4280e9dc8915c..5cf6d00fe77ea 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\_files\MultiselectSourceMock; /** * Class SourceTest @@ -157,4 +158,50 @@ public function testReindexMultiselectAttribute() $result = $connection->fetchAll($select); $this->assertCount(3, $result); } + + /** + * @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php + * @magentoDbIsolation disabled + */ + public function testReindexMultiselectAttributeWithSourceModel() + { + $objectManager = Bootstrap::getObjectManager(); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->create(ProductRepositoryInterface::class); + + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attr **/ + $attr = $objectManager->get(\Magento\Eav\Model\Config::class) + ->getAttribute('catalog_product', 'multiselect_attr_with_source'); + + /** @var $sourceModel MultiselectSourceMock */ + $sourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + MultiselectSourceMock::class + ); + $options = $sourceModel->getAllOptions(); + $product1Id = $options[0]['value'] * 10; + $product2Id = $options[1]['value'] * 10; + + /** @var \Magento\Catalog\Model\Product $product1 **/ + $product1 = $productRepository->getById($product1Id); + $product1->setSpecialFromDate(date('Y-m-d H:i:s')); + $product1->setNewsFromDate(date('Y-m-d H:i:s')); + $productRepository->save($product1); + + /** @var \Magento\Catalog\Model\Product $product2 **/ + $product2 = $productRepository->getById($product2Id); + $product1->setSpecialFromDate(date('Y-m-d H:i:s')); + $product1->setNewsFromDate(date('Y-m-d H:i:s')); + $productRepository->save($product2); + + $this->_eavIndexerProcessor->reindexAll(); + $connection = $this->productResource->getConnection(); + $select = $connection->select() + ->from($this->productResource->getTable('catalog_product_index_eav')) + ->where('entity_id in (?)', [$product1Id, $product2Id]) + ->where('attribute_id = ?', $attr->getId()); + + $result = $connection->fetchAll($select); + $this->assertCount(3, $result); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/MultiselectSourceMock.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/MultiselectSourceMock.php new file mode 100644 index 0000000000000..b9325622d8900 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/MultiselectSourceMock.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\_files; + +use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; + +/** + * Creates mock source for multiselect attributes + */ +class MultiselectSourceMock extends AbstractSource +{ + + public function getAllOptions() + { + return [ + ['value' => 1, 'label' => 'Option 1'], + ['value' => 2, 'label' => 'Option 2'], + ['value' => 3, 'label' => 'Option 3'], + ['value' => 4, 'label' => 'Option 4 "!@#$%^&*'], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model.php new file mode 100644 index 0000000000000..6dcba90bf44fa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* Create attribute */ +/** @var $installer \Magento\Catalog\Setup\CategorySetup */ +$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Setup\CategorySetup::class +); +/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class +); +$entityType = $installer->getEntityTypeId('catalog_product'); +if (!$attribute->loadByCode($entityType, 'multiselect_attr_with_source')->getAttributeId()) { + $attribute->setData( + [ + 'attribute_code' => 'multiselect_attr_with_source', + 'entity_type_id' => $entityType, + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'multiselect', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 1, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => ['Multiselect Attribute with Source Model'], + 'backend_type' => 'varchar', + 'backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class, + 'source_model' => \Magento\Catalog\_files\MultiselectSourceMock::class + ] + ); + $attribute->save(); + + /* Assign attribute to attribute set */ + $installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model_rollback.php new file mode 100644 index 0000000000000..9859e1ab4c78e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute_with_source_model_rollback.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* Delete attribute with multiselect_attribute code */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); +/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Catalog\Model\ResourceModel\Eav\Attribute' +); +$attribute->load('multiselect_attr_with_source', 'attribute_code'); +$attribute->delete(); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php new file mode 100644 index 0000000000000..a1e81fd3b40ad --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\_files\MultiselectSourceMock; + +/** + * Create multiselect attribute + */ +require __DIR__ . '/multiselect_attribute_with_source_model.php'; +require __DIR__ . '/../../Checkout/_files/ValidatorFileMock.php'; + +/** Create product with options and multiselect attribute */ + +/** @var $installer \Magento\Catalog\Setup\CategorySetup */ +$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Setup\CategorySetup::class +); + +/** @var $sourceModel MultiselectSourceMock */ +$sourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + MultiselectSourceMock::class +); +$options = $sourceModel->getAllOptions(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId($options[0]['value'] * 10) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setWebsiteIds([1]) + ->setName('With Multiselect Source Model 1') + ->setSku('simple_mssm_1') + ->setPrice(10) + ->setDescription('Hello " &" Bring the water bottle when you can!') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setMultiselectAttrWithSource([$options[0]['value']]) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId($options[1]['value'] * 10) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setWebsiteIds([1]) + ->setName('With Multiselect Source Model 2') + ->setSku('simple_mssm_2') + ->setPrice(10) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setMultiselectAttrWithSource([$options[1]['value'], $options[2]['value'], $options[3]['value']]) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model_rollback.php new file mode 100644 index 0000000000000..a8121a7913e54 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model_rollback.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require __DIR__ . '/multiselect_attribute_with_source_model_rollback.php'; + +use Magento\Framework\Indexer\IndexerRegistry; + +/** + * Remove all products as strategy of isolation process + */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $productCollection \Magento\Catalog\Model\ResourceModel\Product */ +$productCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create('Magento\Catalog\Model\Product') + ->getCollection(); + +foreach ($productCollection as $product) { + $product->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(IndexerRegistry::class) + ->get(Magento\CatalogInventory\Model\Indexer\Stock\Processor::INDEXER_ID) + ->reindexAll(); From 8daff66d9c4f750bd31ee7d0cc7570699ad9aeab Mon Sep 17 00:00:00 2001 From: Joel Rainwater <joel.rain2o@gmail.com> Date: Fri, 23 Nov 2018 17:46:49 +0100 Subject: [PATCH 1349/1415] moved new parameters to end of list and made them optional --- .../Product/Indexer/Eav/Source.php | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index b7489bff18a1f..7730d7cc9a7fd 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -43,9 +43,9 @@ class Source extends AbstractEav * @param \Magento\Eav\Model\Config $eavConfig * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper - * @param \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository - * @param \Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder * @param null|string $connectionName + * @param \Magento\Eav\Api\AttributeRepositoryInterface|null $attributeRepository + * @param \Magento\Framework\Api\SearchCriteriaBuilder|null $criteriaBuilder */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, @@ -53,9 +53,9 @@ public function __construct( \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, - \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository, - \Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder, - $connectionName = null + $connectionName = null, + \Magento\Eav\Api\AttributeRepositoryInterface $attributeRepository = null, + \Magento\Framework\Api\SearchCriteriaBuilder $criteriaBuilder = null ) { parent::__construct( $context, @@ -65,8 +65,12 @@ public function __construct( $connectionName ); $this->_resourceHelper = $resourceHelper; - $this->attributeRepository = $attributeRepository; - $this->criteriaBuilder = $criteriaBuilder; + $this->attributeRepository = $attributeRepository + ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Eav\Api\AttributeRepositoryInterface::class); + $this->criteriaBuilder = $criteriaBuilder + ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Api\SearchCriteriaBuilder::class); } /** @@ -251,8 +255,9 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu $options[$row['attribute_id']][$row['option_id']] = true; } - // Include custom source model options - $options = $this->getMultiSelectAttributeWithSourceModels($attrIds, $options); + // Retrieve any custom source model options + $sourceModelOptions = $this->getMultiSelectAttributeWithSourceModels($attrIds); + $options = array_replace_recursive($options, $sourceModelOptions); // prepare get multiselect values query $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value'); @@ -323,11 +328,10 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu * https://github.com/magento/magento2/issues/417#issuecomment-265146285 * * @param array $attrIds - * @param array $options * * @return array */ - private function getMultiSelectAttributeWithSourceModels($attrIds, $options) + private function getMultiSelectAttributeWithSourceModels($attrIds) { // Add options from custom source models $this->criteriaBuilder @@ -339,11 +343,12 @@ private function getMultiSelectAttributeWithSourceModels($attrIds, $options) $criteria )->getItems(); + $options = []; foreach ($attributes as $attribute) { $sourceModelOptions = $attribute->getOptions(); // Add options to list used below - foreach ($sourceModelOptions as $o) { - $options[$attribute->getAttributeId()][$o->getValue()] = true; + foreach ($sourceModelOptions as $option) { + $options[$attribute->getAttributeId()][$option->getValue()] = true; } } From 4bf3aa79f5bfd68142fb304bad3ff3d0f2551c06 Mon Sep 17 00:00:00 2001 From: Tiago Sampaio <tiago@tiagosampaio.com> Date: Fri, 23 Nov 2018 15:45:12 -0200 Subject: [PATCH 1350/1415] Fixing a test for Magento Newsletter. --- app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php index 889fc11d71d7e..1de3e6096cd96 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php @@ -68,6 +68,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->subscriberFactoryMock = $this->getMockBuilder(SubscriberFactory::class) + ->disableOriginalConstructor() ->getMock(); $this->subscriberMock = $this->getMockBuilder(Subscriber::class) ->disableOriginalConstructor() From 7ef0c2c827588867d76ae3b981d9ae578303b105 Mon Sep 17 00:00:00 2001 From: Kajal Solanki <kajal.solanki@krishtechnolabs.com> Date: Mon, 26 Nov 2018 14:15:30 +0530 Subject: [PATCH 1351/1415] fix-issue-19399 into 2.3-develop branch --- .../source/module/main/_collapsible-blocks.less | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_collapsible-blocks.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_collapsible-blocks.less index 6420738c6fb9b..a3124affffc10 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_collapsible-blocks.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/_collapsible-blocks.less @@ -127,6 +127,21 @@ } } } + + td.admin__collapsible-block-wrapper { + .admin__collapsible-title { + &:before { + content: @icon-expand-open__content; + } + } + &._show { + .admin__collapsible-title { + &:before { + content: @icon-expand-close__content; + } + } + } + } } &.fieldset-wrapper { From bb946c446d64ceb447e5bdf3dd2b9611bb05a7ec Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 26 Nov 2018 11:34:39 +0000 Subject: [PATCH 1352/1415] magento-engcom/import-export-improvements#135: update storage class from phpcs tests --- .../Model/ResourceModel/Import/Customer/Storage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php index 1046afeebbf9b..43623019c005e 100644 --- a/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php +++ b/app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php @@ -13,6 +13,9 @@ use Magento\ImportExport\Model\ResourceModel\CollectionByPagesIteratorFactory; use Magento\ImportExport\Model\ResourceModel\CollectionByPagesIterator; +/** + * Storage to check existing customers. + */ class Storage { /** @@ -117,6 +120,8 @@ private function loadCustomersData(array $customerIdentifiers) } /** + * Add a customer by an array + * * @param array $customer * @return $this */ From 35a2f06d936f5724d03ca49098b6b2ad9f57ff2d Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Mon, 26 Nov 2018 08:54:57 -0600 Subject: [PATCH 1353/1415] MQE-1187: Fix MFTF skipped tests - LoadingMask addition for test stability. --- .../Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index cc8a62ca48961..9e5f15802a188 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -298,6 +298,7 @@ <waitForPageLoad stepKey="waitForStoresPageOpened"/> <click stepKey="chooseStore" selector="{{AdminOrderStoreScopeTreeSection.storeForOrder(storeView.name)}}"/> <scrollToTopOfPage stepKey="scrollToTop"/> + <waitForPageLoad stepKey="waitForStoreToAppear"/> <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickOnAddProducts"/> <waitForPageLoad stepKey="waitForProductsListForOrder"/> <click selector="{{AdminOrdersGridSection.productForOrder(product.sku)}}" stepKey="chooseTheProduct"/> From 56be425e5f9f3f963042b48a7347f69130b50497 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Mon, 26 Nov 2018 10:24:12 -0600 Subject: [PATCH 1354/1415] MC-5319: Create tax rate, zip code range. Addressing code review comments. --- .../Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml | 2 -- .../Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml index 61999f3e2ea33..057223f4fc546 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRateGridSection.xml @@ -16,7 +16,5 @@ <element name="filterByCountry" type="input" selector="#tax_rate_grid_filter_tax_country_id"/> <element name="filterByPostCode" type="input" selector="#tax_rate_grid_filter_tax_postcode"/> <element name="nthRow" type="block" selector="tr[data-role='row']:nth-of-type({{var}})" parameterized="true" timeout="30"/> - <element name="country" type="select" selector="#tax_rate_grid_filter_tax_country_id"/> - <element name="zipCode" type="text" selector="#tax_rate_grid_filter_tax_postcode"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml index c4abd856354c0..7114e821c3269 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml @@ -50,8 +50,8 @@ <!-- Create a tax rate for zipCodeRange and verify we see expected values on the tax rate grid page --> <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> - <selectOption selector="{{AdminTaxRateGridSection.country}}" userInput="United States" stepKey="selectCountry2" /> - <fillField selector="{{AdminTaxRateGridSection.zipCode}}" userInput="90001-96162" stepKey="seeTaxPostCode1"/> + <selectOption selector="{{AdminTaxRateGridSection.filterByCountry}}" userInput="United States" stepKey="selectCountry2" /> + <fillField selector="{{AdminTaxRateGridSection.filterByPostCode}}" userInput="90001-96162" stepKey="seeTaxPostCode1"/> <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow3"/> <!-- Verify we see expected values on the tax rate form page --> From aa4fb0b8f409bde44777136e2b4e3749ca01eb11 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Mon, 26 Nov 2018 13:58:48 -0600 Subject: [PATCH 1355/1415] MC-5320: Create tax rate, specific postcode --- .../AdminCreateTaxRateSpecificPostcode.xml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml new file mode 100644 index 0000000000000..cb6f852a76493 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateTaxRateSpecificPostcode"> + <annotations> + <stories value="Create tax rate"/> + <title value="Create tax rate,specific postcode"/> + <description value="Test log in to Create Tax Rate and Create specific Postcode"/> + <testCaseId value="MC-5320"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> + <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> + </after> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <!-- Create a tax rate with specific postcode --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField1"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="180" stepKey="fillTaxPostCode"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="Canada" stepKey="selectCountry" /> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="*" stepKey="selectState" /> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput='25' stepKey="seeRate"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <!-- Verify the tax rate grid page shows the specific postcode we just created --> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateGridSection.filterByCountry}}" userInput="Canada" stepKey="fillCountryFilter"/> + <fillField selector="{{AdminTaxRateGridSection.filterByPostCode}}" userInput="180" stepKey="fillPostCodeFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + <!-- Verify we see expected values on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxIdentifierField2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="180" stepKey="seePostCode"/> + <seeInField selector="{{AdminTaxRateFormSection.country}}" userInput="Canada" stepKey="seeCountry2"/> + + <!-- Verify we see expected values on the tax rule form page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex4"/> + <click selector="{{AdminTaxRuleGridSection.add}}" stepKey="clickAdd"/> + <see selector="{{AdminTaxRulesSection.taxRateMultiSelectItems}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxRateOnNewTaxRulePage"/> + </test> +</tests> From df77a398683ca1f37af85d7241db1d3532c30844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Mon, 26 Nov 2018 23:09:49 +0200 Subject: [PATCH 1356/1415] remove lib-url-check(); function was removed as this function does not exist anymore --- lib/web/css/docs/source/_utilities.less | 63 ------------------------- 1 file changed, 63 deletions(-) diff --git a/lib/web/css/docs/source/_utilities.less b/lib/web/css/docs/source/_utilities.less index 312eeffe488ca..1ce15a9a50e2d 100644 --- a/lib/web/css/docs/source/_utilities.less +++ b/lib/web/css/docs/source/_utilities.less @@ -367,66 +367,3 @@ // </tr> // </table> // </pre> - -// # .lib-url-check() -// -// The <code>.lib-url-check()</code> mixin wraps passed value with 'url( ... )' and returns <code>@lib-url-check-output</code> variable. Can be used with <code>.lib-css()</code> mixin. -// - -.example-url-check { - // Set image path variable - @_icon-image: '/images/test.png'; - - // "Call" the mixin - .lib-url-check(@_icon-image); - - // Will return url('/images/test.png') - .lib-css(background, #eee @lib-url-check-output no-repeat 0 0); -} - -// -// If the variable is set to <code>false</code>, the <code>.lib-url-check()</code> will return false. -// -// ``` -// <div class="example-url-check"> -// Block with background. -// </div> -// ``` -// - -.example-url-check-false { - // Set usage image path to false - @_icon-image: false; - - // "Call" the mixin - .lib-url-check(@_icon-image); - - // Will return 'false' and outputs nothing - .lib-css(background, #eee @lib-url-check-output no-repeat 0 0); -} - -// ``` -// <div class="example-url-check-false"> -// Block with no background. -// </div> -// ``` -// - -// # .lib-url-check() variables -// -// <pre> -// <table> -// <tr> -// <th class="vars_head">Mixin variable</th> -// <th class="vars_head">Allowed values</th> -// <th class="vars_head">Output variable</th> -// <th class="vars_head">Comment</th> -// </tr> -// <tr> -// <th>@_path</th> -// <td class="vars_value">'' | false | value</td> -// <td class="vars_value">@lib-url-check-output</td> -// <td>Passed url to wrap in 'url( ... )'. If the 'false' value passed mixin will return 'false'</td> -// </tr> -// </table> -// </pre> From ca55821d94f9f4b34acc1878f0b9d7cc9a768c27 Mon Sep 17 00:00:00 2001 From: dharmesh vaja <dharmesh.vaja@rocketbazaar.com> Date: Tue, 27 Nov 2018 12:28:49 +0530 Subject: [PATCH 1357/1415] 19404-Fixed-News-latter-issue --- .../Magento/Newsletter/Controller/Subscriber/NewAction.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php index fd2a61702e909..1a3a2445ce962 100644 --- a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php +++ b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php @@ -151,10 +151,7 @@ public function execute() $status = (int) $this->_subscriberFactory->create()->subscribe($email); $this->messageManager->addSuccessMessage($this->getSuccessMessage($status)); } catch (LocalizedException $e) { - $this->messageManager->addExceptionMessage( - $e, - __('There was a problem with the subscription: %1', $e->getMessage()) - ); + $this->messageManager->addErrorMessage(__('This email address is already subscribed.')); } catch (\Exception $e) { $this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.')); } From 46b34797d20072e34e0cc87adcbc2cc36d49f281 Mon Sep 17 00:00:00 2001 From: dharmesh vaja <dharmesh.vaja@rocketbazaar.com> Date: Tue, 27 Nov 2018 15:09:31 +0530 Subject: [PATCH 1358/1415] 19404-Fixed-News-latter-issue --- app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php index 1a3a2445ce962..0ed0944579660 100644 --- a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php +++ b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php @@ -151,7 +151,7 @@ public function execute() $status = (int) $this->_subscriberFactory->create()->subscribe($email); $this->messageManager->addSuccessMessage($this->getSuccessMessage($status)); } catch (LocalizedException $e) { - $this->messageManager->addErrorMessage(__('This email address is already subscribed.')); + $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.')); } From 26252db6444c23929cf56e8e3857b81cab9f5b39 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Tue, 27 Nov 2018 12:32:51 +0200 Subject: [PATCH 1359/1415] Skipped randomly failing functional tests --- ...tomerGroupMembershipArePersistedUnderLongTermCookieTest.xml | 3 +++ ...SortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml index 2e09ee7134733..8d766f4daab99 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69455"/> <group value="persistent"/> + <skip> + <issueId value="MAGETWO-96656"/> + </skip> </annotations> <before> <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml index c93b216fc89d5..f44ba8a041cbb 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69988"/> <group value="сonfigurable_product"/> + <skip> + <issueId value="MAGETWO-96658"/> + </skip> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategory"/> From 5937d865c4d6f358ac6ff66cc6217275f293e416 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Tue, 27 Nov 2018 13:26:21 +0200 Subject: [PATCH 1360/1415] magento/magento2:#19418 Cannot add additional field to Newsletter system configuration at desired position - Adjusted Newsletter system configuration fields sortOrder so they has a step of 10 --- .../Newsletter/etc/adminhtml/system.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Newsletter/etc/adminhtml/system.xml b/app/code/Magento/Newsletter/etc/adminhtml/system.xml index 1173f64310304..277005240eabc 100644 --- a/app/code/Magento/Newsletter/etc/adminhtml/system.xml +++ b/app/code/Magento/Newsletter/etc/adminhtml/system.xml @@ -11,39 +11,39 @@ <label>Newsletter</label> <tab>customer</tab> <resource>Magento_Newsletter::newsletter</resource> - <group id="subscription" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1"> + <group id="subscription" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Subscription Options</label> - <field id="allow_guest_subscribe" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="allow_guest_subscribe" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Allow Guest Subscription</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> - <field id="confirm" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="confirm" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Need to Confirm</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> - <field id="confirm_email_identity" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="confirm_email_identity" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Confirmation Email Sender</label> <source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model> </field> - <field id="confirm_email_template" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="confirm_email_template" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Confirmation Email Template</label> <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment> <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model> </field> - <field id="success_email_identity" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="success_email_identity" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Success Email Sender</label> <source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model> </field> - <field id="success_email_template" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="success_email_template" translate="label comment" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Success Email Template</label> <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment> <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model> </field> - <field id="un_email_identity" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="un_email_identity" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Unsubscription Email Sender</label> <source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model> </field> - <field id="un_email_template" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> + <field id="un_email_template" translate="label comment" type="select" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Unsubscription Email Template</label> <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment> <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model> From 4fa45ee22579149d4688319cf2dcde0c8d651e8f Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Tue, 27 Nov 2018 08:44:00 -0600 Subject: [PATCH 1361/1415] MC-5321: Create tax rate, wider zip code range --- .../AdminCreateTaxRateWiderZipCodeRange.xml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml new file mode 100644 index 0000000000000..ba65ea43a6a87 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateTaxRateWiderZipCodeRange"> + <annotations> + <stories value="Create tax rate, wider zip code range"/> + <title value="Create Tax Rate"/> + <description value="Test log in to Create Tax Rate and Create Wider Zip Code Range"/> + <testCaseId value="MC-5321"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> + <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> + </after> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <!-- Create a tax rate with range from 1-7800935 for zipCodes --> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> + <checkOption selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="checkZipRange" /> + <fillField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="1" stepKey="fillZipFrom"/> + <fillField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="7800935" stepKey="fillZipTo"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="United Kingdom" stepKey="selectCountry1"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="7.75" stepKey="seeRate"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex3"/> + <!-- Create a tax rate for zipCodeRange and verify we see expected values on the tax rate grid page --> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateGridSection.filterByCountry}}" userInput="United Kingdom" stepKey="selectCountry2" /> + <fillField selector="{{AdminTaxRateGridSection.filterByPostCode}}" userInput="1-7800935" stepKey="seeTaxPostCode1"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + <!-- Verify we see expected values on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxIdentifierField2"/> + <seeCheckboxIsChecked selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="clickZipRange"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="1" stepKey="seeTaxPostCode2"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="7800935" stepKey="seeTaxPostCode3"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="United Kingdom" stepKey="seeCountry2"/> + + <!-- Verify we see expected values on the tax rule form page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex4"/> + <click selector="{{AdminTaxRuleGridSection.add}}" stepKey="clickAdd"/> + <see selector="{{AdminTaxRulesSection.taxRateMultiSelectItems}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxRateOnNewTaxRulePage"/> + </test> +</tests> From d42b74d2b8175283733626bf41c2c139cb223f4c Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Tue, 27 Nov 2018 17:07:44 +0200 Subject: [PATCH 1362/1415] MAGETWO-95838: Custom product attribute does not update when using Catalog Product Flat tables --- .../Indexer/Product/Flat/Action/Eraser.php | 5 +- .../Indexer/Product/Flat/Action/Indexer.php | 35 +++---- .../Model/Indexer/Product/Flat/Action/Row.php | 12 ++- .../Product/Flat/Action/EraserTest.php | 9 +- .../Indexer/Product/Flat/Action/RowTest.php | 8 +- .../Flat/Action/CustomFlatAttributeTest.php | 91 +++++++++++++++++ .../Indexer/Product/Flat/Action/RowTest.php | 97 ++++++++++++------- ...t_simple_with_custom_attribute_in_flat.php | 79 +++++++++++++++ ...with_custom_attribute_in_flat_rollback.php | 41 ++++++++ 9 files changed, 310 insertions(+), 67 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/CustomFlatAttributeTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat_rollback.php diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Eraser.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Eraser.php index 6762602aecaf1..ad734b96d59d7 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Eraser.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Eraser.php @@ -118,9 +118,10 @@ public function removeDisabledProducts(array &$ids, $storeId) private function getSelectForProducts(array $ids) { $productTable = $this->productIndexerHelper->getTable('catalog_product_entity'); - $select = $this->connection->select()->from($productTable) + $select = $this->connection->select() + ->from(['product_table' => $productTable]) ->columns('entity_id') - ->where('entity_id IN(?)', $ids); + ->where('product_table.entity_id IN(?)', $ids); return $select; } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Indexer.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Indexer.php index 466ba746fa108..a669fb73f64fc 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Indexer.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Indexer.php @@ -9,6 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\EntityManager\MetadataPool; +use Magento\Store\Model\Store; /** * Class Indexer @@ -84,7 +85,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '') [ 'entity_id' => 'e.entity_id', 'attribute_id' => 't.attribute_id', - 'value' => $this->_connection->getIfNullSql('`t2`.`value`', '`t`.`value`'), + 'value' => 't.value' ] ); @@ -99,32 +100,30 @@ public function write($storeId, $productId, $valueFieldSuffix = '') sprintf('e.%s = t.%s ', $linkField, $linkField) . $this->_connection->quoteInto( ' AND t.attribute_id IN (?)', array_keys($ids) - ) . ' AND t.store_id = 0', - [] - )->joinLeft( - ['t2' => $tableName], - sprintf('t.%s = t2.%s ', $linkField, $linkField) . - ' AND t.attribute_id = t2.attribute_id ' . - $this->_connection->quoteInto( - ' AND t2.store_id = ?', - $storeId - ), + ) . ' AND ' . $this->_connection->quoteInto('t.store_id IN(?)', [ + Store::DEFAULT_STORE_ID, + $storeId + ]), [] )->where( 'e.entity_id = ' . $productId - ); + )->order('t.store_id ASC'); $cursor = $this->_connection->query($select); while ($row = $cursor->fetch(\Zend_Db::FETCH_ASSOC)) { $updateData[$ids[$row['attribute_id']]] = $row['value']; $valueColumnName = $ids[$row['attribute_id']] . $valueFieldSuffix; if (isset($describe[$valueColumnName])) { - $valueColumns[$row['value']] = $valueColumnName; + $valueColumns[$row['attribute_id']] = [ + 'value' => $row['value'], + 'column_name' => $valueColumnName + ]; } } //Update not simple attributes (eg. dropdown) if (!empty($valueColumns)) { - $valueIds = array_keys($valueColumns); + $valueIds = array_column($valueColumns, 'value'); + $optionIdToAttributeName = array_column($valueColumns, 'column_name', 'value'); $select = $this->_connection->select()->from( ['t' => $this->_productIndexerHelper->getTable('eav_attribute_option_value')], @@ -133,14 +132,14 @@ public function write($storeId, $productId, $valueFieldSuffix = '') $this->_connection->quoteInto('t.option_id IN (?)', $valueIds) )->where( $this->_connection->quoteInto('t.store_id IN(?)', [ - \Magento\Store\Model\Store::DEFAULT_STORE_ID, + Store::DEFAULT_STORE_ID, $storeId ]) ) ->order('t.store_id ASC'); $cursor = $this->_connection->query($select); while ($row = $cursor->fetch(\Zend_Db::FETCH_ASSOC)) { - $valueColumnName = $valueColumns[$row['option_id']]; + $valueColumnName = $optionIdToAttributeName[$row['option_id']]; if (isset($describe[$valueColumnName])) { $updateData[$valueColumnName] = $row['value']; } @@ -150,6 +149,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '') $columnNames = array_keys($columns); $columnNames[] = 'attribute_set_id'; $columnNames[] = 'type_id'; + $columnNames[] = $linkField; $select->from( ['e' => $entityTableName], $columnNames @@ -159,6 +159,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '') $cursor = $this->_connection->query($select); $row = $cursor->fetch(\Zend_Db::FETCH_ASSOC); if (!empty($row)) { + $linkFieldId = $linkField; foreach ($row as $columnName => $value) { $updateData[$columnName] = $value; } @@ -170,7 +171,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '') if (!empty($updateData)) { $updateData += ['entity_id' => $productId]; if ($linkField !== $metadata->getIdentifierField()) { - $updateData += [$linkField => $productId]; + $updateData += [$linkField => $linkFieldId]; } $updateFields = []; foreach ($updateData as $key => $value) { diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php index d9bfc96b7817a..64a7c4be4e03c 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php @@ -96,15 +96,17 @@ public function execute($id = null) /* @var $status \Magento\Eav\Model\Entity\Attribute */ $status = $this->_productIndexerHelper->getAttribute(ProductInterface::STATUS); $statusTable = $status->getBackend()->getTable(); + $catalogProductEntityTable = $this->_productIndexerHelper->getTable('catalog_product_entity'); $statusConditions = [ - 'store_id IN(0,' . (int)$store->getId() . ')', - 'attribute_id = ' . (int)$status->getId(), - $linkField . ' = ' . (int)$id, + 's.store_id IN(0,' . (int)$store->getId() . ')', + 's.attribute_id = ' . (int)$status->getId(), + 'e.entity_id = ' . (int)$id, ]; $select = $this->_connection->select(); - $select->from($statusTable, ['value']) + $select->from(['e' => $catalogProductEntityTable], ['s.value']) ->where(implode(' AND ', $statusConditions)) - ->order('store_id DESC') + ->joinLeft(['s' => $statusTable], "e.{$linkField} = s.{$linkField}", []) + ->order('s.store_id DESC') ->limit(1); $result = $this->_connection->query($select); $status = $result->fetchColumn(0); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/EraserTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/EraserTest.php index c04428eadef0d..e1e2816d44220 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/EraserTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/EraserTest.php @@ -53,9 +53,14 @@ public function testRemoveDeletedProducts() { $productsToDeleteIds = [1, 2]; $select = $this->createMock(\Magento\Framework\DB\Select::class); - $select->expects($this->once())->method('from')->with('catalog_product_entity')->will($this->returnSelf()); + $select->expects($this->once()) + ->method('from') + ->with(['product_table' => 'catalog_product_entity']) + ->will($this->returnSelf()); $select->expects($this->once())->method('columns')->with('entity_id')->will($this->returnSelf()); - $select->expects($this->once())->method('where')->with('entity_id IN(?)', $productsToDeleteIds) + $select->expects($this->once()) + ->method('where') + ->with('product_table.entity_id IN(?)', $productsToDeleteIds) ->will($this->returnSelf()); $products = [['entity_id' => 2]]; $statement = $this->createMock(\Zend_Db_Statement_Interface::class); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php index 85d8dd8a14917..11d07872fef91 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php @@ -100,10 +100,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->connection->expects($this->any())->method('select')->willReturn($selectMock); - $selectMock->expects($this->any())->method('from')->with( - $attributeTable, - ['value'] - )->willReturnSelf(); + $selectMock->method('from') + ->willReturnSelf(); + $selectMock->method('joinLeft') + ->willReturnSelf(); $selectMock->expects($this->any())->method('where')->willReturnSelf(); $selectMock->expects($this->any())->method('order')->willReturnSelf(); $selectMock->expects($this->any())->method('limit')->willReturnSelf(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/CustomFlatAttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/CustomFlatAttributeTest.php new file mode 100644 index 0000000000000..049e7c8d20119 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/CustomFlatAttributeTest.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Indexer\Product\Flat\Action; + +use Magento\TestFramework\Indexer\TestCase as IndexerTestCase; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Indexer\Product\Flat\Processor; +use Magento\Catalog\Model\ResourceModel\Product\Flat; +use Magento\Framework\Api\SearchCriteriaBuilder; + +/** + * Custom Flat Attribute Test + */ +class CustomFlatAttributeTest extends IndexerTestCase +{ + /** + * @var Processor + */ + private $processor; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->processor = $this->objectManager->get(Processor::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + } + + /** + * Tests that custom product attribute will appear in flat table and can be updated in it. + * + * @magentoDbIsolation disabled + * @magentoAppArea frontend + * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php + * + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\StateException + */ + public function testProductUpdateCustomAttribute(): void + { + $product = $this->productRepository->get('simple_with_custom_flat_attribute'); + $product->setCustomAttribute('flat_attribute', 'changed flat attribute'); + $this->productRepository->save($product); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->create(SearchCriteriaBuilder::class); + /** @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria */ + $searchCriteria = $searchCriteriaBuilder->addFilter('sku', 'simple_with_custom_flat_attribute') + ->create(); + + $items = $this->productRepository->getList($searchCriteria) + ->getItems(); + $product = reset($items); + $resourceModel = $product->getResourceCollection() + ->getEntity(); + + self::assertInstanceOf( + Flat::class, + $resourceModel, + 'Product should be received from flat resource' + ); + + self::assertEquals( + 'changed flat attribute', + $product->getFlatAttribute(), + 'Product flat attribute should be able to change.' + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php index 15c90891878a0..a32b476fe75ff 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php @@ -3,87 +3,110 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Indexer\Product\Flat\Action; +use Magento\TestFramework\Indexer\TestCase as IndexerTestCase; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Indexer\Product\Flat\Processor; +use Magento\Catalog\Block\Product\ListProduct; +use Magento\Catalog\Api\CategoryRepositoryInterface; + /** * Class RowTest */ -class RowTest extends \Magento\TestFramework\Indexer\TestCase +class RowTest extends IndexerTestCase { /** - * @var \Magento\Catalog\Model\Product + * @var Processor */ - protected $_product; + private $processor; /** - * @var \Magento\Catalog\Model\Category + * @var \Magento\Framework\ObjectManagerInterface */ - protected $_category; + private $objectManager; /** - * @var \Magento\Catalog\Model\Indexer\Product\Flat\State + * @var ProductRepositoryInterface */ - protected $_state; + private $productRepository; /** - * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor + * @var CategoryRepositoryInterface */ - protected $_processor; + private $categoryRepository; - protected function setUp() + /** + * @inheritdoc + */ + protected function setUp(): void { - $this->_product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Product::class - ); - $this->_category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Category::class - ); - $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Indexer\Product\Flat\Processor::class - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->processor = $this->objectManager->get(Processor::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $this->categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class); } /** + * Tests product update + * * @magentoDbIsolation disabled * @magentoDataFixture Magento/Catalog/_files/row_fixture.php * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 * @magentoAppArea frontend + * + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\StateException */ - public function testProductUpdate() + public function testProductUpdate(): void { - $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->create(\Magento\Catalog\Model\CategoryFactory::class); - $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->create(\Magento\Catalog\Block\Product\ListProduct::class); + /** @var ListProduct $listProduct */ + $listProduct = $this->objectManager->create(ListProduct::class); - $this->_processor->getIndexer()->setScheduled(false); - $this->assertFalse( - $this->_processor->getIndexer()->isScheduled(), + $this->processor->getIndexer() + ->setScheduled(false); + $isScheduled = $this->processor->getIndexer() + ->isScheduled(); + self::assertFalse( + $isScheduled, 'Indexer is in scheduled mode when turned to update on save mode' ); - $this->_product->load(1); - $this->_product->setName('Updated Product'); - $this->_product->save(); + $this->processor->reindexAll(); - $this->_processor->reindexAll(); - - $category = $categoryFactory->create()->load(9); + $product = $this->productRepository->get('simple'); + $product->setName('Updated Product'); + $this->productRepository->save($product); + + /** @var \Magento\Catalog\Api\Data\CategoryInterface $category */ + $category = $this->categoryRepository->get(9); + /** @var \Magento\Catalog\Model\Layer $layer */ $layer = $listProduct->getLayer(); $layer->setCurrentCategory($category); /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */ $productCollection = $layer->getProductCollection(); - $this->assertTrue( + self::assertTrue( $productCollection->isEnabledFlat(), 'Product collection is not using flat resource when flat is on' ); - $this->assertEquals(2, $productCollection->count(), 'Product collection items count must be exactly 2'); + self::assertEquals( + 2, + $productCollection->count(), + 'Product collection items count must be exactly 2' + ); foreach ($productCollection as $product) { /** @var $product \Magento\Catalog\Model\Product */ - if ($product->getId() == 1) { - $this->assertEquals( + if ($product->getSku() === 'simple') { + self::assertEquals( 'Updated Product', $product->getName(), 'Product name from flat does not match with updated name' diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php new file mode 100644 index 0000000000000..2b1b271a8bb3c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\ProductFactory; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Catalog\Model\Indexer\Product\Flat\Processor; +use Magento\Catalog\Setup\CategorySetup; +use Magento\Eav\Model\Entity; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Type; + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var ProductFactory $productFactory */ +$productFactory = $objectManager->get(ProductFactory::class); +/** @var ProductAttributeRepositoryInterface $attributeRepository */ +$attributeRepository = $objectManager->get(ProductAttributeRepositoryInterface::class); + + +/** @var $installer CategorySetup */ +$installer = $objectManager->create(CategorySetup::class); +$entityModel = $objectManager->create(Entity::class); +$attributeSetId = $installer->getAttributeSetId(Product::ENTITY, 'Default'); +$entityTypeId = $entityModel->setType(Product::ENTITY) + ->getTypeId(); +$groupId = $installer->getDefaultAttributeGroupId($entityTypeId, $attributeSetId); + +/** @var ProductAttributeInterface $attribute */ +$attribute = $objectManager->create(ProductAttributeInterface::class); + +$attribute->setAttributeCode('flat_attribute') + ->setEntityTypeId($entityTypeId) + ->setIsVisible(true) + ->setFrontendInput('text') + ->setIsFilterable(1) + ->setIsUserDefined(1) + ->setUsedInProductListing(1) + ->setBackendType('varchar') + ->setIsUsedInGrid(1) + ->setIsVisibleInGrid(1) + ->setIsFilterableInGrid(1) + ->setFrontendLabel('nobody cares') + ->setAttributeGroupId($groupId) + ->setAttributeSetId(4); + +$attributeRepository->save($attribute); + +/** @var Processor $processor */ +$processor = $objectManager->create(Processor::class); +$scheduled = $processor->getIndexer() + ->isScheduled(); +$processor->reindexAll(); + +$product = $productFactory->create() + ->setTypeId(Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setName('Simple With Attribute That Used In Flat') + ->setSku('simple_with_custom_flat_attribute') + ->setPrice(100) + ->setVisibility(1) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_in_stock' => 1, + ] + ) + ->setStatus(1); +$product->setCustomAttribute('flat_attribute', 'flat attribute value'); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat_rollback.php new file mode 100644 index 0000000000000..c1892d504ecc3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat_rollback.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Catalog\Api\ProductAttributeRepositoryInterface; + +/** @var Magento\Framework\ObjectManagerInterface $objectManager */ +$objectManager = Bootstrap::getObjectManager(); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var ProductAttributeRepositoryInterface $attributeRepository */ +$attributeRepository = $objectManager->get(ProductAttributeRepositoryInterface::class); +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + /** @var \Magento\Catalog\Api\Data\ProductInterface $product */ + $product = $productRepository->get('simple_with_custom_flat_attribute'); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} + +try { + /** @var \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute */ + $attribute = $attributeRepository->get('flat_attribute'); + $attributeRepository->delete($attribute); +} catch (NoSuchEntityException $e) { +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 072660ea9b68a28f760554f7b348514f7209671e Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Tue, 27 Nov 2018 16:11:07 +0100 Subject: [PATCH 1363/1415] style: change b to strong (a11y) --- .../order/view/info/fraud_details.phtml | 4 ++-- .../view/adminhtml/email/failed_payment.html | 20 +++++++++---------- .../view/frontend/email/submitted_form.html | 8 ++++---- .../system/currency/rate/matrix.phtml | 4 ++-- .../templates/sample_email_content.phtml | 2 +- .../email/cron_error.html | 2 +- .../email/account_new_confirmed.html | 2 +- .../templates/sample_email_content.phtml | 2 +- .../sample_email_content_custom.phtml | 2 +- .../Magento_Customer/email/account_new.html | 2 +- .../email/account_new_confirmation.html | 2 +- lib/web/css/docs/forms.html | 2 +- lib/web/css/docs/variables.html | 2 +- setup/view/magento/setup/data-option.phtml | 4 ++-- setup/view/magento/setup/extension-grid.phtml | 4 ++-- setup/view/magento/setup/module-grid.phtml | 2 +- setup/view/magento/setup/select-version.phtml | 2 +- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml index 60fec263352fe..ac91fa30bfbe0 100644 --- a/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml +++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml @@ -44,8 +44,8 @@ $fraudDetails = $payment->getAdditionalInformation('fraud_details'); <?php endif; ?> <?php if(!empty($fraudDetails['fraud_filters'])): ?> - <b><?= $block->escapeHtml(__('Fraud Filters')) ?>: - </b></br> + <strong><?= $block->escapeHtml(__('Fraud Filters')) ?>: + </strong></br> <?php foreach($fraudDetails['fraud_filters'] as $filter): ?> <?= $block->escapeHtml($filter['name']) ?>: <?= $block->escapeHtml($filter['action']) ?> diff --git a/app/code/Magento/Checkout/view/adminhtml/email/failed_payment.html b/app/code/Magento/Checkout/view/adminhtml/email/failed_payment.html index fb55f9b601dc9..03ad7d9e8d848 100644 --- a/app/code/Magento/Checkout/view/adminhtml/email/failed_payment.html +++ b/app/code/Magento/Checkout/view/adminhtml/email/failed_payment.html @@ -23,43 +23,43 @@ <h1>{{trans "Payment Transaction Failed"}}</h1> <ul> <li> - <b>{{trans "Reason"}}</b><br /> + <strong>{{trans "Reason"}}</strong><br /> {{var reason}} </li> <li> - <b>{{trans "Checkout Type"}}</b><br /> + <strong>{{trans "Checkout Type"}}</strong><br /> {{var checkoutType}} </li> <li> - <b>{{trans "Customer:"}}</b><br /> + <strong>{{trans "Customer:"}}</strong><br /> <a href="mailto:{{var customerEmail}}">{{var customer}}</a> <{{var customerEmail}}> </li> <li> - <b>{{trans "Items"}}</b><br /> + <strong>{{trans "Items"}}</strong><br /> {{var items|raw}} </li> <li> - <b>{{trans "Total:"}}</b><br /> + <strong>{{trans "Total:"}}</strong><br /> {{var total}} </li> <li> - <b>{{trans "Billing Address:"}}</b><br /> + <strong>{{trans "Billing Address:"}}</strong><br /> {{var billingAddress.format('html')|raw}} </li> <li> - <b>{{trans "Shipping Address:"}}</b><br /> + <strong>{{trans "Shipping Address:"}}</strong><br /> {{var shippingAddress.format('html')|raw}} </li> <li> - <b>{{trans "Shipping Method:"}}</b><br /> + <strong>{{trans "Shipping Method:"}}</strong><br /> {{var shippingMethod}} </li> <li> - <b>{{trans "Payment Method:"}}</b><br /> + <strong>{{trans "Payment Method:"}}</strong><br /> {{var paymentMethod}} </li> <li> - <b>{{trans "Date & Time:"}}</b><br /> + <strong>{{trans "Date & Time:"}}</strong><br /> {{var dateAndTime}} </li> </ul> diff --git a/app/code/Magento/Contact/view/frontend/email/submitted_form.html b/app/code/Magento/Contact/view/frontend/email/submitted_form.html index 1bce6159c586a..17146257aeff1 100644 --- a/app/code/Magento/Contact/view/frontend/email/submitted_form.html +++ b/app/code/Magento/Contact/view/frontend/email/submitted_form.html @@ -16,19 +16,19 @@ <table class="message-details"> <tr> - <td><b>{{trans "Name"}}</b></td> + <td><strong>{{trans "Name"}}</strong></td> <td>{{var data.name}}</td> </tr> <tr> - <td><b>{{trans "Email"}}</b></td> + <td><strong>{{trans "Email"}}</strong></td> <td>{{var data.email}}</td> </tr> <tr> - <td><b>{{trans "Phone"}}</b></td> + <td><strong>{{trans "Phone"}}</strong></td> <td>{{var data.telephone}}</td> </tr> </table> -<p><b>{{trans "Message"}}</b></p> +<p><strong>{{trans "Message"}}</strong></p> <p>{{var data.comment}}</p> {{template config_path="design/email/footer_template"}} diff --git a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml index 8e0abcb319764..8a16eb71e0853 100644 --- a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml +++ b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml @@ -45,7 +45,7 @@ $_rates = ($_newRates) ? $_newRates : $_oldRates; class="admin__control-text" <?= ($_currencyCode == $_rate) ? ' disabled' : '' ?> /> <?php if (isset($_newRates) && $_currencyCode != $_rate && isset($_oldRates[$_currencyCode][$_rate])): ?> - <div class="admin__field-note"><?= /* @escapeNotVerified */ __('Old rate:') ?> <b><?= /* @escapeNotVerified */ $_oldRates[$_currencyCode][$_rate] ?></b></div> + <div class="admin__field-note"><?= /* @escapeNotVerified */ __('Old rate:') ?> <strong><?= /* @escapeNotVerified */ $_oldRates[$_currencyCode][$_rate] ?></strong></div> <?php endif; ?> </td> <?php else: ?> @@ -56,7 +56,7 @@ $_rates = ($_newRates) ? $_newRates : $_oldRates; class="admin__control-text" <?= ($_currencyCode == $_rate) ? ' disabled' : '' ?> /> <?php if (isset($_newRates) && $_currencyCode != $_rate && isset($_oldRates[$_currencyCode][$_rate])): ?> - <div class="admin__field-note"><?= /* @escapeNotVerified */ __('Old rate:') ?> <b><?= /* @escapeNotVerified */ $_oldRates[$_currencyCode][$_rate] ?></b></div> + <div class="admin__field-note"><?= /* @escapeNotVerified */ __('Old rate:') ?> <strong><?= /* @escapeNotVerified */ $_oldRates[$_currencyCode][$_rate] ?></strong></div> <?php endif; ?> </td> <?php endif; ?> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_Email/templates/sample_email_content.phtml b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_Email/templates/sample_email_content.phtml index d53468a38376f..bb0073cedee96 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_Email/templates/sample_email_content.phtml +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_Email/templates/sample_email_content.phtml @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ ?> -<b>Email content for adminhtml/Magento/default theme</b> +<strong>Email content for adminhtml/Magento/default theme</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_ProductAlert/email/cron_error.html b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_ProductAlert/email/cron_error.html index f13e54edf93a4..d65f9d4c40877 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_ProductAlert/email/cron_error.html +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/adminhtml/Magento/default/Magento_ProductAlert/email/cron_error.html @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ --> -<b>catalog_productalert_cron_error_email_template template from Magento/default</b> +<strong>catalog_productalert_cron_error_email_template template from Magento/default</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Customer/email/account_new_confirmed.html b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Customer/email/account_new_confirmed.html index f687fc041db1e..ffc4d8893fe98 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Customer/email/account_new_confirmed.html +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Customer/email/account_new_confirmed.html @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ --> -<b>customer_create_account_email_confirmed_template template from Magento/default</b> +<strong>customer_create_account_email_confirmed_template template from Magento/default</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content.phtml b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content.phtml index acbdf16d474df..9c973818272c8 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content.phtml +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content.phtml @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ ?> -<b>Email content for frontend/Magento/default theme</b> +<strong>Email content for frontend/Magento/default theme</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content_custom.phtml b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content_custom.phtml index 1730bf904bb34..4ed5685ee0106 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content_custom.phtml +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Magento/default/Magento_Email/templates/sample_email_content_custom.phtml @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ ?> -<b>Custom Email content for frontend/Magento/default theme</b> +<strong>Custom Email content for frontend/Magento/default theme</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/custom_theme/Magento_Customer/email/account_new.html b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/custom_theme/Magento_Customer/email/account_new.html index 7e8f9bd1b12b6..46257060f8284 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/custom_theme/Magento_Customer/email/account_new.html +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/custom_theme/Magento_Customer/email/account_new.html @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ --> -<b>customer_create_account_email_template template from Vendor/custom_theme</b> +<strong>customer_create_account_email_template template from Vendor/custom_theme</strong> diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/default/Magento_Customer/email/account_new_confirmation.html b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/default/Magento_Customer/email/account_new_confirmation.html index c5801b6557a61..9c52c5a1b38cf 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/default/Magento_Customer/email/account_new_confirmation.html +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/design/frontend/Vendor/default/Magento_Customer/email/account_new_confirmation.html @@ -4,4 +4,4 @@ * See COPYING.txt for license details. */ --> -<b>customer_create_account_email_confirmation_template template from Vendor/default</b> +<strong>customer_create_account_email_confirmation_template template from Vendor/default</strong> diff --git a/lib/web/css/docs/forms.html b/lib/web/css/docs/forms.html index 211a9bd650ba0..dc08ddffd2066 100644 --- a/lib/web/css/docs/forms.html +++ b/lib/web/css/docs/forms.html @@ -713,7 +713,7 @@ <h2 id="simple-form-with-required-fields-message">Simple form with "require <th>@_type</th> <td class="vars_value">@form-element-input-type</td> <td class="vars_value">'' [input-text | select | textarea | input-radio | input-checkbox]</td> - <td>Form control type.<br/><b>@form-element-input__[]</b> global variables are used to set up all form elements style. Control-specific global variables use these <b>@form-element-input__[]</b> variables by default. Control-specific global variables can be set up separately.<br/><b>@input-text__[]</b> is used to set up input-text controls style<br/><b>@select__[]</b> is used to set up selects style<br/><b>@textarea__[]</b> is used to set up textarea style</td> + <td>Form control type.<br/><strong>@form-element-input__[]</strong> global variables are used to set up all form elements style. Control-specific global variables use these <strong>@form-element-input__[]</strong> variables by default. Control-specific global variables can be set up separately.<br/><strong>@input-text__[]</strong> is used to set up input-text controls style<br/><strong>@select__[]</strong> is used to set up selects style<br/><strong>@textarea__[]</strong> is used to set up textarea style</td> </tr> <tr> <th>@_background</th> diff --git a/lib/web/css/docs/variables.html b/lib/web/css/docs/variables.html index 4f353dc1554a4..ebbf2122ab209 100644 --- a/lib/web/css/docs/variables.html +++ b/lib/web/css/docs/variables.html @@ -3507,7 +3507,7 @@ <h4 id="the-codelibformelementinputcoed-mixin-variables">The <code>.lib-form-ele <th>@_type</th> <td class="vars_value">@form-element-input-type</td> <td class="vars_value">'' [input-text | select | textarea | input-radio | input-checkbox]</td> - <td>Form control type.<br/><b>@form-element-input__[]</b> global variables are used to set up all form elements style. Control-specific global variables use these <b>@form-element-input__[]</b> variables by default. Control-specific global variables can be set up separately.<br/><b>@input-text__[]</b> is used to set up input-text controls style<br/><b>@select__[]</b> is used to set up selects style<br/><b>@textarea__[]</b> is used to set up textarea style</td> + <td>Form control type.<br/><strong>@form-element-input__[]</strong> global variables are used to set up all form elements style. Control-specific global variables use these <strong>@form-element-input__[]</strong> variables by default. Control-specific global variables can be set up separately.<br/><strong>@input-text__[]</strong> is used to set up input-text controls style<br/><strong>@select__[]</strong> is used to set up selects style<br/><strong>@textarea__[]</strong> is used to set up textarea style</td> </tr> <tr> <th>@_background</th> diff --git a/setup/view/magento/setup/data-option.phtml b/setup/view/magento/setup/data-option.phtml index cb31d96013f24..656b04876c414 100644 --- a/setup/view/magento/setup/data-option.phtml +++ b/setup/view/magento/setup/data-option.phtml @@ -43,7 +43,7 @@ value="false" > <label class="form-label" for="keepData"> - <b>Keep data</b> + <strong>Keep data</strong> <br/><br/> Note: You can see the associated data in your database, however your customer will not see this in your online store. @@ -59,7 +59,7 @@ value="true" > <label class="form-label" for="removeData"> - <b>Remove data</b> + <strong>Remove data</strong> <br/><br/> Did you back up first? Choosing to remove data means the data is unavailable unless you recover it from a backup in the preceding step. diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index 47e5f7eec309b..df2203df2c054 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -66,8 +66,8 @@ <div class="row" ng-show="$root.isMarketplaceAuthorized && extensionsProcessed && total == 0"> <label class="form-label not-found"> - <b>You haven't purchased any extensions yet. Visit <a href="https://marketplace.magento.com">Marketplace</a> - for purchasing extensions.</b><br/> + <strong>You haven't purchased any extensions yet. Visit <a href="https://marketplace.magento.com">Marketplace</a> + for purchasing extensions.</strong><br/> </label> </div> <div class="admin__data-grid-outer-wrap" diff --git a/setup/view/magento/setup/module-grid.phtml b/setup/view/magento/setup/module-grid.phtml index 5fe0447b7c791..3bf9377104df1 100644 --- a/setup/view/magento/setup/module-grid.phtml +++ b/setup/view/magento/setup/module-grid.phtml @@ -8,7 +8,7 @@ <div class="row" ng-show="modulesProcessed && total == 0"> <label class="form-label"> - <b>We didn't find any modules at this time. Please try later.</b><br/> + <strong>We didn't find any modules at this time. Please try later.</strong><br/> </label> </div> <div class="admin__data-grid-outer-wrap" ng-show="modulesProcessed && total > 0"> diff --git a/setup/view/magento/setup/select-version.phtml b/setup/view/magento/setup/select-version.phtml index 920ab86252514..66264e46d50ad 100644 --- a/setup/view/magento/setup/select-version.phtml +++ b/setup/view/magento/setup/select-version.phtml @@ -128,7 +128,7 @@ </div> <div class="row" ng-show="componentsProcessed && total == 0"> <label class="form-label"> - <b>We didn't find any components to upgrade. Click "Next" to continue.<br/> + <strong>We didn't find any components to upgrade. Click "Next" to continue.</strong><br/> </label> </div> <div class="admin__data-grid-outer-wrap" ng-show="componentsProcessed && total > 0"> From 2c8372e62310c85bf7249ff7ba11d199f939d849 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 27 Nov 2018 10:09:19 -0600 Subject: [PATCH 1364/1415] MQE-1187: Fix MFTF skipped tests - Test flaky timing fix, brittle test fix --- .../Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml | 1 + .../Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml | 2 +- .../Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml index 68f6b49e80996..d08f10b22419d 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml @@ -12,6 +12,7 @@ <argument name="customerEmail"/> </arguments> <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomersPage"/> + <conditionalClick selector="{{AdminCustomerFiltersSection.clearAll}}" dependentSelector="{{AdminCustomerFiltersSection.clearAll}}" visible="true" stepKey="clickClearFilters"/> <click stepKey="chooseCustomer" selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}"/> <click stepKey="openActions" selector="{{AdminCustomerGridMainActionsSection.actions}}"/> <waitForPageLoad stepKey="waitActions"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml index d5006eff2fb4a..c44e3f249216b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml @@ -15,6 +15,6 @@ <element name="emailInput" type="input" selector="input[name=email]"/> <element name="apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> <element name="clearAllFilters" type="text" selector=".admin__current-filters-actions-wrap.action-clear"/> - <element name="clearAll" type="button" selector=".action-tertiary.action-clear"/> + <element name="clearAll" type="button" selector=".admin__data-grid-header .action-tertiary.action-clear"/> </section> </sections> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml index 000fba1d88697..1ce94001e55d1 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml @@ -312,6 +312,7 @@ <argument name="Address" value="US_Address_CA"/> </actionGroup> <click stepKey="clickNext" selector="{{CheckoutShippingSection.next}}"/> + <waitForPageLoad stepKey="waitForAddressToLoad"/> <see stepKey="seeAddress" selector="{{CheckoutShippingSection.defaultShipping}}" userInput="{{SimpleTaxCA.state}}"/> <see stepKey="seeShipTo" selector="{{CheckoutPaymentSection.shipToInformation}}" userInput="{{SimpleTaxCA.state}}"/> @@ -329,6 +330,7 @@ <argument name="Address" value="US_Address_NY"/> </actionGroup> <click stepKey="clickNext2" selector="{{CheckoutShippingSection.next}}"/> + <waitForPageLoad stepKey="waitForShippingToLoad"/> <see stepKey="seeShipTo2" selector="{{CheckoutPaymentSection.shipToInformation}}" userInput="{{SimpleTaxNY.state}}"/> <!-- Assert that taxes are applied correctly for NY --> From 98591b458ecf24291876a7ae0d02de08d293e986 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Tue, 27 Nov 2018 11:20:30 -0600 Subject: [PATCH 1365/1415] MC-5321: Create tax rate, wider zip code range --- .../Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml index ba65ea43a6a87..0920ac522785f 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml @@ -10,8 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminCreateTaxRateWiderZipCodeRange"> <annotations> - <stories value="Create tax rate, wider zip code range"/> - <title value="Create Tax Rate"/> + <stories value="Create tax rate"/> + <title value="Create Tax Rate, wider zip code range"/> <description value="Test log in to Create Tax Rate and Create Wider Zip Code Range"/> <testCaseId value="MC-5321"/> <severity value="CRITICAL"/> From 1d0820625eba1602cc929494a9692a193d822873 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Tue, 27 Nov 2018 12:58:33 -0600 Subject: [PATCH 1366/1415] MC-5322: Create tax rate, large rate --- .../Mftf/Test/AdminCreateTaxRateLargeRate.xml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml new file mode 100644 index 0000000000000..db029359b83ac --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateTaxRateLargeRate"> + <annotations> + <stories value="Create tax rate"/> + <title value="Create Tax Rate, large rate"/> + <description value="Test log in to Create Tax Rate and Create Large Rate"/> + <testCaseId value="MC-5322"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillNameFilter"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + <click selector="{{AdminTaxRateFormSection.deleteRate}}" stepKey="clickDeleteRate"/> + <click selector="{{AdminTaxRateFormSection.ok}}" stepKey="clickOk"/> + </after> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <!-- Create a tax rate for large postcodes --> + <click selector="{{AdminTaxRateGridSection.add}}" stepKey="clickAddNewTaxRateButton"/> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillRuleName"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="*" stepKey="fillPostCode"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="France" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="Val-d'Oise" stepKey="selectState" /> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="999" stepKey="fillRate"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex3"/> + <!-- Create a tax rate for large postcodes and verify we see expected values on the tax rate grid page --> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateGridSection.filterByCountry}}" userInput="France" stepKey="selectCountry2" /> + <fillField selector="{{AdminTaxRateGridSection.filterByPostCode}}" userInput="*" stepKey="seeTaxPostCode1"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow3"/> + <!-- Verify we see expected values on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxIdentifierField2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="*" stepKey="seeZipCode"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="France" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="Val-d'Oise" stepKey="seeState"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="999" stepKey="seeRate"/> + + <!-- Verify we see expected values on the tax rule form page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRuleIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex4"/> + <click selector="{{AdminTaxRuleGridSection.add}}" stepKey="clickAdd"/> + <see selector="{{AdminTaxRulesSection.taxRateMultiSelectItems}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeTaxRateOnNewTaxRulePage"/> + </test> +</tests> From 43325d2ccebb77bfb1639a921836ec82dbaa644a Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Tue, 27 Nov 2018 13:05:14 -0600 Subject: [PATCH 1367/1415] MAGETWO-96009: Restricted admin still able to send order comment email modifying POST request - Add additional ACL check to make sure user also has permissions to send comment email - Add unit test coverage for this functionality --- .../Controller/Adminhtml/Order/AddComment.php | 22 ++- .../Adminhtml/Order/AddCommentTest.php | 176 ++++++++++++++++++ 2 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php index 07716314ec6e2..e85083a50d725 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php @@ -1,16 +1,17 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Controller\Adminhtml\Order; -use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Sales\Model\Order\Email\Sender\OrderCommentSender; -class AddComment extends \Magento\Sales\Controller\Adminhtml\Order +/** + * Class AddComment + */ +class AddComment extends \Magento\Sales\Controller\Adminhtml\Order implements HttpPostActionInterface { /** * Authorization level of a basic admin session @@ -19,6 +20,11 @@ class AddComment extends \Magento\Sales\Controller\Adminhtml\Order */ const ADMIN_RESOURCE = 'Magento_Sales::comment'; + /** + * ACL resource needed to send comment email notification + */ + const ADMIN_SALES_EMAIL_RESOURCE = 'Magento_Sales::emails'; + /** * Add order comment action * @@ -36,8 +42,12 @@ public function execute() ); } - $notify = isset($data['is_customer_notified']) ? $data['is_customer_notified'] : false; - $visible = isset($data['is_visible_on_front']) ? $data['is_visible_on_front'] : false; + $notify = $data['is_customer_notified'] ?? false; + $visible = $data['is_visible_on_front'] ?? false; + + if ($notify && !$this->_authorization->isAllowed(self::ADMIN_SALES_EMAIL_RESOURCE)) { + $notify = false; + } $history = $order->addStatusHistoryComment($data['comment'], $data['status']); $history->setIsVisibleOnFront($visible); diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php new file mode 100644 index 0000000000000..3a4157df5c76f --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php @@ -0,0 +1,176 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Controller\Adminhtml\Order; + +class AddCommentTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Sales\Controller\Adminhtml\Order\AddComment + */ + private $addCommentController; + + /** + * @var \Magento\Backend\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject + */ + private $contextMock; + + /** + * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var \Magento\Backend\Model\View\Result\RedirectFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $resultRedirectFactoryMock; + + /** + * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject + */ + private $resultRedirectMock; + + /** + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + /** + * @var \Magento\Sales\Api\OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderRepositoryMock; + + /** + * @var \Magento\Framework\AuthorizationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $authorizationMock; + + /** + * @var \Magento\Sales\Model\Order\Status\History|\PHPUnit_Framework_MockObject_MockObject + */ + private $statusHistoryCommentMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + /** + * Test setup + */ + protected function setUp() + { + $this->contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class); + $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); + $this->orderRepositoryMock = $this->createMock(\Magento\Sales\Api\OrderRepositoryInterface::class); + $this->orderMock = $this->createMock(\Magento\Sales\Model\Order::class); + $this->resultRedirectFactoryMock = $this->createMock(\Magento\Backend\Model\View\Result\RedirectFactory::class); + $this->resultRedirectMock = $this->createMock(\Magento\Backend\Model\View\Result\Redirect::class); + $this->authorizationMock = $this->createMock(\Magento\Framework\AuthorizationInterface::class); + $this->statusHistoryCommentMock = $this->createMock(\Magento\Sales\Model\Order\Status\History::class); + $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); + + $this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock); + + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->addCommentController = $objectManagerHelper->getObject( + \Magento\Sales\Controller\Adminhtml\Order\AddComment::class, + [ + 'context' => $this->contextMock, + 'orderRepository' => $this->orderRepositoryMock, + '_authorization' => $this->authorizationMock, + '_objectManager' => $this->objectManagerMock + ] + ); + } + + /** + * @param array $historyData + * @param bool $userHasResource + * @param bool $expectedNotify + * + * @dataProvider executeWillNotifyCustomerDataProvider + */ + public function testExecuteWillNotifyCustomer(array $historyData, bool $userHasResource, bool $expectedNotify) + { + $orderId = 30; + $this->requestMock->expects($this->once())->method('getParam')->with('order_id')->willReturn($orderId); + $this->orderRepositoryMock->expects($this->once()) + ->method('get') + ->willReturn($this->orderMock); + $this->requestMock->expects($this->once())->method('getPost')->with('history')->willReturn($historyData); + $this->authorizationMock->expects($this->any())->method('isAllowed')->willReturn($userHasResource); + $this->orderMock->expects($this->once()) + ->method('addStatusHistoryComment') + ->willReturn($this->statusHistoryCommentMock); + $this->statusHistoryCommentMock->expects($this->once())->method('setIsCustomerNotified')->with($expectedNotify); + $this->objectManagerMock->expects($this->once())->method('create')->willReturn( + $this->createMock(\Magento\Sales\Model\Order\Email\Sender\OrderCommentSender::class) + ); + + $this->addCommentController->execute(); + } + + /** + * @return array + */ + public function executeWillNotifyCustomerDataProvider() + { + return [ + 'User Has Access - Notify True' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'is_customer_notified' => true, + 'status' => 'Processing' + ], + 'userHasResource' => true, + 'expectedNotify' => true + ], + 'User Has Access - Notify False' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'is_customer_notified' => false, + 'status' => 'Processing' + ], + 'userHasResource' => true, + 'expectedNotify' => false + ], + 'User Has Access - Notify Unset' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'status' => 'Processing' + ], + 'userHasResource' => true, + 'expectedNotify' => false + ], + 'User No Access - Notify True' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'is_customer_notified' => true, + 'status' => 'Processing' + ], + 'userHasResource' => false, + 'expectedNotify' => false + ], + 'User No Access - Notify False' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'is_customer_notified' => false, + 'status' => 'Processing' + ], + 'userHasResource' => false, + 'expectedNotify' => false + ], + 'User No Access - Notify Unset' => [ + 'postData' => [ + 'comment' => 'Great Product!', + 'status' => 'Processing' + ], + 'userHasResource' => false, + 'expectedNotify' => false + ], + ]; + } +} From 4d3347c78da87dac832e72b896ca23485b1a508e Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Wed, 28 Nov 2018 11:23:38 +0200 Subject: [PATCH 1368/1415] Fix: SalesQuoteSaveAfterObserver fails to update the checkout session quote id when applicable #19424 --- .../Checkout/Observer/SalesQuoteSaveAfterObserver.php | 10 ++++++++-- .../Unit/Observer/SalesQuoteSaveAfterObserverTest.php | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Observer/SalesQuoteSaveAfterObserver.php b/app/code/Magento/Checkout/Observer/SalesQuoteSaveAfterObserver.php index d926e33d54113..6bc7965ff5e34 100644 --- a/app/code/Magento/Checkout/Observer/SalesQuoteSaveAfterObserver.php +++ b/app/code/Magento/Checkout/Observer/SalesQuoteSaveAfterObserver.php @@ -7,6 +7,9 @@ use Magento\Framework\Event\ObserverInterface; +/** + * Class SalesQuoteSaveAfterObserver + */ class SalesQuoteSaveAfterObserver implements ObserverInterface { /** @@ -24,15 +27,18 @@ public function __construct(\Magento\Checkout\Model\Session $checkoutSession) } /** + * Assign quote to session + * * @param \Magento\Framework\Event\Observer $observer * @return void */ public function execute(\Magento\Framework\Event\Observer $observer) { + /* @var \Magento\Quote\Model\Quote $quote */ $quote = $observer->getEvent()->getQuote(); - /* @var $quote \Magento\Quote\Model\Quote */ + if ($quote->getIsCheckoutCart()) { - $this->checkoutSession->getQuoteId($quote->getId()); + $this->checkoutSession->setQuoteId($quote->getId()); } } } diff --git a/app/code/Magento/Checkout/Test/Unit/Observer/SalesQuoteSaveAfterObserverTest.php b/app/code/Magento/Checkout/Test/Unit/Observer/SalesQuoteSaveAfterObserverTest.php index 6070bb5d424c1..dabaf173d90b3 100644 --- a/app/code/Magento/Checkout/Test/Unit/Observer/SalesQuoteSaveAfterObserverTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Observer/SalesQuoteSaveAfterObserverTest.php @@ -30,13 +30,14 @@ protected function setUp() public function testSalesQuoteSaveAfter() { + $quoteId = 7; $observer = $this->createMock(\Magento\Framework\Event\Observer::class); $observer->expects($this->once())->method('getEvent')->will( $this->returnValue(new \Magento\Framework\DataObject( - ['quote' => new \Magento\Framework\DataObject(['is_checkout_cart' => 1, 'id' => 7])] + ['quote' => new \Magento\Framework\DataObject(['is_checkout_cart' => 1, 'id' => $quoteId])] )) ); - $this->checkoutSession->expects($this->once())->method('getQuoteId')->with(7); + $this->checkoutSession->expects($this->once())->method('setQuoteId')->with($quoteId); $this->object->execute($observer); } From 114f792296c7fbc7c925f2855b7cbbd7c580d4f1 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel.ruf@ueberbit.de> Date: Wed, 28 Nov 2018 12:09:20 +0100 Subject: [PATCH 1369/1415] fix: remove unused params in categorySubmit invocation --- .../Magento/Catalog/view/adminhtml/web/catalog/category/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js index 75ee3019cf4b6..41f7a874c26f3 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js @@ -82,7 +82,7 @@ define([ return function (config, element) { config = config || {}; jQuery(element).on('click', function () { - categorySubmit(config.url, config.ajax); + categorySubmit(); }); }; }); From b81de6429a1cf0bbb77fccb12b382017def58581 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Wed, 28 Nov 2018 15:50:18 +0200 Subject: [PATCH 1370/1415] MAGETWO-96713: Skipped randomly failing functional test --- .../Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 0d9df9176d2b5..3b9361f79871f 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -16,6 +16,9 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69826"/> <group value="urlRewrite"/> + <skip> + <issueId value="MAGETWO-96713"/> + </skip> </annotations> <!-- Preconditions--> From 2eef9e67c97a03bbba82852da367c03ea525f4f4 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Wed, 28 Nov 2018 16:20:39 +0200 Subject: [PATCH 1371/1415] magento-engcom/import-export-improvements#150: Changing property access level for backward compatibility --- app/code/Magento/ImportExport/Model/History.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Model/History.php b/app/code/Magento/ImportExport/Model/History.php index 19d62259c02a2..b85bf7da81a35 100644 --- a/app/code/Magento/ImportExport/Model/History.php +++ b/app/code/Magento/ImportExport/Model/History.php @@ -45,7 +45,7 @@ class History extends \Magento\Framework\Model\AbstractModel /** * @var \Magento\Backend\Model\Auth\Session */ - private $session; + protected $session; /** * Class constructor From 1ee184b765766d3dbda58c3b03b7e572661c0c44 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 28 Nov 2018 10:32:55 -0600 Subject: [PATCH 1372/1415] MC-5580: Fatal Error during customer login - fix static tests --- .../Magento/Framework/Encryption/Encryptor.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index 919e710d4f2de..343b631b4a468 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -228,6 +228,8 @@ public function validateHashVersion($hash, $validateCount = false) } /** + * Explode password hash + * * @param string $hash * @return array */ @@ -243,6 +245,8 @@ private function explodePasswordHash($hash) } /** + * Returns password hash + * * @return string */ private function getPasswordHash() @@ -251,6 +255,8 @@ private function getPasswordHash() } /** + * Returns password salt + * * @return string */ private function getPasswordSalt() @@ -259,11 +265,15 @@ private function getPasswordSalt() } /** + * Returns password version + * * @return array */ private function getPasswordVersion() { - return array_map('intval', explode( + return array_map( + 'intval', + explode( self::DELIMITER, (string)$this->passwordHashMap[self::PASSWORD_VERSION] ) From 4bf63dadd2df27035063eb24d34c33bc57863470 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 18 Nov 2018 17:14:31 +0530 Subject: [PATCH 1373/1415] issue #19205 fixed --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index b61df8d7cb125..e5755df2291ee 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -827,7 +827,7 @@ private function multiToFlatArray(array $array) if (is_array($value)) { $flatArray = array_merge($flatArray, $this->multiToFlatArray($value)); } else { - $flatArray[$key] = $value; + $flatArray[] = $value; } } From 98ae6ae5f81ed8d9a2de2016390289d110756ac6 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 18 Nov 2018 18:55:08 +0530 Subject: [PATCH 1374/1415] removed unused variable --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index e5755df2291ee..c8cd8c15fdb8e 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -823,7 +823,7 @@ private function recursiveIntval(array $array) private function multiToFlatArray(array $array) { $flatArray = []; - foreach ($array as $key => $value) { + foreach ($array as $value) { if (is_array($value)) { $flatArray = array_merge($flatArray, $this->multiToFlatArray($value)); } else { From 8f22688c3129b973c2bfce69f5871fec1fbcbc92 Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano <fabrizio.balliano@gmail.com> Date: Thu, 29 Nov 2018 11:20:05 +0000 Subject: [PATCH 1375/1415] min php version fix as written here: https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements-tech.html the min php version is 7.1.3 but the check in this file was wrong (so also the error messages) --- app/bootstrap.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/bootstrap.php b/app/bootstrap.php index 8e901cac9bfb8..19283f37d5910 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -11,15 +11,15 @@ #ini_set('display_errors', 1); /* PHP version validation */ -if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) { +if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70103) { if (PHP_SAPI == 'cli') { - echo 'Magento supports 7.0.2, 7.0.4, and 7.0.6 or later. ' . - 'Please read http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements.html'; + echo 'Magento supports 7.1.3 or later. ' . + 'Please read https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html'; } else { echo <<<HTML <div style="font:12px/1.35em arial, helvetica, sans-serif;"> - <p>Magento supports PHP 7.0.2, 7.0.4, and 7.0.6 or later. Please read - <a target="_blank" href="http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements.html"> + <p>Magento supports PHP 7.1.3 or later. Please read + <a target="_blank" href="https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html"> Magento System Requirements</a>. </div> HTML; From 381c3a04b114c14e442157747b2ab90834104753 Mon Sep 17 00:00:00 2001 From: Fabrizio Balliano <fabrizio.balliano@gmail.com> Date: Thu, 29 Nov 2018 11:52:04 +0000 Subject: [PATCH 1376/1415] sys requirements link updated --- app/bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/bootstrap.php b/app/bootstrap.php index 19283f37d5910..40043d4b01c6c 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -14,12 +14,12 @@ if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70103) { if (PHP_SAPI == 'cli') { echo 'Magento supports 7.1.3 or later. ' . - 'Please read https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html'; + 'Please read https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements-tech.html'; } else { echo <<<HTML <div style="font:12px/1.35em arial, helvetica, sans-serif;"> <p>Magento supports PHP 7.1.3 or later. Please read - <a target="_blank" href="https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html"> + <a target="_blank" href="https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements-tech.html"> Magento System Requirements</a>. </div> HTML; From ebce9f357021babb30fcffe01cc8ae7bfbdfe8d9 Mon Sep 17 00:00:00 2001 From: Vlad Veselov <orlangur@users.noreply.github.com> Date: Thu, 29 Nov 2018 14:09:11 +0200 Subject: [PATCH 1377/1415] Make messages consistent --- app/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/bootstrap.php b/app/bootstrap.php index 40043d4b01c6c..0b13d12cece58 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -13,7 +13,7 @@ /* PHP version validation */ if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70103) { if (PHP_SAPI == 'cli') { - echo 'Magento supports 7.1.3 or later. ' . + echo 'Magento supports PHP 7.1.3 or later. ' . 'Please read https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements-tech.html'; } else { echo <<<HTML From e3a8af60bd5cd7bc141da21bb57ec99d743f7db2 Mon Sep 17 00:00:00 2001 From: Max <omaxmo@users.noreply.github.com> Date: Thu, 29 Nov 2018 16:54:14 +0200 Subject: [PATCH 1378/1415] Update Invoice.php you can't cancel invoice if state == paid, If state == paid, you can do the credit memo. When you create an invoice and realise that it needs to be cancelled, be aware that there are some legal restrictions involved. Technically, you should never delete an issued invoice but instead use a credit note to cancel the invoice. --- app/code/Magento/Sales/Model/Order/Invoice.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php index 3f2fa1f72f6e5..e0cd96cd54d8c 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Order/Invoice.php @@ -445,10 +445,6 @@ public function cancel() $order->setBaseDiscountInvoiced($order->getBaseDiscountInvoiced() - $this->getBaseDiscountAmount()); $order->setBaseTotalInvoicedCost($order->getBaseTotalInvoicedCost() - $this->getBaseCost()); - if ($this->getState() == self::STATE_PAID) { - $order->setTotalPaid($order->getTotalPaid() - $this->getGrandTotal()); - $order->setBaseTotalPaid($order->getBaseTotalPaid() - $this->getBaseGrandTotal()); - } $this->setState(self::STATE_CANCELED); $order->setState(\Magento\Sales\Model\Order::STATE_PROCESSING) ->setStatus($order->getConfig()->getStateDefaultStatus(\Magento\Sales\Model\Order::STATE_PROCESSING)); From db6e9046bf91a74b2119aaf9df3b2a0b9c519dd5 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Thu, 29 Nov 2018 08:56:33 -0600 Subject: [PATCH 1379/1415] MC-5328: Update tax rate, 100 rate --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 48 +++++++++++++++ .../Tax/Test/Mftf/Metadata/tax_rate-meta.xml | 25 ++++++++ .../Mftf/Test/Update100TaxRateEntityTest.xml | 60 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 7a8dc35e79690..de40b448311ac 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -10,4 +10,52 @@ <entity name="SimpleTaxRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> </entity> + <entity name="taxRateCustomRateUS" type="taxRate"> + <data key="code" unique="suffix">Tax Rate </data> + <data key="tax_country_id">US</data> + <data key="tax_region_id">12</data> + <data key="tax_postcode">90001</data> + <data key="zip_is_range">0</data> + <data key="rate">100</data> + </entity> + <entity name="defaultTaxRateWithZipRange" type="taxRate"> + <data key="code" unique="suffix">Tax Rate </data> + <data key="tax_country_id">United States</data> + <data key="tax_region_id">12</data> + <data key="zip_is_range">1</data> + <data key="zip_from">90001</data> + <data key="zip_to">96162</data> + <data key="rate">15.05</data> + </entity> + <entity name="defaultTaxRateWithLargeRate" type="taxRate"> + <data key="code" unique="suffix">TaxRate</data> + <data key="tax_country_id">United Kingdom</data> + <data key="tax_postcode">*</data> + <data key="zip_is_range">0</data> + <data key="rate">777</data> + </entity> + <entity name="taxRateCustomRateCanada" type="taxRate"> + <data key="code" unique="suffix">TaxRate</data> + <data key="tax_country_id">Canada</data> + <data key="tax_region_id">*</data> + <data key="tax_postcode">180</data> + <data key="zip_is_range">0</data> + <data key="rate">25</data> + </entity> + <entity name="taxRateCustomRateUK" type="taxRate"> + <data key="code" unique="suffix">TaxRate</data> + <data key="tax_country_id">United Kingdom</data> + <data key="zip_is_range">1</data> + <data key="zip_from">1</data> + <data key="zip_to">7800935</data> + <data key="rate">12.99</data> + </entity> + <entity name="taxRateCustomRateFrance" type="taxRate"> + <data key="code" unique="suffix">TaxRate</data> + <data key="tax_country_id">France</data> + <data key="tax_region_id">277</data> + <data key="tax_postcode">*</data> + <data key="zip_is_range">0</data> + <data key="rate">0.1</data> + </entity> </entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml new file mode 100644 index 0000000000000..1951ae05831db --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateTaxRate" dataType="taxRate" type="create" auth="adminOauth" url="/V1/taxRates" method="POST"> + <contentType>application/json</contentType> + <object key="taxRate" dataType="taxRate"> + <field key="id">integer</field> + <field key="tax_country_id">string</field> + <field key="tax_region_id">integer</field> + <field key="tax_postcode">string</field> + <field key="zip_is_range">integer</field> + <field key="rate">integer</field> + <field key="code">string</field> + </object> + </operation> + <operation name="DeleteTaxRate" dataType="taxRate" type="delete" auth="adminOauth" url="/V1/taxRates/{id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> +</operations> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml new file mode 100644 index 0000000000000..31c9a017389f4 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="Update100TaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, 100 rate"/> + <description value="Test log in to Tax Rate and Update 100 Rate"/> + <testCaseId value="MC-5328"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="taxRateCustomRateUS" stepKey="createTaxRateCustomRateUS"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="createTaxRateCustomRateUS" /> + </after> + + <!-- Search the tax rate on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$createTaxRateCustomRateUS.code$$" stepKey="fillCode"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update values on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="selectState"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="90001" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="100" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated TaxIdentifier(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex4"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField3"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated values on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="seeState2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="90001" stepKey="seeZipCode"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="100" stepKey="seeRate2"/> + </test> +</tests> From cd4b3666b5aa2603ebcdf6d57b39a0fb3903ce1d Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 29 Nov 2018 10:03:48 -0600 Subject: [PATCH 1380/1415] MQE-1187: Fix MFTF skipped tests - Changing skipped tests from MQE-1328 to Magento buc MC-5777 --- .../Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml | 10 +++++----- .../Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml | 2 +- .../Mftf/Test/StorefrontInactiveCatalogRuleTest.xml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml index c8f42213b094c..875a7842f21ff 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml @@ -17,7 +17,7 @@ <testCaseId value="MC-74"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml index 6302ae20407ac..10db68e9053d7 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-65"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> @@ -78,7 +78,7 @@ <testCaseId value="MC-93"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> @@ -104,7 +104,7 @@ <testCaseId value="MC-69"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> @@ -130,7 +130,7 @@ <testCaseId value="MC-60"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> @@ -156,7 +156,7 @@ <testCaseId value="MC-71"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml index ca14315300dbb..06f3682aedd85 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-160"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index aa424b735b179..c6ecc1c6d9658 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -18,7 +18,7 @@ <testCaseId value="MC-79"/> <group value="CatalogRule"/> <skip> - <issueId value="MQE-1328"/> + <issueId value="MC-5777"/> </skip> </annotations> <before> From 70b43a519c48fe8f781c49a1f23d05e93e140359 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 29 Nov 2018 10:05:03 -0600 Subject: [PATCH 1381/1415] MAGETWO-96385: Deleting address on frontend redirects to 404 Page - recommitting after a force push --- .../StorefrontCustomerAddressModalSection.xml | 15 --------------- .../Section/StorefrontCustomerAddressSection.xml | 14 -------------- .../StorefrontCustomerAddressesSection.xml | 1 + .../Test/StorefrontDeleteCustomerAddressTest.xml | 9 ++++----- .../Mftf/Section/ModalConfirmationSection.xml | 1 + 5 files changed, 6 insertions(+), 34 deletions(-) delete mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml delete mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml deleted file mode 100644 index 5cdf7dfea5483..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressModalSection.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontCustomerAddressConfirmationModalSection"> - <element name="message" type="text" selector="aside.confirm div.modal-content"/> - <element name="ok" type="button" selector="aside.confirm .modal-footer .action-primary"/> - <element name="cancel" type="button" selector="aside.confirm .modal-footer .action-secondary"/> - </section> -</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml deleted file mode 100644 index 02ff60dc2c169..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressSection.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="StorefrontCustomerAddressSection"> - <element name="deleteAdditionalAddress" type="button" selector=".action.delete" timeout="30"/> - </section> -</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml index 8a6a98ff45a6a..05bbc559defac 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontCustomerAddressesSection"> <element name="addressesList" type="text" selector=".block-addresses-list" /> + <element name="deleteAdditionalAddress" type="button" selector="//ol[@class='items addresses']/li[@class='item'][{{var}}]//a[@class='action delete']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml index db560773a87f6..7a96616885468 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontDeleteCustomerAddressTest.xml @@ -22,7 +22,6 @@ </before> <after> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage stepKey="amOnSignInPage" url="{{StorefrontCustomerSignInPage.url}}"/> <fillField stepKey="fillEmail" userInput="$$createCustomer.email$$" selector="{{StorefrontCustomerSignInFormSection.emailField}}"/> @@ -32,10 +31,10 @@ <argument name="Address" value="US_Address_NY"/> </actionGroup> <see userInput="You saved the address." stepKey="verifyAddressCreated"/> - <click selector="{{StorefrontCustomerAddressSection.deleteAdditionalAddress}}" stepKey="deleteAdditionalAddress"/> - <waitForElementVisible selector="{{StorefrontCustomerAddressConfirmationModalSection.message}}" stepKey="waitFortheConfirmationModal"/> - <see selector="{{StorefrontCustomerAddressConfirmationModalSection.message}}" userInput="Are you sure you want to delete this address?" stepKey="seeAddressDeleteConfirmationMessage"/> - <click selector="{{StorefrontCustomerAddressConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <click selector="{{StorefrontCustomerAddressesSection.deleteAdditionalAddress('1')}}" stepKey="deleteAdditionalAddress"/> + <waitForElementVisible selector="{{ModalConfirmationSection.modalContent}}" stepKey="waitFortheConfirmationModal"/> + <see selector="{{ModalConfirmationSection.modalContent}}" userInput="Are you sure you want to delete this address?" stepKey="seeAddressDeleteConfirmationMessage"/> + <click selector="{{ModalConfirmationSection.OkButton}}" stepKey="confirmDelete"/> <waitForPageLoad stepKey="waitForDeleteToFinish"/> <see userInput="You deleted the address." stepKey="verifyDeleteAddress"/> </test> diff --git a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml index 35ec242f05c52..4bf84d9ee63da 100644 --- a/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml +++ b/app/code/Magento/Ui/Test/Mftf/Section/ModalConfirmationSection.xml @@ -9,6 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="ModalConfirmationSection"> + <element name="modalContent" type="text" selector="aside.confirm div.modal-content"/> <element name="CancelButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-dismiss')]"/> <element name="OkButton" type="button" selector="//footer[@class='modal-footer']/button[contains(@class, 'action-accept')]"/> </section> From 447ad4763d9b614e2e86862f137578a9b1e47637 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Thu, 29 Nov 2018 11:22:47 -0600 Subject: [PATCH 1382/1415] MC-5328: Update tax rate, 100 rate - Fix test to update all fields --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 22 +++++++++++---- .../Mftf/Test/Update100TaxRateEntityTest.xml | 28 +++++++++---------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index de40b448311ac..22eef75989deb 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -10,17 +10,27 @@ <entity name="SimpleTaxRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> </entity> + <entity name="defaultTaxRate" type="taxRate"> + <data key="code" unique="suffix">Tax Rate </data> + <data key="tax_country_id">US</data> + <data key="tax_region_id">12</data> + <data key="tax_postcode">*</data> + <data key="zip_is_range">0</data> + <data key="rate">10</data> + </entity> <entity name="taxRateCustomRateUS" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> <data key="tax_country_id">US</data> + <data key="tax_country">United States</data> <data key="tax_region_id">12</data> + <data key="tax_region">California</data> <data key="tax_postcode">90001</data> <data key="zip_is_range">0</data> - <data key="rate">100</data> + <data key="rate">100.0000</data> </entity> <entity name="defaultTaxRateWithZipRange" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> - <data key="tax_country_id">United States</data> + <data key="tax_country_id">US</data> <data key="tax_region_id">12</data> <data key="zip_is_range">1</data> <data key="zip_from">90001</data> @@ -29,14 +39,14 @@ </entity> <entity name="defaultTaxRateWithLargeRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">United Kingdom</data> + <data key="tax_country_id">GB</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">777</data> </entity> <entity name="taxRateCustomRateCanada" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">Canada</data> + <data key="tax_country_id">CA</data> <data key="tax_region_id">*</data> <data key="tax_postcode">180</data> <data key="zip_is_range">0</data> @@ -44,7 +54,7 @@ </entity> <entity name="taxRateCustomRateUK" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">United Kingdom</data> + <data key="tax_country_id">GB</data> <data key="zip_is_range">1</data> <data key="zip_from">1</data> <data key="zip_to">7800935</data> @@ -52,7 +62,7 @@ </entity> <entity name="taxRateCustomRateFrance" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">France</data> + <data key="tax_country_id">FR</data> <data key="tax_region_id">277</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml index 31c9a017389f4..27a7f2c51724e 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/Update100TaxRateEntityTest.xml @@ -19,27 +19,27 @@ <group value="mtf_migrated"/> </annotations> <before> - <createData entity="taxRateCustomRateUS" stepKey="createTaxRateCustomRateUS"/> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> - <deleteData stepKey="deleteTaxRate" createDataKey="createTaxRateCustomRateUS" /> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> </after> <!-- Search the tax rate on tax grid page --> <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> <waitForPageLoad stepKey="waitForTaxRateIndex1"/> <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> - <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$createTaxRateCustomRateUS.code$$" stepKey="fillCode"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode"/> <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> <!-- Update values on the tax rate form page --> - <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField2"/> - <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="selectCountry1"/> - <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="selectState"/> - <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="90001" stepKey="fillPostCode"/> - <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="100" stepKey="fillRate1"/> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateUS.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateUS.tax_country_id}}" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateUS.tax_region_id}}" stepKey="selectState"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateUS.tax_postcode}}" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateUS.rate}}" stepKey="fillRate1"/> <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> @@ -47,14 +47,14 @@ <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex4"/> <waitForPageLoad stepKey="waitForTaxRateIndex2"/> <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> - <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="fillTaxIdentifierField3"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{taxRateCustomRateUS.code}}" stepKey="fillTaxIdentifierField3"/> <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> <!-- Verify we see updated values on the tax rate form page --> - <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{SimpleTaxRate.code}}" stepKey="seeRTaxIdentifier"/> - <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="United States" stepKey="seeCountry2"/> - <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="California" stepKey="seeState2"/> - <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="90001" stepKey="seeZipCode"/> - <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="100" stepKey="seeRate2"/> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateUS.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateUS.tax_country}}" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateUS.tax_region}}" stepKey="seeState2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateUS.tax_postcode}}" stepKey="seeZipCode"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateUS.rate}}" stepKey="seeRate2"/> </test> </tests> From c25ff0615ff0e072d57ea02b9a5e02a318b693d6 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Thu, 29 Nov 2018 13:27:43 -0600 Subject: [PATCH 1383/1415] MC-5329: Update tax rate, decimal rate --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 33 +--------- .../Tax/Test/Mftf/Metadata/tax_rate-meta.xml | 2 + .../Test/UpdateDecimalTaxRateEntityTest.xml | 64 +++++++++++++++++++ 3 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/UpdateDecimalTaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 22eef75989deb..463aeda5b6cc8 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -31,41 +31,12 @@ <entity name="defaultTaxRateWithZipRange" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> <data key="tax_country_id">US</data> + <data key="tax_country">United States</data> <data key="tax_region_id">12</data> + <data key="tax_region">California</data> <data key="zip_is_range">1</data> <data key="zip_from">90001</data> <data key="zip_to">96162</data> <data key="rate">15.05</data> </entity> - <entity name="defaultTaxRateWithLargeRate" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">GB</data> - <data key="tax_postcode">*</data> - <data key="zip_is_range">0</data> - <data key="rate">777</data> - </entity> - <entity name="taxRateCustomRateCanada" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">CA</data> - <data key="tax_region_id">*</data> - <data key="tax_postcode">180</data> - <data key="zip_is_range">0</data> - <data key="rate">25</data> - </entity> - <entity name="taxRateCustomRateUK" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">GB</data> - <data key="zip_is_range">1</data> - <data key="zip_from">1</data> - <data key="zip_to">7800935</data> - <data key="rate">12.99</data> - </entity> - <entity name="taxRateCustomRateFrance" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">FR</data> - <data key="tax_region_id">277</data> - <data key="tax_postcode">*</data> - <data key="zip_is_range">0</data> - <data key="rate">0.1</data> - </entity> </entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml index 1951ae05831db..3f192920c5cc3 100644 --- a/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml +++ b/app/code/Magento/Tax/Test/Mftf/Metadata/tax_rate-meta.xml @@ -15,6 +15,8 @@ <field key="tax_region_id">integer</field> <field key="tax_postcode">string</field> <field key="zip_is_range">integer</field> + <field key="zip_from">integer</field> + <field key="zip_to">integer</field> <field key="rate">integer</field> <field key="code">string</field> </object> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/UpdateDecimalTaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/UpdateDecimalTaxRateEntityTest.xml new file mode 100644 index 0000000000000..3002452196904 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/UpdateDecimalTaxRateEntityTest.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="UpdateDecimalTaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, decimal rate"/> + <description value="Test log in to Tax Rate and Update Decimal Tax Rate"/> + <testCaseId value="MC-5329"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> + </after> + + <!-- Search the tax rate on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update decimal tax rate on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{defaultTaxRateWithZipRange.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{defaultTaxRateWithZipRange.tax_country_id}}" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="{{defaultTaxRateWithZipRange.tax_region_id}}" stepKey="selectState"/> + <checkOption selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="checkZipRange"/> + <fillField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="{{defaultTaxRateWithZipRange.zip_from}}" stepKey="fillZipFrom"/> + <fillField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="{{defaultTaxRateWithZipRange.zip_to}}" stepKey="fillZipTo"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{defaultTaxRateWithZipRange.rate}}" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated tax rate(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{defaultTaxRateWithZipRange.code}}" stepKey="fillTaxIdentifierField3"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated tax rate on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{defaultTaxRateWithZipRange.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{defaultTaxRateWithZipRange.tax_country}}" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="{{defaultTaxRateWithZipRange.tax_region}}" stepKey="seeState2"/> + <seeCheckboxIsChecked selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="seeZipRange"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="{{defaultTaxRateWithZipRange.zip_from}}" stepKey="seeTaxPostCode2"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="{{defaultTaxRateWithZipRange.zip_to}}" stepKey="seeTaxPostCode3"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{defaultTaxRateWithZipRange.rate}}" stepKey="seeRate2"/> + </test> +</tests> From dba79a1c1097f5c5131d13e7cf229a29a2dd4fd4 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 29 Nov 2018 13:56:52 -0600 Subject: [PATCH 1384/1415] MQE-1187: Fix MFTF skipped tests - Fixed BrainTree test failing to clean up after itself --- .../Test/Mftf/ActionGroup/ConfigureBraintreeActionGroup.xml | 6 +++++- .../Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/ConfigureBraintreeActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/ConfigureBraintreeActionGroup.xml index 27e2039fe526e..9eaae8b33e73f 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/ConfigureBraintreeActionGroup.xml +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/ConfigureBraintreeActionGroup.xml @@ -6,7 +6,7 @@ */ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="ConfigureBraintree"> <!-- GoTo ConfigureBraintree fields --> @@ -46,4 +46,8 @@ <waitForElementVisible selector="{{BraintreeConfiguraionSection.successfulMessage}}" stepKey="waitForSuccessfullyConfigured" time="10"/> </actionGroup> + <actionGroup name="DisableBrainTree"> + <magentoCLI stepKey="disableBrainTree" command="config:set payment/braintree/active 0"/> + <magentoCLI stepKey="disableBrainTreePaypal" command="config:set payment/braintree_paypal/active 0"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml index 35829071407e0..fa1a6b62db8cf 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml @@ -78,6 +78,9 @@ <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="1"/> <after> + <!-- Disable BrainTree--> + <actionGroup ref="DisableBrainTree" stepKey="disableBrainTree"/> + <!--SignOut--> <actionGroup ref="SignOut" stepKey="signOutFromNewUser"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> @@ -95,8 +98,6 @@ <!--Delete Role--> <actionGroup ref="GoToUserRoles" stepKey="GoBackToUserRoles"/> <actionGroup ref="AdminDeleteRoleActionGroup" stepKey="AdminDeleteRoleActionGroup"/> - </after> - </test> </tests> From 1e919a577dd950d8e4d776c050ddbc94e6135492 Mon Sep 17 00:00:00 2001 From: Kajal Solanki <kajal.solanki@krishtechnolabs.com> Date: Fri, 30 Nov 2018 11:41:33 +0530 Subject: [PATCH 1385/1415] solved Customer group textbox-selectbox alignment issue-19472 --- .../Magento/backend/web/css/source/forms/_controls.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less index bb51abaa0f156..f971246ab469d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_controls.less @@ -75,9 +75,9 @@ max-width: 100%; min-width: 8.5rem; - padding-bottom: @field-control__padding-bottom - .1rem; + padding-bottom: @field-control__padding-bottom; padding-right: 4.4rem; // Distance between select switch and inner text - padding-top: @field-control__padding-top - .1rem; + padding-top: @field-control__padding-top; transition: @smooth__border-color; &:hover { From c3f6889257908193cce7051ee908cc6c2c833733 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 30 Nov 2018 11:38:39 +0200 Subject: [PATCH 1386/1415] ENGCOM-3576: Integration test fix. --- .../testsuite/Magento/Email/Model/TemplateTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php index a83de07443e95..7789a79794f39 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php @@ -315,25 +315,25 @@ public function templateDirectiveDataProvider() Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_template"}}', - '<b>customer_create_account_email_template template from Vendor/custom_theme</b>', + '<strong>customer_create_account_email_template template from Vendor/custom_theme</strong>', ], 'Template from parent theme - frontend' => [ Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_confirmation_template"}}', - '<b>customer_create_account_email_confirmation_template template from Vendor/default</b>', + '<strong>customer_create_account_email_confirmation_template template from Vendor/default</strong', ], 'Template from grandparent theme - frontend' => [ Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_confirmed_template"}}', - '<b>customer_create_account_email_confirmed_template template from Magento/default</b>', + '<strong>customer_create_account_email_confirmed_template template from Magento/default</strong', ], 'Template from grandparent theme - adminhtml' => [ BackendFrontNameResolver::AREA_CODE, TemplateTypesInterface::TYPE_HTML, '{{template config_path="catalog/productalert_cron/error_email_template"}}', - '<b>catalog_productalert_cron_error_email_template template from Magento/default</b>', + '<strong>catalog_productalert_cron_error_email_template template from Magento/default</strong', null, null, true, From ca0da34ee2691bfaca1c74d94a0db33377d4e54c Mon Sep 17 00:00:00 2001 From: GovindaSharma <govindpokhrelsharma@cedcoss.com> Date: Mon, 26 Nov 2018 16:55:35 +0530 Subject: [PATCH 1387/1415] Fixed issue related to 'product_attribute' attribute. Added condition for validating product attribute. --- .../Catalog/Controller/Adminhtml/Product/Attribute/Validate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 8a9d0c9b612cb..381ca5d08d82a 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -105,7 +105,7 @@ public function execute() $attributeCode ); - if ($attribute->getId() && !$attributeId) { + if ($attribute->getId() && !$attributeId || $attributeCode === 'product_type') { $message = strlen($this->getRequest()->getParam('attribute_code')) ? __('An attribute with this code already exists.') : __('An attribute with the same code (%1) already exists.', $attributeCode); From 6475ef2cebde6321ab8ddb6a5234d99a2fb491ad Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 30 Nov 2018 14:42:52 +0200 Subject: [PATCH 1388/1415] ENGCOM-3594: Static test fix. --- .../Magento/Sales/Model/Order/Invoice.php | 107 ++++++++++-------- 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php index e0cd96cd54d8c..14dd0b14ac1f3 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Order/Invoice.php @@ -11,6 +11,8 @@ use Magento\Sales\Model\EntityInterface; /** + * Invoice model. + * * @api * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value) * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value) @@ -504,6 +506,8 @@ public function getItemsCollection() } /** + * Get all Invoice Items. + * * @return array */ public function getAllItems() @@ -518,6 +522,8 @@ public function getAllItems() } /** + * Get Invoice Item by id. + * * @param int|string $itemId * @return bool|\Magento\Sales\Model\Order\Invoice\Item */ @@ -532,8 +538,11 @@ public function getItemById($itemId) } /** + * Add Item to Invoice. + * * @param \Magento\Sales\Model\Order\Invoice\Item $item * @return $this + * @throws \Exception */ public function addItem(\Magento\Sales\Model\Order\Invoice\Item $item) { @@ -678,13 +687,13 @@ public function isLast() } /** - * Adds comment to invoice with additional possibility to send it to customer via email - * and show it in customer account + * Add comment with possibility to send it to customer via email and show it in customer account. * * @param string $comment * @param bool $notify * @param bool $visibleOnFront * @return $this + * @throws \Exception */ public function addComment($comment, $notify = false, $visibleOnFront = false) { @@ -706,6 +715,8 @@ public function addComment($comment, $notify = false, $visibleOnFront = false) } /** + * Get Invoice comments. + * * @param bool $reload * @return \Magento\Sales\Model\ResourceModel\Order\Invoice\Comment\Collection */ @@ -835,7 +846,7 @@ public function getDiscountDescription() } /** - * {@inheritdoc} + * @inheritdoc */ public function setItems($items) { @@ -1003,7 +1014,7 @@ public function getCreatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCreatedAt($createdAt) { @@ -1262,7 +1273,7 @@ public function getUpdatedAt() } /** - * {@inheritdoc} + * @inheritdoc */ public function setComments($comments) { @@ -1270,7 +1281,7 @@ public function setComments($comments) } /** - * {@inheritdoc} + * @inheritdoc */ public function setUpdatedAt($timestamp) { @@ -1278,7 +1289,7 @@ public function setUpdatedAt($timestamp) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreId($id) { @@ -1286,7 +1297,7 @@ public function setStoreId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseGrandTotal($amount) { @@ -1294,7 +1305,7 @@ public function setBaseGrandTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingTaxAmount($amount) { @@ -1302,7 +1313,7 @@ public function setShippingTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTaxAmount($amount) { @@ -1310,7 +1321,7 @@ public function setTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTaxAmount($amount) { @@ -1318,7 +1329,7 @@ public function setBaseTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreToOrderRate($rate) { @@ -1326,7 +1337,7 @@ public function setStoreToOrderRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingTaxAmount($amount) { @@ -1334,7 +1345,7 @@ public function setBaseShippingTaxAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountAmount($amount) { @@ -1342,7 +1353,7 @@ public function setBaseDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseToOrderRate($rate) { @@ -1350,7 +1361,7 @@ public function setBaseToOrderRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGrandTotal($amount) { @@ -1358,7 +1369,7 @@ public function setGrandTotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingAmount($amount) { @@ -1366,7 +1377,7 @@ public function setShippingAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSubtotalInclTax($amount) { @@ -1374,7 +1385,7 @@ public function setSubtotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseSubtotalInclTax($amount) { @@ -1382,7 +1393,7 @@ public function setBaseSubtotalInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreToBaseRate($rate) { @@ -1390,7 +1401,7 @@ public function setStoreToBaseRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingAmount($amount) { @@ -1398,7 +1409,7 @@ public function setBaseShippingAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTotalQty($qty) { @@ -1406,7 +1417,7 @@ public function setTotalQty($qty) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseToGlobalRate($rate) { @@ -1414,7 +1425,7 @@ public function setBaseToGlobalRate($rate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSubtotal($amount) { @@ -1422,7 +1433,7 @@ public function setSubtotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseSubtotal($amount) { @@ -1430,7 +1441,7 @@ public function setBaseSubtotal($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountAmount($amount) { @@ -1438,7 +1449,7 @@ public function setDiscountAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBillingAddressId($id) { @@ -1446,7 +1457,7 @@ public function setBillingAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setIsUsedForRefund($isUsedForRefund) { @@ -1454,7 +1465,7 @@ public function setIsUsedForRefund($isUsedForRefund) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOrderId($id) { @@ -1462,7 +1473,7 @@ public function setOrderId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmailSent($emailSent) { @@ -1470,7 +1481,7 @@ public function setEmailSent($emailSent) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCanVoidFlag($canVoidFlag) { @@ -1478,7 +1489,7 @@ public function setCanVoidFlag($canVoidFlag) } /** - * {@inheritdoc} + * @inheritdoc */ public function setState($state) { @@ -1486,7 +1497,7 @@ public function setState($state) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingAddressId($id) { @@ -1494,7 +1505,7 @@ public function setShippingAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStoreCurrencyCode($code) { @@ -1502,7 +1513,7 @@ public function setStoreCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setOrderCurrencyCode($code) { @@ -1510,7 +1521,7 @@ public function setOrderCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseCurrencyCode($code) { @@ -1518,7 +1529,7 @@ public function setBaseCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setGlobalCurrencyCode($code) { @@ -1526,7 +1537,7 @@ public function setGlobalCurrencyCode($code) } /** - * {@inheritdoc} + * @inheritdoc */ public function setIncrementId($id) { @@ -1534,7 +1545,7 @@ public function setIncrementId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountTaxCompensationAmount($amount) { @@ -1542,7 +1553,7 @@ public function setDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseDiscountTaxCompensationAmount($amount) { @@ -1550,7 +1561,7 @@ public function setBaseDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingDiscountTaxCompensationAmount($amount) { @@ -1558,7 +1569,7 @@ public function setShippingDiscountTaxCompensationAmount($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) { @@ -1566,7 +1577,7 @@ public function setBaseShippingDiscountTaxCompensationAmnt($amnt) } /** - * {@inheritdoc} + * @inheritdoc */ public function setShippingInclTax($amount) { @@ -1574,7 +1585,7 @@ public function setShippingInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseShippingInclTax($amount) { @@ -1582,7 +1593,7 @@ public function setBaseShippingInclTax($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setBaseTotalRefunded($amount) { @@ -1590,7 +1601,7 @@ public function setBaseTotalRefunded($amount) } /** - * {@inheritdoc} + * @inheritdoc */ public function setDiscountDescription($description) { @@ -1598,7 +1609,7 @@ public function setDiscountDescription($description) } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Sales\Api\Data\InvoiceExtensionInterface|null */ @@ -1608,7 +1619,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Sales\Api\Data\InvoiceExtensionInterface $extensionAttributes * @return $this From 8e8aa0db64b4d48f4875684890ab9600887cfff7 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Fri, 30 Nov 2018 09:06:05 -0600 Subject: [PATCH 1389/1415] MC-5330: Update tax rate, large rate --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 25 +------- .../Test/UpdateLargeTaxRateEntityTest.xml | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/UpdateLargeTaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 22eef75989deb..a42579763e1ce 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -40,32 +40,9 @@ <entity name="defaultTaxRateWithLargeRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">777</data> </entity> - <entity name="taxRateCustomRateCanada" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">CA</data> - <data key="tax_region_id">*</data> - <data key="tax_postcode">180</data> - <data key="zip_is_range">0</data> - <data key="rate">25</data> - </entity> - <entity name="taxRateCustomRateUK" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">GB</data> - <data key="zip_is_range">1</data> - <data key="zip_from">1</data> - <data key="zip_to">7800935</data> - <data key="rate">12.99</data> - </entity> - <entity name="taxRateCustomRateFrance" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">FR</data> - <data key="tax_region_id">277</data> - <data key="tax_postcode">*</data> - <data key="zip_is_range">0</data> - <data key="rate">0.1</data> - </entity> </entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/UpdateLargeTaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/UpdateLargeTaxRateEntityTest.xml new file mode 100644 index 0000000000000..6c81a6aeb3f11 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/UpdateLargeTaxRateEntityTest.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="UpdateLargeTaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, large rate"/> + <description value="Test log in to Tax Rate and Update Large Rate"/> + <testCaseId value="MC-5330"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> + </after> + + <!-- Search the tax rate on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update large tax rate on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{defaultTaxRateWithLargeRate.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{defaultTaxRateWithLargeRate.tax_country_id}}" stepKey="selectCountry1"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{defaultTaxRateWithLargeRate.tax_postcode}}" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{defaultTaxRateWithLargeRate.rate}}" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated large tax rate(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex4"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{defaultTaxRateWithLargeRate.code}}" stepKey="fillTaxIdentifierField3"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated large tax rate on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{defaultTaxRateWithLargeRate.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{defaultTaxRateWithLargeRate.tax_country}}" stepKey="seeCountry2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{defaultTaxRateWithLargeRate.tax_postcode}}" stepKey="seeZipCode"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{defaultTaxRateWithLargeRate.rate}}" stepKey="seeRate2"/> + </test> +</tests> From fe7ab8cfb177065cf697e60dede502dc75cd27d5 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 29 Nov 2018 20:20:58 -0600 Subject: [PATCH 1390/1415] MC-5596: Comments are not being added in Credit memo emails --- app/code/Magento/Sales/Model/Order/Creditmemo.php | 6 +++--- .../Magento/Sales/Model/Order/CreditmemoDocumentFactory.php | 4 ++++ .../Test/Unit/Model/Order/CreditmemoDocumentFactoryTest.php | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index 20cec81240262..cba45be6dfb35 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -19,10 +19,10 @@ * Order creditmemo model * * @api - * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value) - * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value) + * @method \Magento\Sales\Model\Order\Creditmemo setSendEmail(bool $value) + * @method \Magento\Sales\Model\Order\Creditmemo setCustomerNote(string $value) * @method string getCustomerNote() - * @method \Magento\Sales\Model\Order\Invoice setCustomerNoteNotify(bool $value) + * @method \Magento\Sales\Model\Order\Creditmemo setCustomerNoteNotify(bool $value) * @method bool getCustomerNoteNotify() * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php index 65c1788c68d0b..6939988ba3d6c 100644 --- a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php @@ -99,11 +99,13 @@ private function attachComment( ->setCreditmemo($creditmemo) ->setIsCustomerNotified($appendComment); $creditmemo->setComments([$comment]); + $creditmemo->setCustomerNote($comment->getComment()); return $creditmemo; } /** * Create new Creditmemo + * * @param \Magento\Sales\Api\Data\OrderInterface $order * @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment @@ -128,6 +130,8 @@ public function createFromOrder( } /** + * Create credit memo from invoice + * * @param \Magento\Sales\Api\Data\InvoiceInterface $invoice * @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoDocumentFactoryTest.php index cb65b70b82718..dc18306942770 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoDocumentFactoryTest.php @@ -12,7 +12,6 @@ use Magento\Sales\Api\Data\CreditmemoCommentInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Invoice; -use Magento\Sales\Api\Data\CreditmemoInterface; use Magento\Sales\Api\Data\CreditmemoItemCreationInterface; use Magento\Sales\Api\Data\CreditmemoCommentCreationInterface; use Magento\Framework\EntityManager\HydratorPool; @@ -82,7 +81,7 @@ class CreditmemoDocumentFactoryTest extends \PHPUnit\Framework\TestCase private $commentCreationArgumentsMock; /** - * @var CreditmemoInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Order\Creditmemo|\PHPUnit_Framework_MockObject_MockObject */ private $creditmemoMock; @@ -121,7 +120,7 @@ public function setUp() $this->creditmemoItemCreationMock = $this->getMockBuilder(CreditmemoItemCreationInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class) + $this->creditmemoMock = $this->getMockBuilder(Order\Creditmemo::class) ->disableOriginalConstructor() ->getMock(); $this->hydratorMock = $this->getMockBuilder(HydratorInterface::class) From 897ef9490372901c67c327436ab592117067fd69 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Fri, 30 Nov 2018 10:21:34 -0600 Subject: [PATCH 1391/1415] MC-5331: Update tax rate, any region --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 20 ++----- .../Test/UpdateAnyRegionTaxRateEntityTest.xml | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/UpdateAnyRegionTaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 22eef75989deb..893a08faeaf30 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -31,7 +31,9 @@ <entity name="defaultTaxRateWithZipRange" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> <data key="tax_country_id">US</data> + <data key="tax_country">United States</data> <data key="tax_region_id">12</data> + <data key="tax_region">California</data> <data key="zip_is_range">1</data> <data key="zip_from">90001</data> <data key="zip_to">96162</data> @@ -40,6 +42,7 @@ <entity name="defaultTaxRateWithLargeRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">777</data> @@ -47,25 +50,10 @@ <entity name="taxRateCustomRateCanada" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">CA</data> + <data key="tax_country">Canada</data> <data key="tax_region_id">*</data> <data key="tax_postcode">180</data> <data key="zip_is_range">0</data> <data key="rate">25</data> </entity> - <entity name="taxRateCustomRateUK" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">GB</data> - <data key="zip_is_range">1</data> - <data key="zip_from">1</data> - <data key="zip_to">7800935</data> - <data key="rate">12.99</data> - </entity> - <entity name="taxRateCustomRateFrance" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">FR</data> - <data key="tax_region_id">277</data> - <data key="tax_postcode">*</data> - <data key="zip_is_range">0</data> - <data key="rate">0.1</data> - </entity> </entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/UpdateAnyRegionTaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/UpdateAnyRegionTaxRateEntityTest.xml new file mode 100644 index 0000000000000..d7b25da6c14ae --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/UpdateAnyRegionTaxRateEntityTest.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="UpdateAnyRegionTaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, any region"/> + <description value="Test log in to Tax Rate and Update Any Region"/> + <testCaseId value="MC-5331"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> + </after> + + <!-- Search the tax rate on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update any region tax rate on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateCanada.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateCanada.tax_country_id}}" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateCanada.tax_region_id}}" stepKey="selectState"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateCanada.tax_postcode}}" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateCanada.rate}}" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated any region tax rate(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{taxRateCustomRateCanada.code}}" stepKey="fillTaxIdentifierField3"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated any region tax rate on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateCanada.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateCanada.tax_country}}" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateCanada.tax_region_id}}" stepKey="seeState2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateCanada.tax_postcode}}" stepKey="seeZipCode"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateCanada.rate}}" stepKey="seeRate2"/> + </test> +</tests> From 0b8c7e9d014f0117ac48335f33ef87159321b0f2 Mon Sep 17 00:00:00 2001 From: Devagouda Patil <depatil@ip-192-168-0-5.ec2.internal> Date: Fri, 30 Nov 2018 11:44:10 -0600 Subject: [PATCH 1392/1415] MAGETWO-95934: Can't upload Watermark Image - Added zephyr testcase reference --- .../Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml index 046f8c405dfdf..a667f40ad327f 100644 --- a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml +++ b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml @@ -15,7 +15,7 @@ <title value="MAGETWO-95934: Can't upload Watermark Image"/> <description value="Watermark images should be able to be uploaded in the admin"/> <severity value="MAJOR"/> - <testCaseId value="MAGETWO-95934"/> + <testCaseId value="MC-5796"/> <group value="Watermark"/> </annotations> <before> From 9f790d3ae117ce0cb8eaa8a51b5165f8356f0730 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 30 Nov 2018 12:10:17 -0600 Subject: [PATCH 1393/1415] MC-5574: Flaky MFTF Tests - fix EndToEndB2CGuestUserTest --- .../Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 0499a57a9211a..72c5648991ef5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -90,7 +90,7 @@ <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectShippingMethod"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> <see userInput="({{shippingMethod}})" selector="{{CheckoutCartSummarySection.shippingMethod}}" stepKey="assertShippingMethod"/> - <waitForText userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" time="30" stepKey="assertShipping"/> + <waitForText userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" time="45" stepKey="assertShipping"/> <see userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" stepKey="assertTotal"/> </actionGroup> From bf864f69ff80deb2b462997cd8ea9d406ba85823 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 30 Nov 2018 14:07:35 -0600 Subject: [PATCH 1394/1415] MQE-1187: Fix MFTF skipped tests - added whitespace to comment formatting --- .../Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml index fa1a6b62db8cf..2ddefa40b536c 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest1.xml @@ -78,7 +78,7 @@ <waitForElementVisible selector="{{NewOrderSection.successMessage}}" stepKey="waitForSuccessMessage" time="1"/> <after> - <!-- Disable BrainTree--> + <!-- Disable BrainTree --> <actionGroup ref="DisableBrainTree" stepKey="disableBrainTree"/> <!--SignOut--> From 1252948442421ffc28084ebf443058ea68711c9e Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Fri, 30 Nov 2018 14:39:32 -0600 Subject: [PATCH 1395/1415] MC-5332: Update tax rate, 12.99 rate --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 13 ++-- .../Mftf/Test/Update1299TaxRateEntityTest.xml | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/Update1299TaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 22eef75989deb..6c0ffa08bbf2e 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -31,7 +31,9 @@ <entity name="defaultTaxRateWithZipRange" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> <data key="tax_country_id">US</data> + <data key="tax_country">United States</data> <data key="tax_region_id">12</data> + <data key="tax_region">California</data> <data key="zip_is_range">1</data> <data key="zip_from">90001</data> <data key="zip_to">96162</data> @@ -40,6 +42,7 @@ <entity name="defaultTaxRateWithLargeRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">777</data> @@ -47,6 +50,7 @@ <entity name="taxRateCustomRateCanada" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">CA</data> + <data key="tax_country">Canada</data> <data key="tax_region_id">*</data> <data key="tax_postcode">180</data> <data key="zip_is_range">0</data> @@ -55,17 +59,10 @@ <entity name="taxRateCustomRateUK" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="zip_is_range">1</data> <data key="zip_from">1</data> <data key="zip_to">7800935</data> <data key="rate">12.99</data> </entity> - <entity name="taxRateCustomRateFrance" type="taxRate"> - <data key="code" unique="suffix">TaxRate</data> - <data key="tax_country_id">FR</data> - <data key="tax_region_id">277</data> - <data key="tax_postcode">*</data> - <data key="zip_is_range">0</data> - <data key="rate">0.1</data> - </entity> </entities> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/Update1299TaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/Update1299TaxRateEntityTest.xml new file mode 100644 index 0000000000000..aa46a5fdae0e1 --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/Update1299TaxRateEntityTest.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="Update1299TaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, 12.99 rate"/> + <description value="Test log in to Tax Rate and Update 12.99 Rate"/> + <testCaseId value="MC-5332"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> + </after> + + <!-- Search the tax identifier on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode1"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update 12.99 tax rate on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateUK.code}}" stepKey="fillTaxIdentifierField1"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateUK.tax_country_id}}" stepKey="selectCountry1"/> + <checkOption selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="checkZipRange"/> + <fillField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="{{taxRateCustomRateUK.zip_from}}" stepKey="fillZipFrom"/> + <fillField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="{{taxRateCustomRateUK.zip_to}}" stepKey="fillZipTo"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateUK.rate}}" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated tax rate(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex2"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{taxRateCustomRateUK.code}}" stepKey="fillTaxIdentifierField2"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated tax rate on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateUK.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateUK.tax_country}}" stepKey="seeCountry2"/> + <seeCheckboxIsChecked selector="{{AdminTaxRateFormSection.zipRange}}" stepKey="seeZipRange"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeFrom}}" userInput="{{taxRateCustomRateUK.zip_from}}" stepKey="seeZipFrom"/> + <seeInField selector="{{AdminTaxRateFormSection.rangeTo}}" userInput="{{taxRateCustomRateUK.zip_to}}" stepKey="seeZipTo"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateUK.rate}}" stepKey="seeRate"/> + </test> +</tests> From 96ca4d7bc4e75e62dc332c77d90c40b545ccd725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20S=C5=82awik?= <maciej.slawik@lizardmedia.pl> Date: Thu, 22 Nov 2018 16:22:53 +0100 Subject: [PATCH 1396/1415] Framework Escaper - remove direct Object Manager usage --- lib/internal/Magento/Framework/Escaper.php | 55 +++++++------------ .../Filter/Test/Unit/StripTagsTest.php | 3 +- .../Framework/Test/Unit/EscaperTest.php | 5 +- .../Magento/Framework/Test/Unit/UrlTest.php | 2 +- 4 files changed, 24 insertions(+), 41 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 80979c3db0910..2e7c41c5256c0 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -46,6 +46,21 @@ class Escaper */ private $escapeAsUrlAttributes = ['href']; + /** + * Escaper constructor. + * @param \Magento\Framework\ZendEscaper|null $escaper + * @param \Psr\Log\LoggerInterface|null $logger + */ + public function __construct( + \Magento\Framework\ZendEscaper $escaper = null, + \Psr\Log\LoggerInterface $logger = null + ) { + $this->escaper = $escaper ?? \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\ZendEscaper::class); + $this->logger = $logger ?? \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Psr\Log\LoggerInterface::class); + } + /** * Escape string for HTML context. * @@ -84,7 +99,7 @@ function ($errorNumber, $errorString) { ); } catch (\Exception $e) { restore_error_handler(); - $this->getLogger()->critical($e); + $this->logger->critical($e); } restore_error_handler(); @@ -201,7 +216,7 @@ private function escapeAttributeValue($name, $value) public function escapeHtmlAttr($string, $escapeSingleQuote = true) { if ($escapeSingleQuote) { - return $this->getEscaper()->escapeHtmlAttr((string) $string); + return $this->escaper->escapeHtmlAttr((string) $string); } return htmlspecialchars((string)$string, ENT_COMPAT, 'UTF-8', false); } @@ -226,7 +241,7 @@ public function escapeUrl($string) */ public function encodeUrlParam($string) { - return $this->getEscaper()->escapeUrl($string); + return $this->escaper->escapeUrl($string); } /** @@ -265,7 +280,7 @@ function ($matches) { */ public function escapeCss($string) { - return $this->getEscaper()->escapeCss($string); + return $this->escaper->escapeCss($string); } /** @@ -340,36 +355,6 @@ public function escapeQuote($data, $addSlashes = false) return htmlspecialchars($data, ENT_QUOTES, null, false); } - /** - * Get escaper - * - * @return \Magento\Framework\ZendEscaper - * @deprecated 100.2.0 - */ - private function getEscaper() - { - if ($this->escaper == null) { - $this->escaper = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\ZendEscaper::class); - } - return $this->escaper; - } - - /** - * Get logger - * - * @return \Psr\Log\LoggerInterface - * @deprecated 100.2.0 - */ - private function getLogger() - { - if ($this->logger == null) { - $this->logger = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Psr\Log\LoggerInterface::class); - } - return $this->logger; - } - /** * Filter prohibited tags. * @@ -384,7 +369,7 @@ private function filterProhibitedTags(array $allowedTags): array ); if (!empty($notAllowedTags)) { - $this->getLogger()->critical( + $this->logger->critical( 'The following tag(s) are not allowed: ' . implode(', ', $notAllowedTags) ); $allowedTags = array_diff($allowedTags, $this->notAllowedTags); diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/StripTagsTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/StripTagsTest.php index 2c42eb3d1c8db..f0dc0d9bd7874 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/StripTagsTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/StripTagsTest.php @@ -12,7 +12,8 @@ class StripTagsTest extends \PHPUnit\Framework\TestCase */ public function testStripTags() { - $stripTags = new \Magento\Framework\Filter\StripTags(new \Magento\Framework\Escaper()); + $escaper = $this->createMock(\Magento\Framework\Escaper::class); + $stripTags = new \Magento\Framework\Filter\StripTags($escaper); $this->assertEquals('three', $stripTags->filter('<two>three</two>')); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index ec05478b90db9..30d373822de57 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -30,12 +30,9 @@ class EscaperTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->escaper = new Escaper(); $this->zendEscaper = new \Magento\Framework\ZendEscaper(); $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); - $objectManagerHelper = new ObjectManager($this); - $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'escaper', $this->zendEscaper); - $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'logger', $this->loggerMock); + $this->escaper = new Escaper($this->zendEscaper, $this->loggerMock); } /** diff --git a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php index 3713978d0f74e..c6a0aa8a00a26 100644 --- a/lib/internal/Magento/Framework/Test/Unit/UrlTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/UrlTest.php @@ -141,7 +141,7 @@ protected function getUrlModel($arguments = []) $modelProperty->setValue($model, $this->urlModifier); $zendEscaper = new \Magento\Framework\ZendEscaper(); - $escaper = new \Magento\Framework\Escaper(); + $escaper = $objectManager->getObject(\Magento\Framework\Escaper::class); $objectManager->setBackwardCompatibleProperty($escaper, 'escaper', $zendEscaper); $objectManager->setBackwardCompatibleProperty($model, 'escaper', $escaper); From 4d0efab39fd1fae43c10d1afc5c5aa143fa143d5 Mon Sep 17 00:00:00 2001 From: sathakur <sathakur@adobe.com> Date: Mon, 3 Dec 2018 09:15:03 -0600 Subject: [PATCH 1397/1415] MC-5333: Update tax rate, 0.1 rate --- .../Tax/Test/Mftf/Data/TaxRateData.xml | 7 +++ .../Mftf/Test/Update01TaxRateEntityTest.xml | 60 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 app/code/Magento/Tax/Test/Mftf/Test/Update01TaxRateEntityTest.xml diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml index 22eef75989deb..666ced6d0ab22 100644 --- a/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml +++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxRateData.xml @@ -31,7 +31,9 @@ <entity name="defaultTaxRateWithZipRange" type="taxRate"> <data key="code" unique="suffix">Tax Rate </data> <data key="tax_country_id">US</data> + <data key="tax_country">United States</data> <data key="tax_region_id">12</data> + <data key="tax_region">California</data> <data key="zip_is_range">1</data> <data key="zip_from">90001</data> <data key="zip_to">96162</data> @@ -40,6 +42,7 @@ <entity name="defaultTaxRateWithLargeRate" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">777</data> @@ -47,6 +50,7 @@ <entity name="taxRateCustomRateCanada" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">CA</data> + <data key="tax_country">Canada</data> <data key="tax_region_id">*</data> <data key="tax_postcode">180</data> <data key="zip_is_range">0</data> @@ -55,6 +59,7 @@ <entity name="taxRateCustomRateUK" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">GB</data> + <data key="tax_country">United Kingdom</data> <data key="zip_is_range">1</data> <data key="zip_from">1</data> <data key="zip_to">7800935</data> @@ -63,7 +68,9 @@ <entity name="taxRateCustomRateFrance" type="taxRate"> <data key="code" unique="suffix">TaxRate</data> <data key="tax_country_id">FR</data> + <data key="tax_country">France</data> <data key="tax_region_id">277</data> + <data key="tax_region">Val-d'Oise</data> <data key="tax_postcode">*</data> <data key="zip_is_range">0</data> <data key="rate">0.1</data> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/Update01TaxRateEntityTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/Update01TaxRateEntityTest.xml new file mode 100644 index 0000000000000..433e390d776de --- /dev/null +++ b/app/code/Magento/Tax/Test/Mftf/Test/Update01TaxRateEntityTest.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="Update01TaxRateEntityTest"> + <annotations> + <stories value="Update Tax Rate"/> + <title value="Update tax rate, 0.1 rate"/> + <description value="Test log in to Tax Rate and Update 0.1 Rate"/> + <testCaseId value="MC-5333"/> + <severity value="CRITICAL"/> + <group value="tax"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultTaxRate" stepKey="initialTaxRate"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData stepKey="deleteTaxRate" createDataKey="initialTaxRate" /> + </after> + + <!-- Search the tax rate on tax grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex1"/> + <waitForPageLoad stepKey="waitForTaxRateIndex1"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters1"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="$$initialTaxRate.code$$" stepKey="fillCode"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch1"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow1"/> + + <!-- Update 0.1 tax rate on the tax rate form page --> + <fillField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateFrance.code}}" stepKey="fillTaxIdentifierField2"/> + <selectOption selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateFrance.tax_country_id}}" stepKey="selectCountry1"/> + <selectOption selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateFrance.tax_region_id}}" stepKey="selectState"/> + <fillField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateFrance.tax_postcode}}" stepKey="fillPostCode"/> + <fillField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateFrance.rate}}" stepKey="fillRate1"/> + <click selector="{{AdminTaxRateFormSection.save}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rate." stepKey="seeSuccess"/> + + <!-- Verify we see updated 0.1 tax rate(from the above step) on the tax rate grid page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRateIndex4"/> + <waitForPageLoad stepKey="waitForTaxRateIndex2"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickClearFilters2"/> + <fillField selector="{{AdminTaxRateGridSection.filterByTaxIdentifier}}" userInput="{{taxRateCustomRateFrance.code}}" stepKey="fillTaxIdentifierField3"/> + <click selector="{{AdminTaxRateGridSection.search}}" stepKey="clickSearch2"/> + <click selector="{{AdminTaxRateGridSection.nthRow('1')}}" stepKey="clickFirstRow2"/> + <!-- Verify we see updated 0.1 tax rate on the tax rate form page --> + <seeInField selector="{{AdminTaxRateFormSection.taxIdentifier}}" userInput="{{taxRateCustomRateFrance.code}}" stepKey="seeRTaxIdentifier"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.country}}" userInput="{{taxRateCustomRateFrance.tax_country}}" stepKey="seeCountry2"/> + <seeOptionIsSelected selector="{{AdminTaxRateFormSection.state}}" userInput="{{taxRateCustomRateFrance.tax_region}}" stepKey="seeState2"/> + <seeInField selector="{{AdminTaxRateFormSection.zipCode}}" userInput="{{taxRateCustomRateFrance.tax_postcode}}" stepKey="seeZipCode"/> + <seeInField selector="{{AdminTaxRateFormSection.rate}}" userInput="{{taxRateCustomRateFrance.rate}}" stepKey="seeRate2"/> + </test> +</tests> From 2e3b28a8797dc250a3267569cb1dc0d2b277ea72 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 3 Dec 2018 11:12:49 -0600 Subject: [PATCH 1398/1415] MAGETWO-96656: Failed funtional test Magento\FunctionalTestingFramework.functional.CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest - Unskip test --- ...tomerGroupMembershipArePersistedUnderLongTermCookieTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml index 8d766f4daab99..2e09ee7134733 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69455"/> <group value="persistent"/> - <skip> - <issueId value="MAGETWO-96656"/> - </skip> </annotations> <before> <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> From 6f30fbaee8d97937483b0cfa7bdc19130436a33b Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 3 Dec 2018 11:24:29 -0600 Subject: [PATCH 1399/1415] MAGETWO-95212: Dynamic block call to getCurrentUrl method is returning ajax request value - Fixed new static test error- --- app/code/Magento/CatalogWidget/Block/Product/ProductsList.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 851f9e3fc5e94..2b95de24d0201 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -163,6 +163,7 @@ protected function _construct() * Get key pieces for caching block content * * @return array + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getCacheKeyInfo() { @@ -240,6 +241,7 @@ protected function _beforeToHtml() * Prepare and return product collection * * @return \Magento\Catalog\Model\ResourceModel\Product\Collection + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function createCollection() { From d35309fd3744361ec6daef399e7997d07560d217 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 3 Dec 2018 11:46:06 -0600 Subject: [PATCH 1400/1415] MAGETWO-96223: MFTF Test Failure AdminConfigurationIndustryTest - Unskipped test --- .../Test/Mftf/Test/AdminConfigurationIndustryTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index 624aa952fbce9..bb682c4468012 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -17,9 +17,6 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-63898"/> <group value="analytics"/> - <skip> - <issueId value="MAGETWO-96223"/> - </skip> </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> From 68754f253fdb05a7415fc3be7fccc26834a8300e Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 4 Dec 2018 11:54:07 -0600 Subject: [PATCH 1401/1415] MAGETWO-96266: Magento\FunctionalTestingFramework.functional.StorefrontTaxQuoteCartGuestSimple randomly fails - unskip test --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 73e018ec83161..7263db10073e0 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -251,9 +251,6 @@ <severity value="CRITICAL"/> <testCaseId value="MC-297"/> <group value="Tax"/> - <skip> - <issueId value="MAGETWO-96266"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From ecaf14ed313708eb62e2a1322de5d0910756ed94 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Tue, 4 Dec 2018 12:06:33 -0600 Subject: [PATCH 1402/1415] MC-5574: Unskipping MFTF Test - unskip test --- .../Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml | 3 --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 --- .../Test/AdminRemoveDefaultVideoDownloadableProductTest.xml | 3 --- .../Tinymce3/Test/Mftf/Test/AdminSwitchWYSIWYGOptionsTest.xml | 3 --- 4 files changed, 12 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml index d38a8e4190c82..03f3e93bb30ec 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -16,9 +16,6 @@ <description value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84375"/> - <skip> - <issueId value="MAGETWO-94438"/> - </skip> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 4b3d5c9258785..11bf03c1d5ee9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,9 +17,6 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> - <skip> - <issueId value="MC-5371" /> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml index 83d859ee7421a..d8bbbb2b4d62b 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml @@ -17,9 +17,6 @@ <severity value="MAJOR"/> <testCaseId value="MC-207"/> <group value="Downloadable"/> - <skip> - <issueId value="MAGETWO-94795"/> - </skip> </annotations> <!-- Create a downloadable product --> diff --git a/app/code/Magento/Tinymce3/Test/Mftf/Test/AdminSwitchWYSIWYGOptionsTest.xml b/app/code/Magento/Tinymce3/Test/Mftf/Test/AdminSwitchWYSIWYGOptionsTest.xml index ed3eea30c8b45..02b8d3686fd68 100644 --- a/app/code/Magento/Tinymce3/Test/Mftf/Test/AdminSwitchWYSIWYGOptionsTest.xml +++ b/app/code/Magento/Tinymce3/Test/Mftf/Test/AdminSwitchWYSIWYGOptionsTest.xml @@ -17,9 +17,6 @@ <description value="Admin should able to switch between versions of TinyMCE"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-82936"/> - <skip> - <issueId value="MAGETWO-89417"/> - </skip> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> From aa8101543e49147a7e3e9df39479a31ccfb04f37 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Tue, 4 Dec 2018 14:01:46 -0600 Subject: [PATCH 1403/1415] Fixed static test failure --- lib/internal/Magento/Framework/Model/AbstractModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php index 1c3e67281c192..567d174938b11 100644 --- a/lib/internal/Magento/Framework/Model/AbstractModel.php +++ b/lib/internal/Magento/Framework/Model/AbstractModel.php @@ -778,7 +778,7 @@ protected function _getValidationRulesBeforeSave() /** * Get list of cache tags applied to model object. - * + * * Return false if cache tags are not supported by model * * @return array|false From 31e8a66fbc78d5394d1bddec22adf14ddce7cc8e Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Wed, 5 Dec 2018 13:15:28 +0200 Subject: [PATCH 1404/1415] Fix integration test. --- .../testsuite/Magento/Email/Model/Template/FilterTest.php | 8 ++++---- .../testsuite/Magento/Email/Model/TemplateTest.php | 8 ++++---- setup/view/magento/setup/extension-grid.phtml | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php index a68b0942ec090..dd55dcc8b47c7 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php @@ -130,22 +130,22 @@ public function layoutDirectiveDataProvider() 'area parameter - omitted' => [ 'adminhtml', 'handle="email_template_test_handle"', - '<b>Email content for frontend/Magento/default theme</b>', + '<strong>Email content for frontend/Magento/default theme</strong>', ], 'area parameter - frontend' => [ 'adminhtml', 'handle="email_template_test_handle" area="frontend"', - '<b>Email content for frontend/Magento/default theme</b>', + '<strong>Email content for frontend/Magento/default theme</strong>', ], 'area parameter - backend' => [ 'frontend', 'handle="email_template_test_handle" area="adminhtml"', - '<b>Email content for adminhtml/Magento/default theme</b>', + '<strong>Email content for adminhtml/Magento/default theme</strong>', ], 'custom parameter' => [ 'frontend', 'handle="email_template_test_handle" template="Magento_Email::sample_email_content_custom.phtml"', - '<b>Custom Email content for frontend/Magento/default theme</b>', + '<strong>Custom Email content for frontend/Magento/default theme</strong>', ], ]; return $result; diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php index a83de07443e95..7789a79794f39 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php @@ -315,25 +315,25 @@ public function templateDirectiveDataProvider() Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_template"}}', - '<b>customer_create_account_email_template template from Vendor/custom_theme</b>', + '<strong>customer_create_account_email_template template from Vendor/custom_theme</strong>', ], 'Template from parent theme - frontend' => [ Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_confirmation_template"}}', - '<b>customer_create_account_email_confirmation_template template from Vendor/default</b>', + '<strong>customer_create_account_email_confirmation_template template from Vendor/default</strong', ], 'Template from grandparent theme - frontend' => [ Area::AREA_FRONTEND, TemplateTypesInterface::TYPE_HTML, '{{template config_path="customer/create_account/email_confirmed_template"}}', - '<b>customer_create_account_email_confirmed_template template from Magento/default</b>', + '<strong>customer_create_account_email_confirmed_template template from Magento/default</strong', ], 'Template from grandparent theme - adminhtml' => [ BackendFrontNameResolver::AREA_CODE, TemplateTypesInterface::TYPE_HTML, '{{template config_path="catalog/productalert_cron/error_email_template"}}', - '<b>catalog_productalert_cron_error_email_template template from Magento/default</b>', + '<strong>catalog_productalert_cron_error_email_template template from Magento/default</strong', null, null, true, diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index df2203df2c054..4800d45e12d4f 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +// @codingStandardsIgnoreFile + ?> <h2 class="page-title">{{$state.current.header}}</h2> From 491e91853826c75ba852732643b5679e5bff17ce Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 5 Dec 2018 14:56:13 +0200 Subject: [PATCH 1405/1415] ENGCOM-3535: Static tests fix. --- .../Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php b/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php index 62b0d30b294b6..f25cd219e3eae 100644 --- a/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php +++ b/lib/internal/Magento/Framework/Webapi/Rest/Response/Renderer/Xml.php @@ -7,6 +7,9 @@ */ namespace Magento\Framework\Webapi\Rest\Response\Renderer; +/** + * Renders response data in Xml format. + */ class Xml implements \Magento\Framework\Webapi\Rest\Response\RendererInterface { /** @@ -165,4 +168,3 @@ protected function _prepareKey($key) return $key; } } - From 773ddd3d3ef0ea7f675d44f944609e6d673c6683 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 5 Dec 2018 17:38:27 +0200 Subject: [PATCH 1406/1415] ENGCOM-3518: Static tests fix. --- lib/internal/Magento/Framework/Escaper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 2e7c41c5256c0..ae6872ab0c6e7 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -47,7 +47,6 @@ class Escaper private $escapeAsUrlAttributes = ['href']; /** - * Escaper constructor. * @param \Magento\Framework\ZendEscaper|null $escaper * @param \Psr\Log\LoggerInterface|null $logger */ From fab3c3bee2f3a53952eaaa083a2899640d49f433 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 5 Dec 2018 17:25:24 -0600 Subject: [PATCH 1407/1415] MC-5596: Comments are not being added in Credit memo emails --- app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php index 6939988ba3d6c..b86acbab20806 100644 --- a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php @@ -100,6 +100,7 @@ private function attachComment( ->setIsCustomerNotified($appendComment); $creditmemo->setComments([$comment]); $creditmemo->setCustomerNote($comment->getComment()); + $creditmemo->setCustomerNoteNotify($appendComment); return $creditmemo; } From 29ec8350c44bae07ef8b4fb1c2438194dcb1ae2a Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Thu, 6 Dec 2018 14:49:51 +0200 Subject: [PATCH 1408/1415] magento/magento2#19404: Fixed integration test --- .../testsuite/Magento/Newsletter/Controller/SubscriberTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/SubscriberTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/SubscriberTest.php index 5347881f5e7d4..92e4f31064e43 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/SubscriberTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/SubscriberTest.php @@ -57,7 +57,7 @@ public function testNewActionUsedEmail() $this->dispatch('newsletter/subscriber/new'); $this->assertSessionMessages($this->equalTo([ - 'There was a problem with the subscription: This email address is already assigned to another user.', + 'This email address is already assigned to another user.', ])); $this->assertRedirect($this->anything()); } From f91201c5d4c20c2d0cc828094d63567600a7fee4 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Thu, 6 Dec 2018 14:54:12 +0200 Subject: [PATCH 1409/1415] magento/magento2#19404: Fixed code styles --- .../Magento/Newsletter/Controller/Subscriber/NewAction.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php index 0ed0944579660..c776ca65407bf 100644 --- a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php +++ b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php @@ -10,6 +10,7 @@ use Magento\Customer\Model\Session; use Magento\Customer\Model\Url as CustomerUrl; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; @@ -22,9 +23,11 @@ use Magento\Newsletter\Model\SubscriberFactory; /** + * New newsletter subscription action + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class NewAction extends SubscriberController +class NewAction extends SubscriberController implements HttpPostActionInterface { /** * @var CustomerAccountManagement @@ -160,6 +163,8 @@ public function execute() } /** + * Get success message + * * @param int $status * @return Phrase */ From bad8596dfece39d4b510edc7e801e4b644e40ee3 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Thu, 6 Dec 2018 14:56:10 +0200 Subject: [PATCH 1410/1415] magento/magento2#19206: Fixed code styles --- .../CatalogInventory/Block/Stockqty/AbstractStockqty.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php index 7b27125f73fa6..4c8f356519e2d 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php @@ -131,7 +131,9 @@ public function getPlaceholderId() */ public function isMsgVisible() { - return $this->getStockQty() > 0 && $this->getStockQtyLeft() > 0 && $this->getStockQtyLeft() <= $this->getThresholdQty(); + return $this->getStockQty() > 0 + && $this->getStockQtyLeft() > 0 + && $this->getStockQtyLeft() <= $this->getThresholdQty(); } /** From 86ccd991afa316cf8f05d5e4d824fc5a0dba0e40 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 6 Dec 2018 12:11:12 -0600 Subject: [PATCH 1411/1415] MC-5496: Dynamic block call to getCurrentUrl method is returning ajax request value - updated test with correct selector --- .../Test/Mftf/Section/StorefrontCategoryProductSection.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryProductSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryProductSection.xml index 7ea74d7913758..178e58ef2d649 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryProductSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryProductSection.xml @@ -28,7 +28,8 @@ <element name="productPriceLabel" type="text" selector="//span[@class='price-label'][contains(text(),'{{var1}}')]" parameterized="true"/> <element name="productPriceLinkAfterLabel" type="text" selector="//span[@class='price-label'][contains(text(),'{{var1}}')]/following::span[contains(text(), '{{var2}}')]" parameterized="true"/> <element name="ProductAddToCartByName" type="button" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//a[contains(@class, 'tocart')]" parameterized="true"/> - <element name="ProductAddToCompareByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//a[contains(@class, 'tocompare')]" parameterized="true"/> + <!--<element name="ProductAddToCompareByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//a[contains(@class, 'tocompare')]" parameterized="true"/>--> + <element name="ProductAddToCompareByName" type="text" selector="//*[contains(@class,'product-item-info')][descendant::a[contains(text(), '{{var1}}')]]//a[contains(@class, 'tocompare')]" parameterized="true"/> <element name="ProductImageByNameAndSrc" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//img[contains(@src, '{{src}}')]" parameterized="true"/> </section> </sections> From 669014b817c05c41da147c7e261e7794626918f6 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 6 Dec 2018 10:48:01 -0600 Subject: [PATCH 1412/1415] MC-5904: Integration test Magento\MessageQueue\Model\Cron\ConsumersRunnerTest failed randomly --- .../Magento/MessageQueue/Model/Cron/ConsumersRunnerTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/Cron/ConsumersRunnerTest.php b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/Cron/ConsumersRunnerTest.php index 4acba63d98e66..3fa80a2dcda1a 100644 --- a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/Cron/ConsumersRunnerTest.php +++ b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/Cron/ConsumersRunnerTest.php @@ -116,6 +116,7 @@ protected function setUp() */ public function testCheckThatPidFilesWasCreated() { + $this->markTestSkipped('MC-5904: Test Fails randomly,'); $this->consumersRunner->run(); foreach ($this->consumerConfig->getConsumers() as $consumer) { $this->waitConsumerPidFile($consumer->getName()); @@ -129,6 +130,8 @@ public function testCheckThatPidFilesWasCreated() */ public function testSpecificConsumerAndRerun() { + $this->markTestSkipped('MC-5904: Test Fails randomly,'); + $specificConsumer = 'quoteItemCleaner'; $pidFilePath = $this->getPidFileName($specificConsumer); $config = $this->config; From 9ec1bed34fd236cabdfe8384a49880239859b5bd Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Fri, 7 Dec 2018 11:24:25 -0600 Subject: [PATCH 1413/1415] Deliver MTF to MFTF conversion --- ...ateLargeRate.xml => AdminCreateTaxRateLargeRateTest.xml} | 2 +- ...tcode.xml => AdminCreateTaxRateSpecificPostcodeTest.xml} | 2 +- ...ange.xml => AdminCreateTaxRateWiderZipCodeRangeTest.xml} | 2 +- ...CodeRange.xml => AdminCreateTaxRateZipCodeRangeTest.xml} | 2 +- .../Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php | 1 + .../Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.xml | 5 +++++ .../Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php | 1 + .../Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.xml | 6 ++++++ .../Magento/Mtf/TestSuite/InjectableTests/basic_green.xml | 2 ++ 9 files changed, 19 insertions(+), 4 deletions(-) rename app/code/Magento/Tax/Test/Mftf/Test/{AdminCreateTaxRateLargeRate.xml => AdminCreateTaxRateLargeRateTest.xml} (98%) rename app/code/Magento/Tax/Test/Mftf/Test/{AdminCreateTaxRateSpecificPostcode.xml => AdminCreateTaxRateSpecificPostcodeTest.xml} (98%) rename app/code/Magento/Tax/Test/Mftf/Test/{AdminCreateTaxRateWiderZipCodeRange.xml => AdminCreateTaxRateWiderZipCodeRangeTest.xml} (98%) rename app/code/Magento/Tax/Test/Mftf/Test/{AdminCreateTaxRateZipCodeRange.xml => AdminCreateTaxRateZipCodeRangeTest.xml} (98%) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml similarity index 98% rename from app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml rename to app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml index db029359b83ac..2c8e245371d98 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRate.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateTaxRateLargeRate"> + <test name="AdminCreateTaxRateLargeRateTest"> <annotations> <stories value="Create tax rate"/> <title value="Create Tax Rate, large rate"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml similarity index 98% rename from app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml rename to app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml index cb6f852a76493..4c5f6045d41fb 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcode.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateTaxRateSpecificPostcode"> + <test name="AdminCreateTaxRateSpecificPostcodeTest"> <annotations> <stories value="Create tax rate"/> <title value="Create tax rate,specific postcode"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml similarity index 98% rename from app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml rename to app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml index 0920ac522785f..38c74f817d8e2 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRange.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateTaxRateWiderZipCodeRange"> + <test name="AdminCreateTaxRateWiderZipCodeRangeTest"> <annotations> <stories value="Create tax rate"/> <title value="Create Tax Rate, wider zip code range"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml similarity index 98% rename from app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml rename to app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml index 7114e821c3269..dcd6ce0270ddb 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRange.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateTaxRateZipCodeRange"> + <test name="AdminCreateTaxRateZipCodeRangeTest"> <annotations> <stories value="Create Tax Rate"/> <title value="Create Tax Rate,zip code range"/> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php index aa74de5afe5f5..8b4f233f35501 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php @@ -28,6 +28,7 @@ class CreateTaxRateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const MFTF_MIGRATED = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.xml index 62e91f39fcce0..b4b76fd62cc34 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Tax\Test\TestCase\CreateTaxRateEntityTest" summary="Create Tax Rate" ticketId="MAGETWO-23286"> <variation name="CreateTaxRateEntityTestVariation1"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> <data name="taxRate/data/zip_from" xsi:type="string">-</data> @@ -21,6 +22,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateInTaxRule" /> </variation> <variation name="CreateTaxRateEntityTestVariation2"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">Yes</data> <data name="taxRate/data/zip_from" xsi:type="string">90001</data> @@ -35,6 +37,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateInTaxRule" /> </variation> <variation name="CreateTaxRateEntityTestVariation3"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> <data name="taxRate/data/zip_from" xsi:type="string">-</data> @@ -48,6 +51,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateInTaxRule" /> </variation> <variation name="CreateTaxRateEntityTestVariation4"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">Yes</data> <data name="taxRate/data/zip_from" xsi:type="string">1</data> @@ -60,6 +64,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateInTaxRule" /> </variation> <variation name="CreateTaxRateEntityTestVariation5"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> <data name="taxRate/data/zip_from" xsi:type="string">-</data> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php index 1e66ad61b6c80..10f41e68b6598 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php @@ -33,6 +33,7 @@ class UpdateTaxRateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const MFTF_MIGRATED = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.xml index f8d9a00958b98..1fef659a3deb0 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Tax\Test\TestCase\UpdateTaxRateEntityTest" summary="Edit Tax Rate" ticketId="MAGETWO-23299"> <variation name="UpdateTaxRateEntityTestVariation1"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">default</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> @@ -20,6 +21,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateForm" /> </variation> <variation name="UpdateTaxRateEntityTestVariation2"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">default</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">Yes</data> @@ -33,6 +35,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateForm" /> </variation> <variation name="UpdateTaxRateEntityTestVariation3"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">default</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> @@ -44,6 +47,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateForm" /> </variation> <variation name="UpdateTaxRateEntityTestVariation4"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">withZipRange</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> @@ -56,6 +60,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateForm" /> </variation> <variation name="UpdateTaxRateEntityTestVariation5"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">withZipRange</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">Yes</data> @@ -67,6 +72,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRateForm" /> </variation> <variation name="UpdateTaxRateEntityTestVariation6"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="initialTaxRate/dataset" xsi:type="string">withZipRange</data> <data name="taxRate/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRate/data/zip_is_range" xsi:type="string">No</data> diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml index 7eea71a955c4f..17578fcfe85b1 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml @@ -11,6 +11,7 @@ <deny> <tag group="stable" value="no" /> <tag group="to_maintain" value="yes" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> <rule scope="testsuite"> @@ -23,6 +24,7 @@ <deny> <tag group="test_type" value="3rd_party_test, 3rd_party_test_single_flow" /> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> <tag group="to_maintain" value="yes" /> </deny> </rule> From cd10fac5b5334390c1e27d4df4a20c737dacd686 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Mon, 3 Dec 2018 10:48:42 -0600 Subject: [PATCH 1414/1415] MQE-1187: Fix MFTF skipped tests - Unskipped working tests --- .../Backup/Test/Mftf/Test/AdminCreateAndDeleteBackupsTest.xml | 3 +-- .../Cms/Test/Mftf/Test/AdminAddImageToWYSIWYGBlockTest.xml | 3 --- ...SortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml | 3 --- .../Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 3 --- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/app/code/Magento/Backup/Test/Mftf/Test/AdminCreateAndDeleteBackupsTest.xml b/app/code/Magento/Backup/Test/Mftf/Test/AdminCreateAndDeleteBackupsTest.xml index 496bb79343092..26f8817c0a1bb 100644 --- a/app/code/Magento/Backup/Test/Mftf/Test/AdminCreateAndDeleteBackupsTest.xml +++ b/app/code/Magento/Backup/Test/Mftf/Test/AdminCreateAndDeleteBackupsTest.xml @@ -18,8 +18,7 @@ <testCaseId value="MAGETWO-94176"/> <group value="backup"/> <skip> - <issueId value="MQE-1187"/> - <issueId value="DEVOPS-3512"/> + <issueId value="MC-5807"/> </skip> </annotations> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToWYSIWYGBlockTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToWYSIWYGBlockTest.xml index 9d19f7307dd29..03edc69e6d625 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToWYSIWYGBlockTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToWYSIWYGBlockTest.xml @@ -16,9 +16,6 @@ <description value="Admin should be able to add image to WYSIWYG content of Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84376"/> - <skip> - <issueId value="MQE-1187" /> - </skip> </annotations> <before> <createData entity="_defaultCmsPage" stepKey="createCMSPage" /> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml index f44ba8a041cbb..c93b216fc89d5 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontSortingByPriceForConfigurableWithCatalogRuleAppliedTest.xml @@ -17,9 +17,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69988"/> <group value="сonfigurable_product"/> - <skip> - <issueId value="MAGETWO-96658"/> - </skip> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategory"/> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 3b9361f79871f..0d9df9176d2b5 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -16,9 +16,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69826"/> <group value="urlRewrite"/> - <skip> - <issueId value="MAGETWO-96713"/> - </skip> </annotations> <!-- Preconditions--> From c442739a0f2bd949918ec5584c22b058d69177f3 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Fri, 7 Dec 2018 13:04:49 -0600 Subject: [PATCH 1415/1415] MQE-1383: Deliver mtf-eol-pr branch to mainline --- .../Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml | 2 +- .../Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml | 2 +- .../Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml index 2c8e245371d98..cb79de19ce23a 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateLargeRateTest.xml @@ -11,7 +11,7 @@ <test name="AdminCreateTaxRateLargeRateTest"> <annotations> <stories value="Create tax rate"/> - <title value="Create Tax Rate, large rate"/> + <title value="Create tax rate, large rate"/> <description value="Test log in to Create Tax Rate and Create Large Rate"/> <testCaseId value="MC-5322"/> <severity value="CRITICAL"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml index 4c5f6045d41fb..696d6c4c87763 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateSpecificPostcodeTest.xml @@ -11,7 +11,7 @@ <test name="AdminCreateTaxRateSpecificPostcodeTest"> <annotations> <stories value="Create tax rate"/> - <title value="Create tax rate,specific postcode"/> + <title value="Create tax rate, specific postcode"/> <description value="Test log in to Create Tax Rate and Create specific Postcode"/> <testCaseId value="MC-5320"/> <severity value="CRITICAL"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml index 38c74f817d8e2..c6c5e318cc791 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateWiderZipCodeRangeTest.xml @@ -11,7 +11,7 @@ <test name="AdminCreateTaxRateWiderZipCodeRangeTest"> <annotations> <stories value="Create tax rate"/> - <title value="Create Tax Rate, wider zip code range"/> + <title value="Create tax rate, wider zip code range"/> <description value="Test log in to Create Tax Rate and Create Wider Zip Code Range"/> <testCaseId value="MC-5321"/> <severity value="CRITICAL"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml index dcd6ce0270ddb..6d9717318efc8 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCreateTaxRateZipCodeRangeTest.xml @@ -10,8 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminCreateTaxRateZipCodeRangeTest"> <annotations> - <stories value="Create Tax Rate"/> - <title value="Create Tax Rate,zip code range"/> + <stories value="Create tax rate"/> + <title value="Create tax tate, zip code range"/> <description value="Test log in to Create Tax Rate and Create Zip Code Range"/> <testCaseId value="MC-5319"/> <severity value="CRITICAL"/>