From c5ebd86cd9dacc368ae4b09af04fdac1b66cfb6f Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Thu, 12 Apr 2018 14:30:17 -0500 Subject: [PATCH 001/701] 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 11d7acc61d7..6867efd81c7 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 002/701] 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 158cc3da2d0..7fe55499bf2 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 003/701] 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 2d516e82f40..f722927e452 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 1b99ce9a280..a3acb789758 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 396e443355d..6b18ac3e29d 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 004/701] 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 f722927e452..5f792d1729c 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 4e7c3cbd5d64d299965ff258cab84b11c3d6379d Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Tue, 19 Jun 2018 15:36:06 -0500 Subject: [PATCH 005/701] 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 d2f5f5ce566..7fa2f615545 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 39fffa23dc1..956152d2e08 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 006/701] 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 00000000000..0f5346e619a --- /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 007/701] 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 7461d9010a0..a27ee27c0b8 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 0f5346e619a..c477fabe048 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 562ad729fe7..e2191342056 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 008/701] 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 c477fabe048..2d7fe4d165a 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 009/701] 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 2d7fe4d165a..9b629f410f4 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 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 010/701] 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 8262a7e4154..eae0e600434 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 12cbe1ca0e5..aacda763ca2 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 1a22ea947f8..f2cd745e96d 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 011/701] 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 d4b9856c5e3..e6ab0ff5026 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 012/701] 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 d3b8edbed2e..7f44e286fb8 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 7f636334687..b4b42d0da2d 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 013/701] 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 b4b42d0da2d..b75e3adb740 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 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 014/701] 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 c85b484d51c..e6923caa3d2 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 1e0747acc36..ab6a34c4274 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 015/701] 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 38b581da752..5d9badf4207 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 a45d6a62488..af2a43ceaed 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 016/701] 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 5519245ec24..61108c64dda 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 c72651a78da..186cbcb81bf 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 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 017/701] 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 a32faa4640a..9712d129bcd 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 018/701] 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 e52791deaf2..519cf668e74 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 019/701] 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 52d132d634b..24e8c242986 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 d08819ebe94..cb45f73f794 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 616d49496e2..3cc0f6d8bc6 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 9fe66f7545eeb34b3e1a45a4dce92908f14e6c5a Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoud.beekman@mediact.nl> Date: Sun, 26 Aug 2018 19:12:04 +0200 Subject: [PATCH 020/701] Make it possible to disable report bugs link As developer I have removed this link a lot of times with a layout update (remove=true). Since we most of the times do not want this by default it should be configurable whether to show this link or not. A new setting is added under Design > Configuration > Edit > Other Settings > Footer. The new label is 'Display Report Bugs Link'. The default value for this setting is 'Yes' to keep it backwards compatible. --- app/code/Magento/Theme/etc/config.xml | 1 + app/code/Magento/Theme/etc/di.xml | 4 ++++ app/code/Magento/Theme/i18n/en_US.csv | 1 + .../adminhtml/ui_component/design_config_form.xml | 14 ++++++++++++++ .../Magento/Theme/view/frontend/layout/default.xml | 2 +- 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/etc/config.xml b/app/code/Magento/Theme/etc/config.xml index a6984b449d9..b44691c0df9 100644 --- a/app/code/Magento/Theme/etc/config.xml +++ b/app/code/Magento/Theme/etc/config.xml @@ -46,6 +46,7 @@ Disallow: /*SID= </header> <footer translate="copyright"> <copyright>Copyright © 2013-present Magento, Inc. All rights reserved.</copyright> + <report_bugs>1</report_bugs> </footer> </design> <theme> diff --git a/app/code/Magento/Theme/etc/di.xml b/app/code/Magento/Theme/etc/di.xml index 5ff82ce2db6..148267feeaa 100644 --- a/app/code/Magento/Theme/etc/di.xml +++ b/app/code/Magento/Theme/etc/di.xml @@ -214,6 +214,10 @@ <item name="path" xsi:type="string">design/footer/absolute_footer</item> <item name="fieldset" xsi:type="string">other_settings/footer</item> </item> + <item name="footer_report_bugs" xsi:type="array"> + <item name="path" xsi:type="string">design/footer/report_bugs</item> + <item name="fieldset" xsi:type="string">other_settings/footer</item> + </item> <item name="default_robots" xsi:type="array"> <item name="path" xsi:type="string">design/search_engine_robots/default_robots</item> <item name="fieldset" xsi:type="string">other_settings/search_engine_robots</item> diff --git a/app/code/Magento/Theme/i18n/en_US.csv b/app/code/Magento/Theme/i18n/en_US.csv index db641b5da1f..c8c586f0bc6 100644 --- a/app/code/Magento/Theme/i18n/en_US.csv +++ b/app/code/Magento/Theme/i18n/en_US.csv @@ -188,3 +188,4 @@ Settings,Settings ID,ID View,View Action,Action +"Display Report Bugs Link","Display Report Bugs Link" 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 48adca3b1a1..8d4580f90c7 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 @@ -233,6 +233,20 @@ <dataScope>footer_copyright</dataScope> </settings> </field> + <field name="footer_report_bugs" formElement="select"> + <settings> + <dataType>text</dataType> + <label translate="true">Display Report Bugs Link</label> + <dataScope>footer_report_bugs</dataScope> + </settings> + <formElements> + <select> + <settings> + <options class="Magento\Config\Model\Config\Source\Yesno"/> + </settings> + </select> + </formElements> + </field> </fieldset> <fieldset name="search_engine_robots" sortOrder="120"> <settings> diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index 716341f5a64..c84222be19c 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -119,7 +119,7 @@ </arguments> </block> <block class="Magento\Theme\Block\Html\Footer" name="copyright" template="Magento_Theme::html/copyright.phtml"/> - <block class="Magento\Framework\View\Element\Template" name="report.bugs" template="Magento_Theme::html/bugreport.phtml" /> + <block class="Magento\Framework\View\Element\Template" name="report.bugs" template="Magento_Theme::html/bugreport.phtml" ifconfig="design/footer/report_bugs"/> </container> </referenceContainer> <referenceContainer name="before.body.end"> 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 021/701] 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 3779cab431c..944d78f79ca 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 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 022/701] 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 f5dd5bb13ea..435cf5e433b 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 4f086ce8ac2..add7d220e8e 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 e99233d0769..1d834ad10b2 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 3a45c34df17..e9fabb6150d 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 a3acb789758..c8e733a7956 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 787d2c10a44..0c10796a30e 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 023/701] 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 c8b9a1e46a1..dcd3bc93569 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 f81fb2affd3..a26a92df385 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 024/701] 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 c8e733a7956..94ee5a16b5b 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 6b18ac3e29d..365c8d5b9b0 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 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 025/701] 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 944d78f79ca..94b7fff44fd 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 026/701] 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 7372d9715c7..4e68f206026 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 7ea7e4af3c3..ec38ad9ad3a 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 0112d09eb73..4ad2e314c83 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 b872a4ef9fb..f299cd5accd 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 7f636334687..7ccfa5725a7 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 7d06e0f7b74..67512e73350 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 d4d10bfa6dc..5be06fa3836 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 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 027/701] 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 435cf5e433b..4b65f2a207b 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 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 028/701] 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 0df091eb5f8..fca5c2e0bcf 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 88ff2bbace4..1c81260cfe7 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 4fae51de86c..3e5f6e4d04f 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 00000000000..ea07db7b3f9 --- /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 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 029/701] 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 4b65f2a207b..9593cb98395 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 add7d220e8e..169c59aa1c7 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 e9fabb6150d..e5951fb129e 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 d5de12a3503..9e215667903 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 030/701] 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 0df091eb5f8..fca5c2e0bcf 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 88ff2bbace4..1c81260cfe7 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 4fae51de86c..3e5f6e4d04f 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 00000000000..ea07db7b3f9 --- /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 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 031/701] 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 169c59aa1c7..1d7d15f8416 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 7d5a097eeea..18927b5f4ec 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 032/701] 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 9b629f410f4..3fdbb3eae0b 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 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 033/701] 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 fc93b86f5da..8beffab8053 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 034/701] 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 cd450e26cd8..40acd20302c 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 ce92a2c1d95..fb95f67d13c 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 035/701] 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 40acd20302c..cd450e26cd8 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 fb95f67d13c..ce92a2c1d95 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 036/701] 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 d1160329545..855ebbb7639 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 4315597a3cf..28587bca3cc 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 63c993e27c9..e9ce18ef0d3 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 037/701] 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 6ea00591576..a4b3ca95e45 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 01411523108..870d1dedefe 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 d3ab7dd086a..1043f45a740 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 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 038/701] 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 e94104ae473..d86118eeca6 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 a7cc894c9a0..b3e8b0e2b0d 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 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 039/701] 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 ea07db7b3f9..253eb7a3be6 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 040/701] 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 817de6828e4..a7076ba8526 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 db452113ada..35cc2a903bc 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 00000000000..a2a1fcb7fb5 --- /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 a4b3ca95e45..233f554512f 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 383c97a166d..9ec65fb0804 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 041/701] 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 870d1dedefe..dd1fb4b0a8b 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 042/701] 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 a7076ba8526..825288b3664 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 35cc2a903bc..fa8103f7033 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 a2a1fcb7fb5..20e713be9a4 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 233f554512f..bb06d05371e 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 dd1fb4b0a8b..49723f4190a 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 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 043/701] 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 b5d60459714..6dc25501c92 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 044/701] 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 20e713be9a4..60b183db941 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 fd808386920..23687484f10 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 b83676c2e10..a497233afbd 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 08e24cfeb38..d7ee6dabce7 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 00000000000..00de4cdf937 --- /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 045/701] 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 fa8103f7033..9fcfe39f6dd 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 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 046/701] 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 9c747393cc7..60c79a04481 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 8a5f1919f78..eeacc90fba9 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 bb06d05371e..7c359936704 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 00de4cdf937..92a33487615 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 49723f4190a..9538e8729e4 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 969d9530ae5..1a0073b154f 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 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 047/701] 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 00000000000..2e6133f1e32 --- /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 9235ec271a3..683dfb8de1f 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 048/701] 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 2e6133f1e32..811bf08fc1c 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 049/701] 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 c82623632d7..b904b025e4e 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 7a920166a8c..0d98c1ec1a7 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 e4d329bc850..4350ffeb033 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 00000000000..dd34777d365 --- /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 050/701] 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 1d7d15f8416..faf01921e57 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 5f792d1729c..28a360adc51 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 051/701] 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 811bf08fc1c..3cf961c0f42 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 052/701] 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 a112da79d16..b4d6dc2c19e 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 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 053/701] 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 825288b3664..0c6b2cb52e1 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 9fcfe39f6dd..ca2ba9d231a 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 60b183db941..00000000000 --- 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 00000000000..8fe02a9123b --- /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 9538e8729e4..d0eacc94e2c 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 054/701] 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 f493cbc88f1..b9b1aeb9157 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 60c79a04481..e9fc8bf3362 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 b85b03852b6..2a75773754f 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 055/701] 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 0c6b2cb52e1..e32d84b393a 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 ca2ba9d231a..34dcf6639f9 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 9ec65fb0804..72d27152d63 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 056/701] 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 4261873cc8e..ae8005db95a 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 057/701] 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 dbede5491e0..9ec2c62a3c2 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 d8aed1250d8..5414e9c2a5c 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 058/701] 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 9ec2c62a3c2..f8554a4ea11 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 00000000000..f4698b68657 --- /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 059/701] 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 546983bb5e5..77df85e5200 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 2f0415b40dc..b0f8aebf1da 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 0f2326d37c1..5a920ee2f5d 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 c74c62dc6d9..8e867c891d9 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 7d01ff0efc4..3c473dec784 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 a9a5c5b1774..89a3c2e855f 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 99e1d1ad539..3f1e272345e 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 96aa5bdfeff..e9b2a5ce44c 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 8ebd45596d3..0ab1b626b07 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 c7f145eaddb..3001fa41165 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 5b0291eb143..4929e474949 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 2ee9f41870a..7a990e82cbd 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 32e1078c01c..7c0273334d7 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 ec0c32d9af1..112b9e9ccc4 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 11a59cfa59f..621206d9bbb 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 b65a76e8806..6e3defac9a1 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 623fbed57e6..63afa7ad1fc 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 a0bd015c150..5dbe65141f1 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 445824baadf..0f2d0c90bd5 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 75df3027ad9..233b7a804d9 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 feb4877028d..90ee7541a5d 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 2a3d0d3dad4..6a0548b3395 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 596add349db..ceee78469f0 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 060/701] 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 a652d0ef902..2ea3b9aaf10 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 98de8ea3476..e0b0d066c1c 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 106526f66e7..2731d4be182 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 1103f3e54a4..ced16e01b2b 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 5c63a191420..bca42473e2f 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 d08819ebe94..dcfe9c41d31 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 061/701] 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 3c2f20fcc18..242c551c984 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 062/701] 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 be5692a8948..33f4fc9000c 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 40de71e28c0..88bc57b2c27 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 063/701] 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 efb68fd4243..83c80e1e5af 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 242c551c984..54e6e9e1d3c 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 064/701] 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 83c80e1e5af..67f8cadbfae 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 54e6e9e1d3c..a083b7c6fa9 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 a8b3fb1a81f..5a4b15d6cca 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 065/701] 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 a083b7c6fa9..59b299d176b 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 d57525590b9..ea761db9026 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 066/701] #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 73f4df56790..6586f647e24 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 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 067/701] 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 92a33487615..1e9ce849db1 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 e3ef78df82b..87ce9d4ff35 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 d78095f05fe..57d775cdeb7 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 083fa246c96..5e4a5cc45fe 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 068/701] 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 671acc97010..251326415a5 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 0890139741aa73a06f81223e0793c0994e171f4d Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 11:05:54 -0300 Subject: [PATCH 069/701] #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 6586f647e24..7a1ba9513ec 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 070/701] 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 253eb7a3be6..ecc415585eb 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 071/701] 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 89557be3499..47979591a58 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 072/701] 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 7fa2f615545..423d4b8d09d 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 b75e3adb740..873cd64e9c3 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 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 073/701] 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 6ea8d8a1672..13e4e286311 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 074/701] 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 47979591a58..14c6154f0cb 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 423d4b8d09d..cc8bb7aae78 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 5372c7df5e16601f2cce687e15ff25ecdd0b82ce Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 17:18:04 -0300 Subject: [PATCH 075/701] #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 7a1ba9513ec..6f4c9943861 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 076/701] 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 e32d84b393a..e730381b0ea 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 34dcf6639f9..16449762b4a 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 7603400ba8d..e914b8c96d0 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 b9b1aeb9157..f34a70260a2 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 e9fc8bf3362..17af610fed7 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 077/701] 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 16449762b4a..d9627ddd147 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 1a0073b154f..36e216ab4e5 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 078/701] 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 dd34777d365..9180636db78 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 079/701] 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 009c07602fc..3e6164208b4 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 659df0f8447..bcf0d0bfe26 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 be198e7190e..247eb624b2a 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 e2de4aec717..7d2af3b31d9 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 f5e8a23525a..f97cc89c5c8 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 da37c8d7647..1ca24a0c730 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 7fc45eed356..fdf23332fff 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 00000000000..50172e8381d --- /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 00000000000..8b3c79f66e3 --- /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 00000000000..d62354daf76 --- /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 00000000000..3c19ab7e216 --- /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 00000000000..8082e48e57b --- /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 00000000000..0a09740e974 --- /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 00000000000..5318797db5f --- /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 00000000000..8b04bd281a7 --- /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 00000000000..918f465569a --- /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 00000000000..1c003e64683 --- /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 00000000000..27da660c54c --- /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 00000000000..0af6ea796e0 --- /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 00000000000..ead561c0d5f --- /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 00000000000..c96e447ea7c --- /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 00000000000..86462e31a7b --- /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 00000000000..2e397fbf76c --- /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 00000000000..93334bf4c40 --- /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 12645d03414..e78983c62f6 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 0cfaba845fd..b27f4d7e421 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 080/701] 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 247eb624b2a..87112032e1e 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 50172e8381d..00000000000 --- 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 8b3c79f66e3..9e012c14272 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 d62354daf76..afc0b6a0c6f 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 3c19ab7e216..8c8b58943a5 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 8082e48e57b..d4839012f0b 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 0a09740e974..ea64972868d 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 86462e31a7b..492fc708485 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 5318797db5f..518cd548536 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 8b04bd281a7..0b7bc187ecd 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 918f465569a..00000000000 --- 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 1c003e64683..00000000000 --- 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 27da660c54c..00000000000 --- 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 0af6ea796e0..00000000000 --- 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 ead561c0d5f..00000000000 --- 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 c96e447ea7c..00000000000 --- 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 2e397fbf76c..00000000000 --- 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 93334bf4c40..00000000000 --- 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 b27f4d7e421..18772756b12 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 081/701] #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 6f4c9943861..142f6af91cc 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 082/701] 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 223c6d6ab04..06943b25de5 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 083/701] 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 50ff560e53a..ed8e80c1fd0 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 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 084/701] 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 a485069341a..41547806e70 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 bfff885bcbb..1c43dd6fe63 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 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 085/701] 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 d9617209dcd..1706383fc78 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 2d5594a43b1..dcfdca9e8ed 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 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 086/701] 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 ecc415585eb..f0111ede64c 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 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 087/701] 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 77df85e5200..c1103e514e0 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 b0f8aebf1da..a303b15d11a 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 d2779b79b30..cefc4ada7d2 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 5a920ee2f5d..eb96913806f 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 53132ffaa74..089ea15726c 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 8e867c891d9..a05a4845f4a 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 3c473dec784..cb35c16c7f3 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 74af4ec57c7..fe0c495e8c4 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 ae246665b28..1ce80d9d1e9 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 1d7905cca79..a9c6de72acb 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 89a3c2e855f..ce77cec6788 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 3f1e272345e..3617bf52d72 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 73e9f0f5fa1..5d1cf957df7 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 0ab1b626b07..420300ebd7e 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 3001fa41165..52d43943daf 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 a5580606134..08ebefb68d7 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 4929e474949..d1e668cc9ec 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 7a990e82cbd..71ac1b08fd5 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 7c0273334d7..b42007aed9d 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 112b9e9ccc4..13f71c00c73 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 621206d9bbb..0d85648c18a 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 6e3defac9a1..ee108fe484b 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 63afa7ad1fc..52fd66924b9 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 5dbe65141f1..cb6b0045e66 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 0f2d0c90bd5..b9ab168f68d 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 0eea86da61b..78a627c195f 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 233b7a804d9..d5beab83cdd 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 98d36dea28a..85f6c504457 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 ceee78469f0..087d57ffa41 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 088/701] 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 bf60381a8a4..435fdb0b413 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 d9627ddd147..4e33fc737f0 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 8fe02a9123b..00000000000 --- 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 f34a70260a2..e73f3527517 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 17af610fed7..666e6c1942c 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 00000000000..a945822d92f --- /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 089/701] 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 f6e5b955816..83f27def4b4 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 090/701] 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 ce77cec6788..714e2b11dae 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 420300ebd7e..44c542d04d6 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 52d43943daf..3d184bf1a77 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 091/701] 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 8841fab7579..5f0be1bdb8a 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 34cebde64d0..fdf1bfc3540 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 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 092/701] 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 3d184bf1a77..25e728aab7d 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 093/701] 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 25e728aab7d..82c2b52c970 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 094/701] 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 a497233afbd..17778c76da9 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 1e9ce849db1..50dcfbf3da0 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 5a1dcae6cb0..1f70ad0f7df 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 36e216ab4e5..5b7a80bb38d 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 9793fb17167618d4f86316a2110cbd0f52e8ce15 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 14:43:08 +0300 Subject: [PATCH 095/701] 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 241255f68e3..5c96fbbe9e2 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 5e8ea9c4ad0..bd377e40f18 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 c450f44eeb530881115d63857f9d7e6af6f97158 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 19 Sep 2018 14:46:20 +0300 Subject: [PATCH 096/701] 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 38449c56866..00000000000 --- 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 bfd1d1e825f..00000000000 --- 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 56473ec948f..00000000000 --- 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 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 097/701] 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 b3e8b0e2b0d..a7cc894c9a0 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 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 098/701] 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 3cf961c0f42..9dc0dd68ee4 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 683dfb8de1f..4a382e16447 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 099/701] 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 26401c782ef..5f53e621655 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 b54b02bd6de..499d1f5adc9 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 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 100/701] 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 c6e2412f7e5..7ea979df30a 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 101/701] 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 3572cb9d87f..cce00c50d37 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 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 102/701] 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 0b824ca94ca..995999c3a0c 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 ba428dd00dd..2f2029d2f13 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 103/701] 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 c1103e514e0..f0d998e19d7 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 a303b15d11a..a18fe053d5c 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 eb96913806f..40bdf93d161 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 a05a4845f4a..cae8ea16c63 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 cb35c16c7f3..f29330af258 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 714e2b11dae..9180268ac5c 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 3617bf52d72..14619ce9bfc 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 5d1cf957df7..6ff0f8ea0f3 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 44c542d04d6..6338851bd2f 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 d1e668cc9ec..7138a7729fe 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 71ac1b08fd5..3662a2cef8d 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 13f71c00c73..d5d46116820 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 0d85648c18a..82024b3b015 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 ee108fe484b..dbdcd9ff17b 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 52fd66924b9..3f6cb41ce39 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 cb6b0045e66..265e9dbeb33 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 b9ab168f68d..b86e386c847 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 d5beab83cdd..2a8b3d41527 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 90ee7541a5d..30d1a96ea42 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 104/701] 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 14619ce9bfc..3a5558e6d6f 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 105/701] 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 0fb8a7b8825..5b2b771434b 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 106/701] 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 435fdb0b413..985d812fc74 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 4e33fc737f0..8a9d0c9b612 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 e73f3527517..ced65b2d2e1 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 666e6c1942c..c6210f93e12 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 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 107/701] 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 9712d129bcd..b3fa07479a7 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 5e4249685f8..755e54a919b 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 60f33baab9a476c4320f17b80e1e1df74543ac9f Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 14:54:58 +0300 Subject: [PATCH 108/701] 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 bd377e40f18..e862710379a 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 cdc0fd39bac4218fe16eecb34ee7ffa407ac94ca Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 21 Sep 2018 15:58:18 +0300 Subject: [PATCH 109/701] 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 d2f9fb7ebc4..10fc2349968 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 fb2e3dd4290..124ac912a7c 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 3de44e35d24..27a00f86dd9 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 fe17adcb09c..52264c78b77 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 6c17762a882..f33350ea482 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 15e570da04b..e79cea80ac8 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 921fa81fa6f..12855e457ef 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 f5b6fdc93d3..4810b6c28ca 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 7cb70c9a822..c2059e1935a 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 110/701] 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 77f41024ba0..00000000000 --- 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 b79ad008e5e..00000000000 --- 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 aad20f757e9..00000000000 --- 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 111/701] 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 52264c78b77..6aee2894f49 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 112/701] 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 f5ab45c5eb1..a98d6193402 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 3df667094f2..2e82d8064a9 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 7adde3c11ac..a10a2246048 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 0500f318582..5050b6be7e5 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 43e98419798..890c475b0c3 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 00000000000..48f6ccfead2 --- /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 00000000000..dd52deab825 --- /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 00000000000..0c7dc522f57 --- /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 00000000000..dd52deab825 --- /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 14d9528852bd30b6f7545b3a22ac2d555a196543 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Fri, 21 Sep 2018 15:14:11 -0300 Subject: [PATCH 113/701] 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 59b299d176b..2bfa465c826 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 5a4b15d6cca..17ba759a4d7 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 114/701] 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 fe17adcb09c..3d88aeaef76 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 b0d1647d8b8..b2276d79f5e 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 47413207211e76618b2c85ecf73371dc2f02a84a Mon Sep 17 00:00:00 2001 From: "tomasz.blaszkiewicz" <hello@magently.com> Date: Fri, 7 Sep 2018 11:16:49 +0200 Subject: [PATCH 115/701] Fix currency symbol setting back to default #17567 --- .../Model/System/Currencysymbol.php | 8 +++++--- .../view/adminhtml/templates/grid.phtml | 19 ++++++++++--------- .../backend/web/css/source/forms/_fields.less | 7 +++++++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php index fcde688a1e1..518e7fcf418 100644 --- a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php +++ b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php @@ -192,9 +192,11 @@ public function getCurrencySymbolsData() */ public function setCurrencySymbolsData($symbols = []) { - foreach ($this->getCurrencySymbolsData() as $code => $values) { - if (isset($symbols[$code]) && ($symbols[$code] == $values['parentSymbol'] || empty($symbols[$code]))) { - unset($symbols[$code]); + if (!$this->_storeManager->isSingleStoreMode()) { + foreach ($this->getCurrencySymbolsData() as $code => $values) { + if (isset($symbols[$code]) && ($symbols[$code] == $values['parentSymbol'] || empty($symbols[$code]))) { + unset($symbols[$code]); + } } } $value = []; diff --git a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/grid.phtml b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/grid.phtml index 0ba3c7ed2d7..6e9b9a396ec 100644 --- a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/grid.phtml +++ b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/grid.phtml @@ -23,10 +23,9 @@ </label> <div class="admin__field-control"> <input id="custom_currency_symbol<?= /* @escapeNotVerified */ $code ?>" - class="required-entry admin__control-text" + class="required-entry admin__control-text <?= $data['inherited'] ? 'disabled' : '' ?>" type="text" value="<?= $block->escapeHtmlAttr($data['displaySymbol']) ?>" - <?= $data['inherited'] ? ' disabled="disabled"' : '' ?> name="custom_currency_symbol[<?= /* @escapeNotVerified */ $code ?>]"> <div class="admin__field admin__field-option"> <input id="custom_currency_symbol_inherit<?= /* @escapeNotVerified */ $code ?>" @@ -49,16 +48,18 @@ require(['jquery', "mage/mage", 'prototype'], function(jQuery){ function toggleUseDefault(code, value) { - checkbox = $('custom_currency_symbol_inherit'+code); - input = $('custom_currency_symbol'+code); - if (checkbox.checked) { - input.value = value; - input.disabled = true; + checkbox = jQuery('#custom_currency_symbol_inherit'+code); + input = jQuery('#custom_currency_symbol'+code); + + if (checkbox.is(':checked')) { + input.addClass('disabled'); + input.val(value); + input.prop('readonly', true); } else { - input.disabled = false; + input.removeClass('disabled'); + input.prop('readonly', false); } } - window.toggleUseDefault = toggleUseDefault; }); </script> 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 c87b8f2ca5c..4ce119e74b1 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 @@ -166,6 +166,13 @@ .admin__control-text, .admin__control-textarea { width: 100%; + &.disabled { + background-color: #e9e9e9; + border-color: #adadad; + color: #303030; + cursor: not-allowed; + opacity: .5; + } } } 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 116/701] 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 b29eee9a47f..9907ce9de1f 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 117/701] 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 9907ce9de1f..e14cde3e692 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 118/701] 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 e14cde3e692..223db01351d 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 119/701] 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 3c423d075be..98b514f3a6a 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 ec38ad9ad3a..20cec812402 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 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 120/701] 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 7d0f9148cd7..d92539396de 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 121/701] 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 3d88aeaef76..94c18b2cd56 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 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 122/701] 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 3d30f836659..157999224d7 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 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 123/701] 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 9f8d827b208..9c5f18c0357 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 6b754dcc5d4..40ea919226d 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 00000000000..ddc0160d300 --- /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 124/701] 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 f0111ede64c..e66ad24fd54 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 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 125/701] 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 7c359936704..563d410a113 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 d0eacc94e2c..af31e481807 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 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 126/701] 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 563d410a113..b140ea3ea32 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 af31e481807..daa73ea7bce 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 127/701] 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 b140ea3ea32..dd49be74e68 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 128/701] 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 22d29eae165..1a7adcd531c 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 129/701] 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 3d882ee2eae..cdbd50c3f34 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 6cc4041f75a..6e83a647919 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 130/701] 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 9c5f18c0357..82f75a76bc2 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 ddc0160d300..635d74f3f27 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 131/701] 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 82f75a76bc2..1f6c2ab4bb2 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 635d74f3f27..2e34521ebd8 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 4719a6ed3ce0433a404c14e18e9375ea29ebd9a3 Mon Sep 17 00:00:00 2001 From: Oleksii Lisovyi <olexii.lisovyi@ven.com> Date: Mon, 24 Sep 2018 15:15:41 +0300 Subject: [PATCH 132/701] Module Catalog: fix issue with custom option price conversion for different base currency on website level --- .../Model/ResourceModel/Product/Option/Value.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php index ce0a9b6e461..5ffc9fbd575 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php @@ -160,19 +160,22 @@ protected function _saveValuePrices(AbstractModel $object) && isset($objectPrice) && $object->getStoreId() != Store::DEFAULT_STORE_ID ) { - $baseCurrency = $this->_config->getValue( + $website = $this->_storeManager->getStore($object->getStoreId())->getWebsite(); + + $websiteBaseCurrency = $this->_config->getValue( Currency::XML_PATH_CURRENCY_BASE, - 'default' + ScopeInterface::SCOPE_WEBSITE, + $website ); - $storeIds = $this->_storeManager->getStore($object->getStoreId())->getWebsite()->getStoreIds(); + $storeIds = $website->getStoreIds(); if (is_array($storeIds)) { foreach ($storeIds as $storeId) { if ($priceType == 'fixed') { $storeCurrency = $this->_storeManager->getStore($storeId)->getBaseCurrencyCode(); /** @var $currencyModel Currency */ $currencyModel = $this->_currencyFactory->create(); - $currencyModel->load($baseCurrency); + $currencyModel->load($websiteBaseCurrency); $rate = $currencyModel->getRate($storeCurrency); if (!$rate) { $rate = 1; 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 133/701] 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 1fb73ea28bf..9d673092b80 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 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 134/701] 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 7c359936704..1ec47f14fee 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 d0eacc94e2c..1dc833d5901 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 135/701] 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 b690395ebab..088ad5a61f6 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 00000000000..52551e6dc96 --- /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 00000000000..9606b0eb605 --- /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 efb1b12fc60..a07616474a4 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 04223d13533..970b1619f02 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 53a34562ae6aeab152cee9c9ac240bcb7259c2ff Mon Sep 17 00:00:00 2001 From: utietze <ulf@tietze-digital.de> Date: Wed, 26 Sep 2018 19:59:54 +0200 Subject: [PATCH 136/701] Update CategoryProcessor.php --- .../Model/Import/Product/CategoryProcessor.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index a5aefff656b..c8bff8a3bf4 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -114,6 +114,9 @@ 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)); 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 137/701] 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 223db01351d..f29c6e475f0 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 138/701] 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 ab566a70a75..0059cee60d3 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 7eafbad8299..f77bdd0263a 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 e571baa23e4..b35ab867bb0 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 139/701] 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 d6006c21c8a..52e9270952a 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 9d733a92159..5c741d0832b 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 140/701] 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 32d6ad86670..eef35abcc97 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 7dda1110fd1..846b20ed225 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 a7b82d54afb..02cc233acc7 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 c0f8b5a45fe..395d15bc02f 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 141/701] 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 f29c6e475f0..fe020f450a6 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 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 142/701] 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 2e34521ebd8..38da50e730d 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 143/701] 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 fd808386920..92aa55eedda 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 c980c43b8f3..301bd4b7a57 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 a46d40c62c7..a2bdaa7dbc6 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 bfc059ccb24..cfd41f2ab97 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 b1cb1920f39..71bdfe0613b 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 ab2c6eb89d2..7cfb5bf40be 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 7555337db8e..f231d74b70d 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 2e4788823a2..537ba2bbce0 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 00000000000..50e9e01d711 --- /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 144/701] 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 d86118eeca6..87c5a47a7b8 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 145/701] 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 35ec242f05c..bba73480d2d 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 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 146/701] 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 90af9bee270..f2d4b570f08 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 87c5a47a7b8..ce6b4d98bbc 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 31fd0696db3..e9eee5c7668 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 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 147/701] 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 c7eb7220503..fa2853c7386 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 148/701] 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 c5e704c2434..a33d460a507 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 7fe8832cd58..f276a96cd1d 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 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 149/701] 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 251326415a5..c1c6fb2eaed 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 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 150/701] 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 855ebbb7639..9bf67954cc2 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 28587bca3cc..0ad4ad8ec79 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 d3fba768e9f..38bc35bda39 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 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 151/701] 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 150c8adf0b2..55646aa9b4a 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 152/701] 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 e2a646275d9..dfd7bfb5aa9 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 2550f70f0be..849366434db 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 153/701] 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 fdd0b70997f..0ab6b5fdf2b 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 c394a2463f5..624b159163b 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 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 154/701] 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 fffb0746d49..6aed5cd39aa 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 e6ab0ff5026..31d5c30d25f 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 155/701] 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 0059cee60d3..3dc9f3e8445 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 f77bdd0263a..ec07c19a2c1 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 156/701] 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 92aa55eedda..c0a3c65d84d 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 50e9e01d711..a87780365c9 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 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 157/701] 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 fe589554154..aa23fa767d1 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 62452228b61..a2b5380d288 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 158/701] 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 5aaa78822af..fe9c14f886f 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 bba73480d2d..35ec242f05c 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 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 159/701] 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 9ae551b69d3..7c0cc03186c 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 a138c9bbac0..e6ed94e0223 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 bd1c057133d..37c0eb6ea12 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 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 160/701] 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 fe9c14f886f..75e3210cad7 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 161/701] 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 71105cd844c..3681dfe8e5b 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 04bac807637..bb7b04f53dd 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 2bebb5bd95b..81a9587d36f 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 c4c8af6b221a84e5f389a95a29bc60af4fc3ae44 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 28 Sep 2018 18:27:01 +0300 Subject: [PATCH 162/701] 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 6aee2894f49..06c1f41c388 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 f33350ea482..59e7f16adfd 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 163/701] 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 744c4d06a0d..3ef4168238b 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 9d3182b6236..9e4a6d92195 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 00000000000..c9a3b8089cc --- /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 164/701] 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 863165ecf72..4d1957991d1 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 be65372725c..85ad66013cf 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 ccc8950450d..f0d899b678c 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 3679803c04d..005c7860cfe 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 a669016eb6b..bc60a5c9b10 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 937175511b1..145db146347 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 7c3577df452..df00e4c7106 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 f4018ed5b5d..a4a843c636c 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 7ba438ff36a..6898e33d49f 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 bb0de008163..8f1f3fde142 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 efc95548670..425e6c00416 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 5262316e2ca..5447ff635f9 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 139154be9df..d6110f4b3b2 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 82a64923ef7..c1c9997bc83 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 ee66a91f395..21d8b7297da 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 83058b6f0ad..a8d46911193 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 eee6ac37767..ed841996ea0 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 61b7075043d..5d4096a3afa 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 ae218f65087..83ad7acca84 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 0cf9f04f976..ca701db7d2a 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 120a22f60d0..c8dbd89017b 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 27a2bd82a5d..73a79f7c872 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 51695fd261d..7f0c5fdae6d 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 33881061eb8..cd3ff62d536 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 8b0a18105ec..e971f59cf10 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 4bdd4336c52..d8b3c19ddb9 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 af1839f04ab..b9b44df6f40 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 ba5a16978c5..47a8681a73c 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 02beeae0f15..4ce286bf159 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 8119d7c5869..7aac6e98fc0 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 63d9656fea2..7c15514f211 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 a3b1d76fef1..e61a886a41d 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 126a0a7ea32..108f1b9f4fd 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 5fbd08c1343..4ffd8ff4ba5 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 16a22aba8db..4f14b7daba1 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 69e4b90baf0..db1d550c372 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 99d34de1830..4b9db55105e 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 6faffefde60..d1259159606 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 32ecb497142..1904df9ccd5 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 9e954b57f64..963dd532954 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 7a39a7bf478..31ac889b19e 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 ce8ce6829a0..bac8c1bb57c 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 ffd434251f9..e32785a6a17 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 c02d861fda8..495e1a4567d 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 c624f9d1c2e..cb7210813b0 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 365e03b3648..b104fd03297 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 5b6152dbb2ad5609a83fda659a7dfbe5abcc442b Mon Sep 17 00:00:00 2001 From: Vincent MARMIESSE <vincent.marmiesse@ph2m.com> Date: Mon, 24 Sep 2018 13:30:50 +0200 Subject: [PATCH 165/701] Label should always be blank even if attribute is required --- .../Magento/Eav/Model/Entity/Attribute/Source/Table.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index 8f8c39bf260..f9aa1a9ed3b 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -9,6 +9,8 @@ use Magento\Store\Model\StoreManagerInterface; /** + * Eav attribute default source when values are coming from another table + * * @api * @since 100.0.2 */ @@ -127,12 +129,14 @@ public function getSpecificOptions($ids, $withEmpty = true) } /** + * Add an empty option to the array + * * @param array $options * @return array */ private function addEmptyOption(array $options) { - array_unshift($options, ['label' => $this->getAttribute()->getIsRequired() ? '' : ' ', 'value' => '']); + array_unshift($options, ['label' => ' ', 'value' => '']); return $options; } 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 166/701] 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 65bc7b5fb0c..79f6024132b 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 2e411839400..639c0aecb36 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 3990587fa8c..1ac7ad37737 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 70c076fc216..7e0ad7c46d6 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 5c28db9a3b0..81b7414380b 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 48a78204774..15856bbee74 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 29238022811..26837448f2d 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 155dea824cd..ddb4085fa13 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 aa3d82954cf..be572793f1e 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 8ee404e9df2..27a784f8609 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 b0bf91013af..bff878122c8 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 bed27c16f3a..eb4761adf83 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 30be62826fc..c24acf4610e 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 82bd3d139f3..bf431396cc0 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 c51de6e28b2..2ffa63098cd 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 6bf5bb632f0..a5650cac733 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 81c0ecdb321..b49809cfc80 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 4584838782a..be2609ccc33 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 2e7eb097af5..398d6e9dd18 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 2b4be8369de..9ea4007c6bd 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 1a18b4c05e3..a2c39deff18 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 31916c456f0..0308fda6573 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 cee6bb9f648..f8863aca8db 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 798801187b4..1cdd9c5b9fa 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 f3b6399c4d7..cd0aa12f913 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 bbdb1dd7b65..9f105bd3ea4 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 426fa69a5fd..6db063bde7d 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 168446e9606..ed2b1be5c70 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 fa7bcce8f22..b01f3c50d50 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 c96ccf3663b..02d533d7bcb 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 f11d8709ba4..35f616f1096 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 70af9cafd74..796559d1f70 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 cce195c953e..8722cd52b61 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 2aab76cb953..d88e5627df0 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 8d097487b1b..a660cf62b1a 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 a6a97a89882..49caede8c4a 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 49d1fe82d8e..ff9aeb4fb44 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 7e0cb306d48..916bfdd6020 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 e706756515a..aff558c6d02 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 1904df9ccd5..2d8dfb92224 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 963dd532954..e554d3c774a 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 bac8c1bb57c..bcd4080b30b 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 4431d3d7dab..a8bb3b2fe28 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 df314377b5a..3d2b9eed037 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 e7cf5da0935..c382569338e 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 692e199fffa..67ed66da2a0 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 49a55ddf26e..7136fad5b19 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 7925a619c80..a61c691c0d5 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 1e35a3c0352..3986cc617f0 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 f15e313ce06..0e3ba0d4e66 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 bbec04eed06..9d7e31ee3b6 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 64a2fdc25bb..c28bc3485cf 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 85281ce5568..007647db39b 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 c73651ad800..690ef9115ed 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 4a654acc920..55c85829799 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 8c4e5c432d5..906220db28d 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 a70f83d7ac9..c122bae15cb 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 7256e11b8ed..916e03f4714 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 8e47a0674e2..6e6aee08f92 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 5729b2544b3..ceff0ea2e5d 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 8db96ad04b2..4321105a7e8 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 2eb7d06d31a..863f1fb7466 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 5e4c2e0ff8a..68ca546b819 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 e32785a6a17..f0eade4bfbc 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 b6e60aabf48..d5b7be8bf01 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 001f9936c95..6b18c4307f5 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 cb7210813b0..956a1b2360f 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 23429dd43e3..7f6dbe033e3 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 a823867296f..7bcb91e9454 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 167/701] 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 3ef4168238b..1e2561e2efe 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 168/701] 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 3fdbb3eae0b..66316d0af8b 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 169/701] 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 b71b466714e..11556dcfb7e 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 170/701] 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 3681dfe8e5b..5ba513e5de6 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 171/701] 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 5ba513e5de6..ba4c4efd78f 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 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 172/701] 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 fe020f450a6..cd68ca98899 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 16a7f0babc8cfd4420dfea32c35449745449791b Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:05:26 -0300 Subject: [PATCH 173/701] 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 2bfa465c826..fbda76a8e36 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 174/701] 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 fbda76a8e36..5dbaf093698 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 17ba759a4d7..e8e20070c55 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 175/701] 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 e8e20070c55..11e9a22d8ce 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 176/701] 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 5dbaf093698..2bc0b36cb6e 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 177/701] 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 2bc0b36cb6e..8534e798481 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 11e9a22d8ce..217bf5b7f01 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 178/701] 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 217bf5b7f01..c2ef294daf0 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 179/701] 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 c2ef294daf0..4aff80161ef 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 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 180/701] 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 ed8e80c1fd0..50ff560e53a 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 181/701] #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 6f4c9943861..d75da01b5de 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 6fabc513da9..f9475d78607 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 182/701] 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 d1c44383b4a..6165def067e 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 ec725ad5fe4..19bcca985f9 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 49525fd99da..00000000000 --- 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 f39d641b18a..00000000000 --- 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 7fbe454f709..00000000000 --- 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 d1bc251f263..00000000000 --- 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 6f13f04aef3..00000000000 --- 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 49525fd99da..00000000000 --- 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 f39d641b18a..00000000000 --- 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 7293cea9a9b..00000000000 --- 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 27559a48bef..00000000000 --- 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 986c2af6164..00000000000 --- 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 4c1cd7300cf..00000000000 --- 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 d9a98d4baa6..00000000000 --- 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 45ec5f3adf2..00000000000 --- 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 361f06a6ff3..00000000000 --- 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 49525fd99da..00000000000 --- 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 f39d641b18a..00000000000 --- 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 6fd2a54c601..00000000000 --- 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 f3340b205f1..00000000000 --- 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 6aa54d2fb9b..00000000000 --- 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 4fead0e5149..00000000000 --- 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 200c52cab79..00000000000 --- 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 d759d1ab274..00000000000 --- 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 8cd83fd6206..00000000000 --- 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 f8702eeaf5e..00000000000 --- 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 6a196c2c32c..00000000000 --- 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 c107debc1aa..00000000000 --- 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 f908c5cb457..00000000000 --- 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 b18c24050d3..00000000000 --- 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 183/701] #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 84db685c029..8fdef2cbaad 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 f9475d78607..4fc73caf7e1 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 f05338ad1e7..9950c89ce3c 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 184/701] 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 7240707f642..6add4e8cb3a 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 185/701] 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 71a876bbbcd..beb2c2bffa1 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 ed08c84cdb6..7a9de9670f2 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 186/701] 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 66316d0af8b..e4fd894f608 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 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 187/701] 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 0b3d298061c..ff361a87bc7 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 188/701] 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 f6dd8f8527a..82c612c1a78 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 00000000000..1649706a51f --- /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 189/701] 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 00000000000..5c65fce10cc --- /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 beaab64280a..36a294f26e1 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 190/701] 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 8beffab8053..723910978df 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 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 191/701] 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 7e88a484f9f..e9c15bd7f8c 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 192/701] 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 e6df38c563e..4ebb23f33e9 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 193/701] 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 f301fb9289e..f5011248d77 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 bf8796a03f5..006354b997d 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 194/701] 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 cd68ca98899..e0b1903621d 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 401f4aa15e800cac2f2c83c005654ccb59c5e23f Mon Sep 17 00:00:00 2001 From: Miguel Balparda <miguel.balparda@moozo.com.ar> Date: Tue, 2 Oct 2018 12:45:18 -0300 Subject: [PATCH 195/701] Added required fields to templates --- .github/ISSUE_TEMPLATE.md | 9 +++++---- .github/ISSUE_TEMPLATE/bug_report.md | 9 +++++---- .github/ISSUE_TEMPLATE/developer-experience-issue.md | 5 +++-- .github/ISSUE_TEMPLATE/feature_request.md | 5 +++-- .github/PULL_REQUEST_TEMPLATE.md | 9 +++++---- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 12ad4e452b1..ce3f059a46f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,11 +5,12 @@ - Information on your environment, - Steps to reproduce, - Expected and actual results, + Fields marked with (*) are required. Please don't remove the template. Please also have a look at our guidelines article before adding a new issue https://github.com/magento/magento2/wiki/Issue-reporting-guidelines --> -### Preconditions +### Preconditions (*) <!--- Please provide as detailed information about your environment as possible. For example Magento version, tag, HEAD, PHP & MySQL version, etc.. @@ -17,7 +18,7 @@ 1. 2. -### Steps to reproduce +### Steps to reproduce (*) <!--- It is important to provide a set of clear steps to reproduce this bug. If relevant please include code samples @@ -26,10 +27,10 @@ 2. 3. -### Expected result +### Expected result (*) <!--- Tell us what should happen --> 1. [Screenshots, logs or description] -### Actual result +### Actual result (*) <!--- Tell us what happens instead --> 1. [Screenshots, logs or description] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 17aa66c919e..33a6ef02ace 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,28 +6,29 @@ about: Technical issue with the Magento 2 core components <!--- Please review our guidelines before adding a new issue: https://github.com/magento/magento2/wiki/Issue-reporting-guidelines +Fields marked with (*) are required. Please don't remove the template. --> -### Preconditions +### Preconditions (*) <!--- Provide the exact Magento version (example: 2.2.5) and any important information on the environment where bug is reproducible. --> 1. 2. -### Steps to reproduce +### Steps to reproduce (*) <!--- Important: Provide a set of clear steps to reproduce this bug. We can not provide support without clear instructions on how to reproduce. --> 1. 2. -### Expected result +### Expected result (*) <!--- Tell us what do you expect to happen. --> 1. [Screenshots, logs or description] 2. -### Actual result +### Actual result (*) <!--- Tell us what happened instead. Include error messages and issues. --> 1. [Screenshots, logs or description] 2. diff --git a/.github/ISSUE_TEMPLATE/developer-experience-issue.md b/.github/ISSUE_TEMPLATE/developer-experience-issue.md index a66b0c62ef8..423d4818fb3 100644 --- a/.github/ISSUE_TEMPLATE/developer-experience-issue.md +++ b/.github/ISSUE_TEMPLATE/developer-experience-issue.md @@ -6,12 +6,13 @@ about: Issues related to customization, extensibility, modularity <!--- Please review our guidelines before adding a new issue: https://github.com/magento/magento2/wiki/Issue-reporting-guidelines +Fields marked with (*) are required. Please don't remove the template. --> -### Summary +### Summary (*) <!--- Describe the issue you are experiencing. Include general information, error messages, environments, and so on. --> -### Examples +### Examples (*) <!--- Provide code examples or a patch with a test (recommended) to clearly indicate the problem. --> ### Proposed solution diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index de85da43b70..d6c816c2ee2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -6,12 +6,13 @@ about: Please consider reporting directly to https://github.com/magento/communit <!--- Important: This repository is intended only for Magento 2 Technical Issues. Enter Feature Requests at https://github.com/magento/community-features. Project stakeholders monitor and manage requests. Feature requests entered using this form may be moved to the forum. +Fields marked with (*) are required. Please don't remove the template. --> -### Description +### Description (*) <!--- Describe the feature you would like to add. --> -### Expected behavior +### Expected behavior (*) <!--- What is the expected behavior of this feature? How is it going to work? --> ### Benefits diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5b0b9d74e45..f191bd9aaba 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,12 +3,13 @@ To help us process this pull request we recommend that you add the following information: - Summary of the pull request, - Issue(s) related to the changes made, - - Manual testing scenarios, + - Manual testing scenarios + Fields marked with (*) are required. Please don't remove the template. --> <!--- Please provide a general summary of the Pull Request in the Title above --> -### Description +### Description (*) <!--- Please provide a description of the changes proposed in the pull request. Letting us know what has changed and why it needed changing will help us validate this pull request. @@ -22,7 +23,7 @@ 1. magento/magento2#<issue_number>: Issue title 2. ... -### Manual testing scenarios +### Manual testing scenarios (*) <!--- Please provide a set of unambiguous steps to test the proposed code change. Giving us manual testing scenarios will help with the processing and validation process. @@ -30,7 +31,7 @@ 1. ... 2. ... -### Contribution checklist +### Contribution checklist (*) - [ ] Pull request has a meaningful description of its purpose - [ ] All commits are accompanied by meaningful commit messages - [ ] All new or changed code is covered with unit/integration tests (if applicable) From d89f7b3fbb7a61ebac4cc96547b24e139a835871 Mon Sep 17 00:00:00 2001 From: Miguel Balparda <miguel.balparda@moozo.com.ar> Date: Tue, 2 Oct 2018 12:51:08 -0300 Subject: [PATCH 196/701] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index ce3f059a46f..2b1720ccaab 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,7 +5,7 @@ - Information on your environment, - Steps to reproduce, - Expected and actual results, - Fields marked with (*) are required. Please don't remove the template. + Fields marked with (*) are required. Please don't remove the template. Please also have a look at our guidelines article before adding a new issue https://github.com/magento/magento2/wiki/Issue-reporting-guidelines --> From 921333cf7f7f8af046d0fe4fd0237dad37ecf39a Mon Sep 17 00:00:00 2001 From: Miguel Balparda <miguel.balparda@moozo.com.ar> Date: Tue, 2 Oct 2018 12:52:02 -0300 Subject: [PATCH 197/701] Update feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index d6c816c2ee2..f64185773ca 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -5,8 +5,7 @@ about: Please consider reporting directly to https://github.com/magento/communit --- <!--- -Important: This repository is intended only for Magento 2 Technical Issues. Enter Feature Requests at https://github.com/magento/community-features. Project stakeholders monitor and manage requests. Feature requests entered using this form may be moved to the forum. -Fields marked with (*) are required. Please don't remove the template. +Important: This repository is intended only for Magento 2 Technical Issues. Enter Feature Requests at https://github.com/magento/community-features. Project stakeholders monitor and manage requests. Feature requests entered using this form may be moved to the forum. Fields marked with (*) are required. Please don't remove the template. --> ### Description (*) From 543fce4f671377309d68bc0132c33a0000342493 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 2 Oct 2018 13:27:17 -0500 Subject: [PATCH 198/701] Fixed static test --- .../Model/Import/Product/CategoryProcessor.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index c8bff8a3bf4..ffa0d4aff87 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 to be processed + * * @return $this */ protected function initCategories() 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 199/701] 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 82f5b515eb9..0032a6c987e 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 200/701] 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 00000000000..0ec7e12e42d --- /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 0f618058e06..47da945c2cc 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 9235ec271a3..e80e6846bf9 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 295113a98e4..c7b4c7688b9 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 201/701] 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 a87780365c9..c93b216fc89 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 202/701] 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 f0d998e19d7..c0c224766eb 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 a18fe053d5c..8b0849c8874 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 6338851bd2f..da8a3268753 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 82c2b52c970..b124897770b 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 e09bae08dde..6f3ff1df574 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 3f6cb41ce39..b22775e0987 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 265e9dbeb33..0ef8726e07f 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 b86e386c847..79ea0d7408c 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 2a8b3d41527..9ccbf80f99a 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 203/701] 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 e66ad24fd54..534541c96ea 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 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 204/701] 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 99c963501a9..68dc8d753b5 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 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 205/701] 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 6add4e8cb3a..8756aab1ace 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 206/701] 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 8756aab1ace..3958c6d152c 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 207/701] 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 ce92a2c1d95..16582192058 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 d12ae8f821e..a802496d299 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 208/701] 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 16582192058..6b2604723cc 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 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 209/701] 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 9180268ac5c..468a9e7946f 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 da8a3268753..c4fab39dfde 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 79ea0d7408c..11f9787bf14 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 30d1a96ea42..1208aeb31ea 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 210/701] 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 11f9787bf14..0fce3a52170 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 211/701] 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 f2d1dd9f0a8..c38f182f275 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 76b060015c5..27fa5eb783b 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 eaaba639d49..8fa77a7388b 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 212/701] 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 c989f2dd474..35a17824b1d 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 213/701] 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 6e3e7f7d171..3ee6cef4773 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 214/701] 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 a7410cac64d..51a9313fdef 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 1fc599e4c85..b434fd3f5d3 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 3dcf6c4a3fc..3095abef7bb 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 b0cc1bf061a..9b3165a2c55 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 60b9f34d29a..f68ef35e534 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 ea6882e21c8..26d31456bf6 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 215/701] 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 9a55f981b76..14bcc395633 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 216/701] 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 14bcc395633..31edeaae9da 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 217/701] 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 f016b0dbefd..c81274337f4 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 218/701] 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 d8e1b837a1d..d9f2b14a40e 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 7f6d862ada0..114c7918910 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 219/701] 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 50b40cf4f2e..04baef55863 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 220/701] 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 72936d31739..b01f254b837 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 2c73d7a0791..7f1fd719422 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 221/701] 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 ebd8671de02..d57154c4299 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 4326a51f309..11614e79bba 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 222/701] 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 8cabe71c175..6f83072f0af 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 223/701] 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 6f83072f0af..37f938338c9 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 224/701] 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 37f938338c9..7fc26b8efdc 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 225/701] 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 7fc26b8efdc..8a8514f3c9c 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 226/701] 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 8a8514f3c9c..6b6c1762fad 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 227/701] 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 b4be904223a..901866d52f7 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 228/701] 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 6b2604723cc..13cfa4a98ca 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 229/701] 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 13cfa4a98ca..b2f96855388 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 230/701] 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 35a17824b1d..6552e854400 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 231/701] 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 4590af4f2d6..03012918f4a 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 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 232/701] 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 e3b3d834522..38bc52eac42 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 921fa81fa6f..eb06d8d5d66 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 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 233/701] 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 4ebb23f33e9..cb72189f6d5 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 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 234/701] 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 38da50e730d..a4bd507d98f 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 235/701] 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 f9cec6404dc..e6e747aed32 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 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 236/701] 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 e6e747aed32..f12e2dba6e4 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 47d5df331e5..82bb2526a9e 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 237/701] 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 82bb2526a9e..47d5df331e5 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 238/701] 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 16331ccde24..3925975a0f7 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 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 239/701] 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 f12e2dba6e4..49339054f87 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 240/701] 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 1c476443381..728044b89ca 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 241/701] 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 e9284225284..e67d9f8ad18 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 242/701] 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 00000000000..ad9e8edd4d1 --- /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 00000000000..7ce7bc6de4a --- /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 00000000000..45eb999c803 --- /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 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 243/701] 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 381ee2b9015..77833711e7f 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 244/701] 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 7240707f642..615a0c0f96e 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 245/701] 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 77833711e7f..6bd78cecd3a 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 5852c25bf06e8c489b089bf3947babda4ec8d312 Mon Sep 17 00:00:00 2001 From: Chris Nanninga <chris.nanninga@classyllama.com> Date: Thu, 20 Sep 2018 12:23:22 -0500 Subject: [PATCH 246/701] Fixed issue with lib-line-height mixin failing when value of 'normal' is passed --- lib/web/css/source/lib/_typography.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/web/css/source/lib/_typography.less b/lib/web/css/source/lib/_typography.less index 07128abbf7f..62529fe08d1 100644 --- a/lib/web/css/source/lib/_typography.less +++ b/lib/web/css/source/lib/_typography.less @@ -37,7 +37,7 @@ } // Rem line height -.lib-line-height(@heightValue) when not (@heightValue = false) and not (ispercentage(@heightValue)) { +.lib-line-height(@heightValue) when not (@heightValue = false) and not (@heightValue = normal) and not (ispercentage(@heightValue)) { .lib-font-size-value(@heightValue); .lib-css(line-height, @fontValue); } @@ -46,6 +46,10 @@ .lib-css(line-height, @heightValue); } +.lib-line-height(@heightValue) when (@heightValue = normal) { + .lib-css(line-height, @heightValue); +} + .lib-wrap-words() { overflow-wrap: break-word; word-wrap: break-word; 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 247/701] 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 31edeaae9da..8bec7642831 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 248/701] 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 ab0531ad095..5218b055dee 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 493cabfaee9..f1c22465032 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 8d40d7fa6bb..312da5cf0b8 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 1a022e92c82..b9ec1dd87d1 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 00000000000..429d03e93d1 --- /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 df1d04545b439b753d1e54187ffc51671d3980c7 Mon Sep 17 00:00:00 2001 From: pavel <pavel@newamsterdam.se> Date: Sat, 8 Sep 2018 17:26:12 +0300 Subject: [PATCH 249/701] Implemented 17964: Backend Order creation Authorizenet: If invalid credit card number is entered the loader keeps spinning forever without any error message --- .../Sales/view/adminhtml/web/order/create/scripts.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js index e653ed2a955..bfeb70ee1ea 100644 --- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js +++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js @@ -1171,8 +1171,10 @@ define([ submit : function() { - jQuery('#edit_form').trigger('processStart'); - jQuery('#edit_form').trigger('submitOrder'); + if(jQuery('#edit_form').valid()) { + jQuery('#edit_form').trigger('processStart'); + jQuery('#edit_form').trigger('submitOrder'); + } }, _realSubmit: function () { From ba431d60828e6c82614aadc1104beff6a4472a44 Mon Sep 17 00:00:00 2001 From: pavel <pavel@newamsterdam.se> Date: Thu, 20 Sep 2018 18:39:54 +0300 Subject: [PATCH 250/701] Refactored Implemented 17964: Backend Order creation Authorizenet: If invalid credit card number is entered the loader keeps spinning forever without any error message --- .../Sales/view/adminhtml/web/order/create/scripts.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js index bfeb70ee1ea..233fccab4fd 100644 --- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js +++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js @@ -1171,9 +1171,10 @@ define([ submit : function() { - if(jQuery('#edit_form').valid()) { - jQuery('#edit_form').trigger('processStart'); - jQuery('#edit_form').trigger('submitOrder'); + var $editForm = jQuery('#edit_form'); + if ($editForm.valid()) { + $editForm.trigger('processStart'); + $editForm.trigger('submitOrder'); } }, From 124da1635d535797b81163d7f44b04f8ccbff867 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 4 Oct 2018 12:05:41 +0300 Subject: [PATCH 251/701] Fixed code style issue --- .../Magento/Sales/view/adminhtml/web/order/create/scripts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js index 233fccab4fd..259ca2165e6 100644 --- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js +++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js @@ -1172,6 +1172,7 @@ define([ submit : function() { var $editForm = jQuery('#edit_form'); + if ($editForm.valid()) { $editForm.trigger('processStart'); $editForm.trigger('submitOrder'); From ed1f6a5ae5700eadb512c9ba792f86be431277ad Mon Sep 17 00:00:00 2001 From: Graham Wharton <graham@gwharton.me.uk> Date: Fri, 5 Oct 2018 17:22:49 +0100 Subject: [PATCH 252/701] added component status based filtering --- .../view/base/web/js/core/renderer/layout.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js index fe312738469..ac1de4631e9 100644 --- a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js +++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js @@ -224,7 +224,7 @@ define([ */ build: function (parent, node, name) { var defaults = parent && parent.childDefaults || {}, - children = node.children, + children = this.filterDisabledChildren(node.children), type = getNodeType(parent, node), dataScope = getDataScope(parent, node), component, @@ -294,6 +294,35 @@ define([ return node; }, + /** + * Filter out all disabled components. + * + * @param {Object} children + * @returns {*} + */ + filterDisabledChildren: function (children) { + var cIds; + + //cleanup children config.componentDisabled = true + if (children && typeof children === 'object') { + cIds = Object.keys(children); + + if (cIds) { + _.each(cIds, function (cId) { + if (typeof children[cId] === 'object' && + children[cId].hasOwnProperty('config') && + typeof children[cId].config === 'object' && + children[cId].config.hasOwnProperty('componentDisabled') && + children[cId].config.componentDisabled === true) { + delete children[cId]; + } + }); + } + } + + return children; + }, + /** * Init component. * 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 253/701] 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 718f55c3e55..fa2dcff1917 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 49e05832f2e..941421d456c 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 00000000000..6b6d6d6e6ec --- /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 00000000000..dd52deab825 --- /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 254/701] 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 7ce7bc6de4a..ebc01c4e085 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 45eb999c803..dd37677b5b5 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 255/701] 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 5218b055dee..ab0531ad095 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 f1c22465032..c4a0b55de9b 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 312da5cf0b8..52735acc6d7 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 429d03e93d1..00000000000 --- 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 00000000000..fb18fa1bfab --- /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 256/701] 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 fa2dcff1917..2806f76b138 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 941421d456c..f6194db6d8e 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 257/701] 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 c9a0c0cc0f8..f8a1707e6c2 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 258/701] 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 8bec7642831..ed17634aa48 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 259/701] 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 da4ec37c51d..f0cdab9498a 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 11614e79bba..7fe679b18d8 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 260/701] 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 e31eb44146a..12205aeed8f 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 2e783af6bfc..4c6014af512 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 e2c74823dff..7ab0d9209dd 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 261/701] 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 70794d24a64..78ad7b32330 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 9a1b8fd6401f872f5f5f12db15839135e4f38d27 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 14:06:43 +0200 Subject: [PATCH 262/701] throw exception InvalidArgumentException during validate scheme --- .../Magento/Framework/Communication/Config/Validator.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index 5e2687c3b08..3bcc44bd448 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -46,6 +46,8 @@ public function validateResponseSchemaType($responseSchema, $topicName) { try { $this->validateType($responseSchema); + } catch (\InvalidArgumentException $e) { + throw $e; } catch (\Exception $e) { throw new \LogicException( sprintf( @@ -67,6 +69,8 @@ public function validateRequestSchemaType($requestSchema, $topicName) { try { $this->validateType($requestSchema); + } catch (\InvalidArgumentException $e) { + throw $e; } catch (\Exception $e) { throw new \LogicException( sprintf( @@ -90,6 +94,8 @@ public function validateResponseHandlersType($serviceName, $methodName, $handler { try { $this->methodsMap->getMethodParams($serviceName, $methodName); + } catch (\InvalidArgumentException $e) { + throw $e; } catch (\Exception $e) { throw new \LogicException( sprintf( From 4f017f89e2588aaa0df2714935d24abd9100e981 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 15:20:07 +0200 Subject: [PATCH 263/701] catch InvalidArgumentException, throw correct message, unit test --- .../Communication/Config/Validator.php | 16 +++-- .../Communication/Config/ValidatorTest.php | 58 +++++++++++++++++++ 2 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index 3bcc44bd448..c3b2d03089f 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -13,6 +13,7 @@ */ class Validator { + const INVALID_ANNOTATIONS = 123; /** * @var TypeProcessor */ @@ -47,7 +48,11 @@ public function validateResponseSchemaType($responseSchema, $topicName) try { $this->validateType($responseSchema); } catch (\InvalidArgumentException $e) { - throw $e; + throw new \LogicException( + 'Response schema definition has wrong annotations', + self::INVALID_ANNOTATIONS, + $e + ); } catch (\Exception $e) { throw new \LogicException( sprintf( @@ -70,7 +75,11 @@ public function validateRequestSchemaType($requestSchema, $topicName) try { $this->validateType($requestSchema); } catch (\InvalidArgumentException $e) { - throw $e; + throw new \LogicException( + 'Response schema definition has wrong annotations', + self::INVALID_ANNOTATIONS, + $e + ); } catch (\Exception $e) { throw new \LogicException( sprintf( @@ -94,8 +103,6 @@ public function validateResponseHandlersType($serviceName, $methodName, $handler { try { $this->methodsMap->getMethodParams($serviceName, $methodName); - } catch (\InvalidArgumentException $e) { - throw $e; } catch (\Exception $e) { throw new \LogicException( sprintf( @@ -115,6 +122,7 @@ public function validateResponseHandlersType($serviceName, $methodName, $handler * @param string $typeName * @return $this * @throws \Exception In case when type is invalid + * @throws \InvalidArgumentException */ protected function validateType($typeName) { diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php new file mode 100644 index 00000000000..0f54ae015a0 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -0,0 +1,58 @@ +<?php +/** + * m2git + */ + +namespace Magento\Framework\Test\Unit\Communication\Config; + + +use Magento\Framework\Communication\Config\Validator; +use Magento\Framework\Reflection\MethodsMap; +use Magento\Framework\Reflection\TypeProcessor; + +class ValidatorTest extends \PHPUnit\Framework\TestCase +{ + protected $typeProcessor; + protected $methodsMap; + + public function setUp() + { + $this->methodsMap = $this->createMock(MethodsMap::class); + + $this->methodsMap->expects(static::any()) + ->method('getMethodsMap') + ->will($this->throwException(new \InvalidArgumentException())); + + + $this->typeProcessor = $this->createMock(TypeProcessor::class); + $this->typeProcessor->expects(static::any()) + ->method('isTypeSimple') + ->willReturn(false); + + $this->typeProcessor->expects(static::any()) + ->method('isTypeSimple') + ->willReturn(false); + } + + /** + * @expectedException \LogicException + * @expectedExceptionCode 123 + */ + public function testValidateResponseSchemaType() + { + /** @var Validator $validator */ + $validator = new Validator($this->typeProcessor, $this->methodsMap); + $validator->validateResponseSchemaType('123', '123'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionCode 123 + */ + public function testValidateRequestSchemaType() + { + /** @var Validator $validator */ + $validator = new Validator($this->typeProcessor, $this->methodsMap); + $validator->validateRequestSchemaType('123', '123'); + } +} \ No newline at end of file From 6dd7115e953efb35c03c648889d12068b3fa7fce Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 15:22:37 +0200 Subject: [PATCH 264/701] annotations --- lib/internal/Magento/Framework/Reflection/MethodsMap.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/Reflection/MethodsMap.php b/lib/internal/Magento/Framework/Reflection/MethodsMap.php index 944cd8771ee..77015be8437 100644 --- a/lib/internal/Magento/Framework/Reflection/MethodsMap.php +++ b/lib/internal/Magento/Framework/Reflection/MethodsMap.php @@ -94,6 +94,8 @@ public function getMethodReturnType($typeName, $methodName) * 'validatePassword' => 'boolean' * ] * </pre> + * @throws \InvalidArgumentException + * @throws \ReflectionException */ public function getMethodsMap($interfaceName) { @@ -148,6 +150,8 @@ public function getMethodParams($serviceClassName, $serviceMethodName) * * @param string $interfaceName * @return array + * @throws \ReflectionException + * @throws \InvalidArgumentException */ private function getMethodMapViaReflection($interfaceName) { From 335c2011bd536b908ab7b5e888f16614b0e2c12e Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 15:25:04 +0200 Subject: [PATCH 265/701] remove annotations --- .../Test/Unit/Communication/Config/ValidatorTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php index 0f54ae015a0..633cf7b6abb 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -1,8 +1,4 @@ <?php -/** - * m2git - */ - namespace Magento\Framework\Test\Unit\Communication\Config; From 7903cd5d130846efbead59f27955a3a5a439b620 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 16:02:05 +0200 Subject: [PATCH 266/701] throw exception code from previous exception --- .../Magento/Framework/Communication/Config/Validator.php | 5 ++--- .../Test/Unit/Communication/Config/ValidatorTest.php | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index c3b2d03089f..0bd3763028d 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -13,7 +13,6 @@ */ class Validator { - const INVALID_ANNOTATIONS = 123; /** * @var TypeProcessor */ @@ -50,7 +49,7 @@ public function validateResponseSchemaType($responseSchema, $topicName) } catch (\InvalidArgumentException $e) { throw new \LogicException( 'Response schema definition has wrong annotations', - self::INVALID_ANNOTATIONS, + $e->getCode(), $e ); } catch (\Exception $e) { @@ -77,7 +76,7 @@ public function validateRequestSchemaType($requestSchema, $topicName) } catch (\InvalidArgumentException $e) { throw new \LogicException( 'Response schema definition has wrong annotations', - self::INVALID_ANNOTATIONS, + $e->getCode(), $e ); } catch (\Exception $e) { diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php index 633cf7b6abb..c440d39f018 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -17,7 +17,7 @@ public function setUp() $this->methodsMap->expects(static::any()) ->method('getMethodsMap') - ->will($this->throwException(new \InvalidArgumentException())); + ->will($this->throwException(new \InvalidArgumentException('message', 333))); $this->typeProcessor = $this->createMock(TypeProcessor::class); @@ -32,7 +32,7 @@ public function setUp() /** * @expectedException \LogicException - * @expectedExceptionCode 123 + * @expectedExceptionCode 333 */ public function testValidateResponseSchemaType() { @@ -43,7 +43,7 @@ public function testValidateResponseSchemaType() /** * @expectedException \LogicException - * @expectedExceptionCode 123 + * @expectedExceptionCode 333 */ public function testValidateRequestSchemaType() { From dfda40787fda0b0abe58520a74b72820f2c7fed7 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 16:09:56 +0200 Subject: [PATCH 267/701] modified exception message --- .../Magento/Framework/Communication/Config/Validator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index 0bd3763028d..73d245d79e1 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -48,7 +48,7 @@ public function validateResponseSchemaType($responseSchema, $topicName) $this->validateType($responseSchema); } catch (\InvalidArgumentException $e) { throw new \LogicException( - 'Response schema definition has wrong annotations', + 'Response schema definition has service class with wrong annotated methods', $e->getCode(), $e ); @@ -75,7 +75,7 @@ public function validateRequestSchemaType($requestSchema, $topicName) $this->validateType($requestSchema); } catch (\InvalidArgumentException $e) { throw new \LogicException( - 'Response schema definition has wrong annotations', + 'Request schema definition has service class with wrong annotated methods', $e->getCode(), $e ); 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 268/701] 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 bad1118e3ae..4d3b36c7fe6 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 b2621a5a3310ca0b8177f350370eb6b95d5d2f22 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sat, 6 Oct 2018 17:26:58 +0200 Subject: [PATCH 269/701] Was added description to exceptions, annotations to properties and classes. Implemented validation of exception message in unit test --- .../Communication/Config/Validator.php | 2 +- .../Framework/Reflection/MethodsMap.php | 8 ++++---- .../Communication/Config/ValidatorTest.php | 18 ++++++++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index 73d245d79e1..f08c3700a33 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -121,7 +121,7 @@ public function validateResponseHandlersType($serviceName, $methodName, $handler * @param string $typeName * @return $this * @throws \Exception In case when type is invalid - * @throws \InvalidArgumentException +` * @throws \InvalidArgumentException if methods don't have annotation */ protected function validateType($typeName) { diff --git a/lib/internal/Magento/Framework/Reflection/MethodsMap.php b/lib/internal/Magento/Framework/Reflection/MethodsMap.php index 77015be8437..6b0ddfbfc21 100644 --- a/lib/internal/Magento/Framework/Reflection/MethodsMap.php +++ b/lib/internal/Magento/Framework/Reflection/MethodsMap.php @@ -94,8 +94,8 @@ public function getMethodReturnType($typeName, $methodName) * 'validatePassword' => 'boolean' * ] * </pre> - * @throws \InvalidArgumentException - * @throws \ReflectionException + * @throws \InvalidArgumentException if methods don't have annotation + * @throws \ReflectionException for missing DocBock or invalid reflection class */ public function getMethodsMap($interfaceName) { @@ -150,8 +150,8 @@ public function getMethodParams($serviceClassName, $serviceMethodName) * * @param string $interfaceName * @return array - * @throws \ReflectionException - * @throws \InvalidArgumentException + * @throws \ReflectionException for missing DocBock or invalid reflection class + * @throws \InvalidArgumentException if methods don't have annotation */ private function getMethodMapViaReflection($interfaceName) { diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php index c440d39f018..36e43de9280 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -1,14 +1,27 @@ <?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Framework\Test\Unit\Communication\Config; - use Magento\Framework\Communication\Config\Validator; use Magento\Framework\Reflection\MethodsMap; use Magento\Framework\Reflection\TypeProcessor; +/** + * Unit test for \Magento\Framework\Communication\Config\Validator class + */ class ValidatorTest extends \PHPUnit\Framework\TestCase { + /** + * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject + */ protected $typeProcessor; + + /** + * @var MethodsMap|\PHPUnit_Framework_MockObject_MockObject + */ protected $methodsMap; public function setUp() @@ -19,7 +32,6 @@ public function setUp() ->method('getMethodsMap') ->will($this->throwException(new \InvalidArgumentException('message', 333))); - $this->typeProcessor = $this->createMock(TypeProcessor::class); $this->typeProcessor->expects(static::any()) ->method('isTypeSimple') @@ -33,6 +45,7 @@ public function setUp() /** * @expectedException \LogicException * @expectedExceptionCode 333 + * @expectedExceptionMessage Response schema definition has service class with wrong annotated methods */ public function testValidateResponseSchemaType() { @@ -44,6 +57,7 @@ public function testValidateResponseSchemaType() /** * @expectedException \LogicException * @expectedExceptionCode 333 + * @expectedExceptionMessage Request schema definition has service class with wrong annotated methods */ public function testValidateRequestSchemaType() { From e6833c8af293def8774eebc90c7cd994a08f50ba Mon Sep 17 00:00:00 2001 From: Lewis Voncken <lewis@experius.nl> Date: Sat, 6 Oct 2018 18:58:17 +0200 Subject: [PATCH 270/701] [FEATURE] [issue-3283] Added Filter Support for Yes/No --- .../Magento/Catalog/Model/ResourceModel/Eav/Attribute.php | 2 +- .../Model/ResourceModel/Product/Indexer/Eav/Source.php | 2 +- .../templates/catalog/product/attribute/js.phtml | 2 +- .../Front/ProductAttributeFormBuildFrontTabObserver.php | 8 ++++---- .../adminhtml/ui_component/product_attribute_add_form.xml | 6 ++++-- .../Swatches/view/adminhtml/web/js/product-attributes.js | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php index 8f8e9f6bfed..806da8f81e2 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php @@ -478,7 +478,7 @@ protected function _isOriginalIndexable() $backendType = $this->getOrigData('backend_type'); $frontendInput = $this->getOrigData('frontend_input'); - if ($backendType == 'int' && $frontendInput == 'select') { + if ($backendType == 'int' && ($frontendInput == 'select' || $frontendInput == 'boolean')) { return true; } elseif ($backendType == 'varchar' && $frontendInput == 'multiselect') { return true; 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 5b68730209b..77836c58d50 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 @@ -84,7 +84,7 @@ protected function _getIndexableAttributes($multiSelect) if ($multiSelect == true) { $select->where('ea.backend_type = ?', 'varchar')->where('ea.frontend_input = ?', 'multiselect'); } else { - $select->where('ea.backend_type = ?', 'int')->where('ea.frontend_input = ?', 'select'); + $select->where('ea.backend_type = ?', 'int')->where('ea.frontend_input IN( ? )', ['select', 'boolean']); } return $this->getConnection()->fetchCol($select); 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 8a5f1919f78..3cbfa0f29d7 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 @@ -55,7 +55,7 @@ function bindAttributeInputType() { checkOptionsPanelVisibility(); switchDefaultValueField(); - if($('frontend_input') && ($('frontend_input').value=='select' || $('frontend_input').value=='multiselect' || $('frontend_input').value=='price')){ + if($('frontend_input') && ($('frontend_input').value=='boolean' || $('frontend_input').value=='select' || $('frontend_input').value=='multiselect' || $('frontend_input').value=='price')){ if($('is_filterable') && !$('is_filterable').getAttribute('readonly')){ $('is_filterable').disabled = false; } 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 6b64610caf5..fc1edeb1e23 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -54,8 +54,8 @@ 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 Dropdown, Multiple Select and Price'), - 'note' => __('Can be used only with catalog input type Dropdown, Multiple Select and Price.'), + '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.'), 'values' => [ ['value' => '0', 'label' => __('No')], ['value' => '1', 'label' => __('Filterable (with results)')], @@ -70,8 +70,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) [ 'name' => 'is_filterable_in_search', 'label' => __("Use in Search Results Layered Navigation"), - 'title' => __('Can be used only with catalog input type Dropdown, Multiple Select and Price'), - 'note' => __('Can be used only with catalog input type Dropdown, Multiple Select and Price.'), + '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.'), 'values' => $this->optionList->toOptionArray(), ] ); diff --git a/app/code/Magento/LayeredNavigation/view/adminhtml/ui_component/product_attribute_add_form.xml b/app/code/Magento/LayeredNavigation/view/adminhtml/ui_component/product_attribute_add_form.xml index 000e10197af..0d7476081d1 100644 --- a/app/code/Magento/LayeredNavigation/view/adminhtml/ui_component/product_attribute_add_form.xml +++ b/app/code/Magento/LayeredNavigation/view/adminhtml/ui_component/product_attribute_add_form.xml @@ -11,6 +11,7 @@ <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="valuesForEnable" xsi:type="array"> + <item name="boolean" xsi:type="string">boolean</item> <item name="select" xsi:type="string">select</item> <item name="multiselect" xsi:type="string">multiselect</item> <item name="price" xsi:type="string">price</item> @@ -19,7 +20,7 @@ </item> </argument> <settings> - <notice translate="true">Can be used only with catalog input type Dropdown, Multiple Select and Price.</notice> + <notice translate="true">Can be used only with catalog input type Yes/No (Boolean), Dropdown, Multiple Select and Price.</notice> <dataType>string</dataType> <label translate="true">Use in Layered Navigation</label> <dataScope>is_filterable</dataScope> @@ -36,6 +37,7 @@ <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="valuesForEnable" xsi:type="array"> + <item name="boolean" xsi:type="string">boolean</item> <item name="select" xsi:type="string">select</item> <item name="multiselect" xsi:type="string">multiselect</item> <item name="price" xsi:type="string">price</item> @@ -45,7 +47,7 @@ </item> </argument> <settings> - <notice translate="true">Can be used only with catalog input type Dropdown, Multiple Select and Price.</notice> + <notice translate="true">Can be used only with catalog input type Yes/No (Boolean), Dropdown, Multiple Select and Price.</notice> <label translate="true">Use in Search Results Layered Navigation</label> <dataScope>is_filterable_in_search</dataScope> <imports> 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 01411523108..46083cd9fb4 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 @@ -45,7 +45,7 @@ define([ get tabsFront() { return this.attrTabsFront.length ? this.attrTabsFront.closest('li') : $('#front_fieldset-wrapper'); }, - selectFields: ['select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'], + selectFields: ['boolean', 'select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'], /** * @this {swatchProductAttributes} 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 271/701] 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 3958c6d152c..2bb25f3fd58 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 272/701] 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 4d3b36c7fe6..b09598d4fd7 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 7392ba6993b625968539f204109d2e3327a72eb3 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sun, 7 Oct 2018 11:01:25 +0200 Subject: [PATCH 273/701] short descriptions was added --- .../Magento/Framework/Communication/Config/Validator.php | 6 ++++++ .../Test/Unit/Communication/Config/ValidatorTest.php | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index f08c3700a33..bf21b3dcf95 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -38,6 +38,8 @@ public function __construct( } /** + * Validate response schema definition for topic + * * @param string $responseSchema * @param string $topicName * @return void @@ -65,6 +67,8 @@ public function validateResponseSchemaType($responseSchema, $topicName) } /** + * Validate request schema definition for topic + * * @param string $requestSchema * @param string $topicName * @return void @@ -92,6 +96,8 @@ public function validateRequestSchemaType($requestSchema, $topicName) } /** + * Validate service method specified in the definition of handler + * * @param string $serviceName * @param string $methodName * @param string $handlerName diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php index 36e43de9280..6829bdab592 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -1,4 +1,4 @@ -<?php +<?php declare(strict_types=1); /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. @@ -65,4 +65,4 @@ public function testValidateRequestSchemaType() $validator = new Validator($this->typeProcessor, $this->methodsMap); $validator->validateRequestSchemaType('123', '123'); } -} \ No newline at end of file +} 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 274/701] 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 f5d109b198d..d120b80fc27 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 275/701] 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 d120b80fc27..ab4e985ee4a 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 276/701] 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 ab4e985ee4a..1fff1aedcfa 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 b37d2d6fb3fed1d4c39ca24de413d25961fe8008 Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sun, 7 Oct 2018 12:04:19 +0200 Subject: [PATCH 277/701] moved strict_types block --- .../Test/Unit/Communication/Config/ValidatorTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php index 6829bdab592..55410af176a 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Communication/Config/ValidatorTest.php @@ -1,8 +1,10 @@ -<?php declare(strict_types=1); +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Test\Unit\Communication\Config; use Magento\Framework\Communication\Config\Validator; 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 278/701] 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 1fff1aedcfa..c80b2141294 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 279/701] 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 fb1931ed57c..0eb87374f3b 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 280/701] 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 c80b2141294..2b65c279136 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 9f1d4bfa763f23a5a25f14bae95455dca3e4628f Mon Sep 17 00:00:00 2001 From: Artsiom Bruneuski <artsiom.bruneuski@tudock.de> Date: Sun, 7 Oct 2018 13:08:35 +0200 Subject: [PATCH 281/701] removed wrong symbol --- .../Magento/Framework/Communication/Config/Validator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Communication/Config/Validator.php b/lib/internal/Magento/Framework/Communication/Config/Validator.php index bf21b3dcf95..76ef1b85b63 100644 --- a/lib/internal/Magento/Framework/Communication/Config/Validator.php +++ b/lib/internal/Magento/Framework/Communication/Config/Validator.php @@ -127,7 +127,7 @@ public function validateResponseHandlersType($serviceName, $methodName, $handler * @param string $typeName * @return $this * @throws \Exception In case when type is invalid -` * @throws \InvalidArgumentException if methods don't have annotation + * @throws \InvalidArgumentException if methods don't have annotation */ protected function validateType($typeName) { 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 282/701] 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 b09598d4fd7..d770d674bb3 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 a4ac677b2f2fcd666fbfb48aeab40263bb094a43 Mon Sep 17 00:00:00 2001 From: Hugo <hugovk@users.noreply.github.com> Date: Sun, 7 Oct 2018 20:21:36 +0300 Subject: [PATCH 283/701] Use SVG badge And fix some text [CI skip] --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 50a20b55d4e..c292f1100f3 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ [![Build Status](https://travis-ci.org/magento/magento2.svg?branch=2.3-develop)](https://travis-ci.org/magento/magento2) [![Open Source Helpers](https://www.codetriage.com/magento/magento2/badges/users.svg)](https://www.codetriage.com/magento/magento2) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/magento/magento2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[![Crowdin](https://d322cqt584bo4o.cloudfront.net/magento-2/localized.png)](https://crowdin.com/project/magento-2) +[![Crowdin](https://d322cqt584bo4o.cloudfront.net/magento-2/localized.svg)](https://crowdin.com/project/magento-2) <h2>Welcome</h2> 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](http://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html). ## Install Magento -To install Magento, see either: -* [Installation guide](http://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html) +* [Installation guide](http://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. @@ -52,7 +51,7 @@ Stay up-to-date on the latest security news and patches for Magento by signing u <h2>License</h2> -Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license +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. 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 284/701] 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 d770d674bb3..0ff12faf54c 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 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 285/701] 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 20a556ab414..7a7f9c0affc 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 f9a576367dd..aa303af656a 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 8a42865a3fe..95b06e40602 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 74a0b2d7cf1..8a907bd54aa 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 49bc150fc4e6886cd84e92cc047dce2653ad2b36 Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Mon, 8 Oct 2018 11:24:19 +0300 Subject: [PATCH 286/701] MAGETWO-91388: Enable caching of AJAX requests on Varnish/Fastly --- .../Swatches/Controller/Ajax/Media.php | 22 ++++++++++++++++--- .../view/frontend/web/js/swatch-renderer.js | 14 +++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Swatches/Controller/Ajax/Media.php b/app/code/Magento/Swatches/Controller/Ajax/Media.php index 079ba8f8971..2616213336f 100644 --- a/app/code/Magento/Swatches/Controller/Ajax/Media.php +++ b/app/code/Magento/Swatches/Controller/Ajax/Media.php @@ -24,18 +24,26 @@ class Media extends \Magento\Framework\App\Action\Action */ private $swatchHelper; + /** + * @var \Magento\PageCache\Model\Config + */ + protected $config; + /** * @param Context $context * @param \Magento\Catalog\Model\ProductFactory $productModelFactory * @param \Magento\Swatches\Helper\Data $swatchHelper + * @param \Magento\PageCache\Model\Config $config */ public function __construct( Context $context, \Magento\Catalog\Model\ProductFactory $productModelFactory, - \Magento\Swatches\Helper\Data $swatchHelper + \Magento\Swatches\Helper\Data $swatchHelper, + \Magento\PageCache\Model\Config $config ) { $this->productModelFactory = $productModelFactory; $this->swatchHelper = $swatchHelper; + $this->config = $config; parent::__construct($context); } @@ -48,14 +56,22 @@ public function __construct( public function execute() { $productMedia = []; + + /** @var \Magento\Framework\Controller\Result\Json $resultJson */ + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + + /** @var \Magento\Framework\App\ResponseInterface $response */ + $response = $this->getResponse(); + if ($productId = (int)$this->getRequest()->getParam('product_id')) { $productMedia = $this->swatchHelper->getProductMediaGallery( $this->productModelFactory->create()->load($productId) ); + $resultJson->setHeader('X-Magento-Tags', 'catalog_product_' . $productId); + + $response->setPublicHeaders($this->config->getTtl()); } - /** @var \Magento\Framework\Controller\Result\Json $resultJson */ - $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); $resultJson->setData($productMedia); return $resultJson; } 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 853eba3c98d..63dbd31751e 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 @@ -1029,12 +1029,14 @@ define([ mediaCallData.isAjax = true; $widget._XhrKiller(); $widget._EnableProductMediaLoader($this); - $widget.xhr = $.get( - $widget.options.mediaCallback, - mediaCallData, - mediaSuccessCallback, - 'json' - ).done(function () { + $widget.xhr = $.ajax({ + url: $widget.options.mediaCallback, + cache: true, + type: 'GET', + dataType: 'json', + data: mediaCallData, + success: mediaSuccessCallback + }).done(function () { $widget._XhrKiller(); }); } 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 287/701] 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 6eb5fd7e9d3..0b6630c4d6c 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 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 288/701] 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 0b6630c4d6c..bc23032903d 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 99788b8236a068d4d4a5d74ed039cc443126fd19 Mon Sep 17 00:00:00 2001 From: Vadim Justus <v.justus@techdivision.com> Date: Mon, 8 Oct 2018 11:07:08 +0200 Subject: [PATCH 289/701] 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 c2521f77ca2..a0f06cd406b 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 53e95921ea9..2bc9b474ff2 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 038174c8e52..dbb8602678d 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 b876615468b..2daebf96c6c 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 70a2c29ff9a..35959017606 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 c9ae6a96a36..397048cb046 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 9122fb00386..2f2b97bf1fa 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 ed496f3882f..0f441ee6268 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 a23d5030b82..be815c31456 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 969af6481cb..d92d2931867 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 1521b34c715..5a4c4b7ef52 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 a2fc7801b1d..5d129c199fc 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 2732048d144..90f7d993e36 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 ddb84abf3d1..dcd611a1483 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 2d011e24f41..7e3ee63d33a 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 80a7e79289c..2b0c4058293 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 8a1f7da5158..49cc746e79d 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 e504e6355a1..f57db6b2cef 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 94d4998c1e3..8be61afbbce 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 15dfbd122e9..38d3c33a9a1 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 2c41e179892..74e062b7e07 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 adaa762f327..9551e06264c 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 c315338be0d..cb8741c88b0 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 494d440eeed..eb76dd5fce0 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 36721db8748..29f7aa61ab8 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 b86c3cf13f3..c13a2560c6a 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 366cb1c3902..ef430108265 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 abe473bd968..a24a10d7433 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 5ced55edf20..3f0523e8fba 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 f9738484766..fae1ee72ac3 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 bc5fda4939a..1e826ef229f 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 1d200d27a44..b13f7e570d8 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 9ed891d1dcc..992709419fa 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 8b55b6f3279..007d744b229 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 e258878dbf07fcb14449b8253adb2f8f35b6ebcf Mon Sep 17 00:00:00 2001 From: Valentin Boyanov <val.rusev@gmail.com> Date: Mon, 8 Oct 2018 14:02:48 +0200 Subject: [PATCH 290/701] 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 dc928b4c794..4f4ed9de03e 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 <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:16:07 -0300 Subject: [PATCH 291/701] 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 67f8cadbfae..efb68fd4243 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 <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:17:39 -0300 Subject: [PATCH 292/701] 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 ea761db9026..d57525590b9 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 <thiagolimaufrj@gmail.com> Date: Mon, 8 Oct 2018 14:27:56 +0200 Subject: [PATCH 293/701] 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 5cd8b6a7d0b..556939ec112 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 <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:34:26 -0300 Subject: [PATCH 294/701] 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 be005264b7b..f9e003aca69 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,6 +294,12 @@ <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> </arguments> </type> + <type name="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter"> + <arguments> + <argument name="defaultTimezonePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE</argument> + <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> + </arguments> + </type> <type name="Magento\Framework\Locale\Resolver"> <arguments> <argument name="defaultLocalePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE</argument> diff --git a/app/etc/di.xml b/app/etc/di.xml index db979f9b763..282a0af4f46 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -146,6 +146,7 @@ <preference for="Magento\Framework\Locale\FormatInterface" type="Magento\Framework\Locale\Format" /> <preference for="Magento\Framework\Locale\ResolverInterface" type="Magento\Framework\Locale\Resolver" /> <preference for="Magento\Framework\Stdlib\DateTime\TimezoneInterface" type="Magento\Framework\Stdlib\DateTime\Timezone" /> + <preference for="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverterInterface" type="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter" /> <preference for="Magento\Framework\Communication\ConfigInterface" type="Magento\Framework\Communication\Config" /> <preference for="Magento\Framework\Module\ResourceInterface" type="Magento\Framework\Module\ModuleResource" /> <preference for="Magento\Framework\Pricing\Amount\AmountInterface" type="Magento\Framework\Pricing\Amount\Base" /> 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 00000000000..23dadc11cc6 --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Stdlib\DateTime\Timezone; + +use Magento\Framework\Locale\ResolverInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * Class LocalizedDateToUtcConverter + */ +class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterface +{ + /** + * Contains default date format + * + * @var string + */ + private $defaultFormat = 'Y-m-d H:i:s'; + + /** + * @var ResolverInterface + */ + private $localeResolver; + + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @var string + */ + private $scopeType; + + /** + * @var string + */ + private $defaultTimezonePath; + + /** + * LocalizedDateToUtcConverter constructor. + * + * @param ResolverInterface $localeResolver + */ + public function __construct( + ResolverInterface $localeResolver, + ScopeConfigInterface $scopeConfig, + $scopeType, + $defaultTimezonePath + ) + { + $this->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 00000000000..277900c46ba --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Stdlib\DateTime\Timezone; + +interface LocalizedDateToUtcConverterInterface +{ + /** + * @param string $data + * @return string + */ + public function convertLocalizedDateToUtc($date); +} \ No newline at end of file From 51e8fe7118e6734e3ee250483d9877eda2d1388a Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 10:07:17 -0300 Subject: [PATCH 295/701] 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 efb68fd4243..58c5ba8a7e0 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 f9e003aca69..be005264b7b 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,12 +294,6 @@ <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> </arguments> </type> - <type name="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter"> - <arguments> - <argument name="defaultTimezonePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE</argument> - <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> - </arguments> - </type> <type name="Magento\Framework\Locale\Resolver"> <arguments> <argument name="defaultLocalePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE</argument> diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php index 23dadc11cc6..721ed9a384d 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 <drenaud@magento.com> Date: Mon, 8 Oct 2018 08:15:23 -0500 Subject: [PATCH 296/701] 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 1f1530b08b2..224ccbce10f 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 @@ <constraint name="Magento\User\Test\Constraint\AssertUserSuccessLogin" /> </variation> <variation name="UpdateAdminUserRoleEntityTestVariation2"> - <data name="issue" xsi:type="string">MAGETWO-65658: [FT] User with restricted access can't log in to Admin in UpdateAdminUserEntityTest</data> <data name="user/dataset" xsi:type="string">default</data> <data name="role/data/resource_access" xsi:type="string">Custom</data> <data name="role/data/roles_resources" xsi:type="string">Sales</data> From 9d824af97af6d6ac34cf18b1c6086dc59ba58cdc Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 8 Oct 2018 16:39:07 +0300 Subject: [PATCH 297/701] 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 2ea3b9aaf10..98738e055ca 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 <core@magentocommerce.com> - */ 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 e0b0d066c1c..6ec1cc6c46d 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 <ogorkun@magento.com> Date: Mon, 8 Oct 2018 17:45:30 +0300 Subject: [PATCH 298/701] 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 40aa110382e..00000000000 --- a/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Config\Test\Unit\App\Config\Type; - -use Magento\Config\App\Config\Type\System; -use Magento\Framework\App\Config\ConfigSourceInterface; -use Magento\Framework\App\Config\Spi\PostProcessorInterface; -use Magento\Framework\App\Config\Spi\PreProcessorInterface; -use Magento\Framework\Cache\FrontendInterface; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Store\Model\Config\Processor\Fallback; -use Magento\Config\App\Config\Type\System\Reader; - -/** - * Test how Class process source, cache them and retrieve value by path - * @package Magento\Config\Test\Unit\App\Config\Type - */ -class SystemTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $source; - - /** - * @var PostProcessorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $postProcessor; - - /** - * @var PreProcessorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $preProcessor; - - /** - * @var Fallback|\PHPUnit_Framework_MockObject_MockObject - */ - private $fallback; - - /** - * @var FrontendInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $cache; - - /** - * @var System - */ - private $configType; - - /** - * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $serializer; - - /** - * @var Reader|\PHPUnit_Framework_MockObject_MockObject - */ - private $reader; - - public function setUp() - { - $this->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 <nathsmit@adobe.com> Date: Mon, 8 Oct 2018 09:46:05 -0500 Subject: [PATCH 299/701] 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 42697e1b66b..83e7c678ffc 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 <loganstellway@users.noreply.github.com> Date: Mon, 8 Oct 2018 09:10:59 -0700 Subject: [PATCH 300/701] 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 615a0c0f96e..8b37798f468 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 14d4016e68a6ceb9dbcb383253301917501885db Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 8 Oct 2018 11:25:29 -0500 Subject: [PATCH 301/701] 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 8be12ec6ad5..1da9ff88c9a 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 1d854331731..580de228559 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 <paliarus@adobe.com> Date: Mon, 8 Oct 2018 11:27:41 -0500 Subject: [PATCH 302/701] 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 b01f254b837..33af93db13b 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 <core@magentocommerce.com> * @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 7fe679b18d8..fdc9e5f083b 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 52735acc6d7..ff4c920d2cd 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 <nathsmit@adobe.com> Date: Mon, 8 Oct 2018 12:42:27 -0500 Subject: [PATCH 303/701] 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 1da9ff88c9a..ebedc869e14 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 580de228559..e2a156cc6fb 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 <ilagno@adobe.com> Date: Mon, 8 Oct 2018 13:54:34 -0500 Subject: [PATCH 304/701] 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 2f2029d2f13..2695948e783 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 <mlesechko@magento.com> Date: Mon, 8 Oct 2018 15:28:28 -0500 Subject: [PATCH 305/701] 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 17778c76da9..78d06afa7f0 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 @@ <element name="checkIfTabOpen" selector="//div[@id='advanced_fieldset-wrapper' and not(contains(@class,'opened'))]" type="button"/> <element name="useInLayeredNavigation" type="select" selector="#is_filterable"/> </section> + <section name="AttributeOptionsSection"> + <element name="AddOption" type="button" selector="#add_new_option_button"/> + </section> <section name="StorefrontPropertiesSection"> <element name="PageTitle" type="text" selector="//span[text()='Storefront Properties']" /> <element name="StoreFrontPropertiesTab" selector="#product_attribute_tabs_front" type="button"/> 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 00000000000..17ca306eecc --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * 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="DropdownAttributeOptionsSection"> + <element name="nthAdminLabel" 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 new file mode 100644 index 00000000000..d9942e9fc1b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.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="AdminCreateDropdownProductAttributeTest"> + <annotations> + <features value="Catalog"/> + <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"/> + <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 25e03676f68..6538af31780 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 50dcfbf3da0..5d174e71012 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 306/701] 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 94ee5a16b5b..342326e6666 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 365c8d5b9b0..423b7553ced 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 307/701] 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 9593cb98395..a433ec0953a 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 28a360adc51..eae92e1663f 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 308/701] 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 69f9fb18411..25cf8d3fb3b 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 309/701] 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 14c6154f0cb..ca8063aa578 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 00000000000..d0c2144c951 --- /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 00000000000..06d3667f4d0 --- /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 00000000000..4fa84e4e28f --- /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 310/701] 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 d9942e9fc1b..c3e0b22bc5a 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 24870a9e675..5a8dc1df860 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 cf2b91e2df2..2f8fcbdd7d4 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 a945822d92f..b2597afdf92 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 406c6dceb0331ac25e7f090090d5f2bc2faced1f Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Tue, 9 Oct 2018 07:49:30 +0300 Subject: [PATCH 311/701] MAGETWO-91388: Enable caching of AJAX requests on Varnish/Fastly --- app/code/Magento/Swatches/Controller/Ajax/Media.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swatches/Controller/Ajax/Media.php b/app/code/Magento/Swatches/Controller/Ajax/Media.php index 2616213336f..5847846f4d5 100644 --- a/app/code/Magento/Swatches/Controller/Ajax/Media.php +++ b/app/code/Magento/Swatches/Controller/Ajax/Media.php @@ -64,10 +64,11 @@ public function execute() $response = $this->getResponse(); if ($productId = (int)$this->getRequest()->getParam('product_id')) { + $product = $this->productModelFactory->create()->load($productId); $productMedia = $this->swatchHelper->getProductMediaGallery( - $this->productModelFactory->create()->load($productId) + $product ); - $resultJson->setHeader('X-Magento-Tags', 'catalog_product_' . $productId); + $resultJson->setHeader('X-Magento-Tags', implode(',', $product->getIdentities())); $response->setPublicHeaders($this->config->getTtl()); } From d866790f6cec6aeed33f4efb939756079afbf533 Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Tue, 9 Oct 2018 15:01:40 +0530 Subject: [PATCH 312/701] Added validation on maximum quantity allowed in shopping cart --- .../view/adminhtml/ui_component/product_form.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml b/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml index f8571b6e332..0a7f0fdc32d 100644 --- a/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml +++ b/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml @@ -288,7 +288,7 @@ <settings> <scopeLabel>[GLOBAL]</scopeLabel> <validation> - <rule name="validate-number" xsi:type="boolean">true</rule> + <rule name="validate-greater-than-zero" xsi:type="boolean">true</rule> </validation> <label translate="true">Maximum Qty Allowed in Shopping Cart</label> <dataScope>max_sale_qty</dataScope> 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 313/701] 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 a035c84b4ca..4d63ee4125b 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 4280663178e..950634ba2d9 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 25ccd8b32d1..d4e1f2745e3 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 6bf677151ed..7bd305f546d 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 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 314/701] 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 c6e2412f7e5..d7cfab8ccf1 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 1e11b5c5c60f54849ad0e934f036d3cb08a65575 Mon Sep 17 00:00:00 2001 From: Sam Granger <sam.granger@gmail.com> Date: Tue, 9 Oct 2018 15:36:02 +0200 Subject: [PATCH 315/701] Do not output html for region field due to xss --- .../web/template/shipping-address/address-renderer/default.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 05ced7a978f..2a5dc27328a 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 @@ -8,7 +8,7 @@ <text args="address().prefix"/> <text args="address().firstname"/> <text args="address().middlename"/> <text args="address().lastname"/> <text args="address().suffix"/><br/> <text args="_.values(address().street).join(', ')"/><br/> - <text args="address().city "/>, <span html="address().region"></span> <text args="address().postcode"/><br/> + <text args="address().city "/>, <span text="address().region"></span> <text args="address().postcode"/><br/> <text args="getCountryName(address().countryId)"/><br/> <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> From 880622b3f6b827d30f4bbb6677b7d7fb5fc9caaa Mon Sep 17 00:00:00 2001 From: Sam Granger <sam.granger@gmail.com> Date: Tue, 9 Oct 2018 15:36:44 +0200 Subject: [PATCH 316/701] Do not output html for region field due to xss --- .../template/shipping-information/address-renderer/default.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 97286a28552..541413955cb 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -8,7 +8,7 @@ <text args="address().prefix"/> <text args="address().firstname"/> <text args="address().middlename"/> <text args="address().lastname"/> <text args="address().suffix"/><br/> <text args="_.values(address().street).join(', ')"/><br/> - <text args="address().city "/>, <span html="address().region"></span> <text args="address().postcode"/><br/> + <text args="address().city "/>, <span text="address().region"></span> <text args="address().postcode"/><br/> <text args="getCountryName(address().countryId)"/><br/> <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> From f9bde4091d147c65944f2e08cad1c84650ca952f Mon Sep 17 00:00:00 2001 From: Sam Granger <sam.granger@gmail.com> Date: Tue, 9 Oct 2018 15:37:48 +0200 Subject: [PATCH 317/701] Do not output html for region field due to xss --- .../view/frontend/web/template/billing-address/details.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index cc1d960bbe4..ea521b3a8af 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -8,7 +8,7 @@ <text args="currentBillingAddress().prefix"/> <text args="currentBillingAddress().firstname"/> <text args="currentBillingAddress().middlename"/> <text args="currentBillingAddress().lastname"/> <text args="currentBillingAddress().suffix"/><br/> <text args="_.values(currentBillingAddress().street).join(', ')"/><br/> - <text args="currentBillingAddress().city "/>, <span html="currentBillingAddress().region"></span> <text args="currentBillingAddress().postcode"/><br/> + <text args="currentBillingAddress().city "/>, <span text="currentBillingAddress().region"></span> <text args="currentBillingAddress().postcode"/><br/> <text args="getCountryName(currentBillingAddress().countryId)"/><br/> <a if="currentBillingAddress().telephone" attr="'href': 'tel:' + currentBillingAddress().telephone" text="currentBillingAddress().telephone"></a><br/> 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 318/701] 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 683a18d0e4e..b9233c8b702 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 319/701] 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 c53b2fa6e2a..b29ebe7d57d 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 320/701] 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 8b37798f468..e64956dce17 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 99b04aa7998faded2889dc706ee57891431c4d99 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 9 Oct 2018 18:27:53 +0300 Subject: [PATCH 321/701] Covering the AssignOrderToCustomerObserver by Unit Test --- .../AssignOrderToCustomerObserverTest.php | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php diff --git a/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php new file mode 100644 index 00000000000..c6e02151b9b --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Test\Unit\Observer; + +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Observer\AssignOrderToCustomerObserver; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; + +/** + * Class AssignOrderToCustomerObserverTest + */ +class AssignOrderToCustomerObserverTest extends TestCase +{ + /** @var AssignOrderToCustomerObserver */ + protected $sut; + + /** @var OrderRepositoryInterface|PHPUnit_Framework_MockObject_MockObject */ + protected $orderRepositoryMock; + + /** + * Set Up + */ + protected function setUp() + { + $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->sut = new AssignOrderToCustomerObserver($this->orderRepositoryMock); + } + + /** + * Test assigning order to customer after issuing guest order + * + * @dataProvider getCustomerIds + * @param null|int $customerId + * @return void + */ + public function testAssignOrderToCustomerAfterGuestOrder($customerId) + { + $orderId = 1; + /** @var Observer|PHPUnit_Framework_MockObject_MockObject $observerMock */ + $observerMock = $this->createMock(Observer::class); + /** @var Event|PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->getMockBuilder(Event::class)->disableOriginalConstructor() + ->setMethods(['getData']) + ->getMock(); + /** @var CustomerInterface|PHPUnit_Framework_MockObject_MockObject $customerMock */ + $customerMock = $this->createMock(CustomerInterface::class); + /** @var OrderInterface|PHPUnit_Framework_MockObject_MockObject $orderMock */ + $orderMock = $this->getMockBuilder(OrderInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock); + $eventMock->expects($this->any())->method('getData') + ->willReturnMap([ + ['delegate_data', null, ['__sales_assign_order_id' => $orderId]], + ['customer_data_object', null, $customerMock] + ]); + $orderMock->expects($this->once())->method('getCustomerId')->willReturn($customerId); + $this->orderRepositoryMock->expects($this->once())->method('get')->with($orderId) + ->willReturn($orderMock); + if (!$customerId) { + $this->orderRepositoryMock->expects($this->once())->method('save')->with($orderMock); + $this->sut->execute($observerMock); + return ; + } + + $this->orderRepositoryMock->expects($this->never())->method('save')->with($orderMock); + $this->sut->execute($observerMock); + } + + /** + * Customer id assigned to order + * + * @return array + */ + public function getCustomerIds() + { + return [[null, 1]]; + } +} 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 322/701] 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 a1aacf6e803..9b20a782c38 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 323/701] 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 0a692a9b868..c2a0d4dab1f 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 324/701] 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 5a8dc1df860..7adc0dcfdf4 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 2f8fcbdd7d4..8b513bc8532 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 57d775cdeb7..7ecaeb5ea7b 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 5e4a5cc45fe..f4adb9dec12 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 1f70ad0f7df..101e9f596be 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 5b7a80bb38d..10f6703f583 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 b2597afdf92..a945822d92f 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 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 325/701] 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 00000000000..a2391dda548 --- /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 00000000000..7558b13d624 --- /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 00000000000..4d97dee56f0 --- /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 cb53a2a4f38..7a5c5e1d158 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 c8ff851ae54..23171307588 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 326/701] 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 c38f182f275..aa937851168 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 6ef6ddd0e73..69af6f4fb1b 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 27fa5eb783b..76b060015c5 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 8fa77a7388b..789978d8180 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 327/701] 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 5db3933dd11..1da7b99c6d8 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 00000000000..d11a3fa6e8a --- /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 946bfe13f34..52e980052a8 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 bf1ec774829..53ab66c7ef2 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 00000000000..7e60039e868 --- /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 328/701] 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 23687484f10..5de3d40fff9 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 17ca306eecc..0f438540603 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 c3e0b22bc5a..525f81de6c4 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 5d174e71012..b03f7718759 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 101e9f596be..ab8c29889ea 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 10f6703f583..f806674d297 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 fdc154d40d1d5cf3637a8f307b97c75b00370348 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 11:24:11 -0400 Subject: [PATCH 329/701] Setup Wizard > Menu Logo Bugfix --- setup/view/magento/setup/navigation/side-menu.phtml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/setup/view/magento/setup/navigation/side-menu.phtml b/setup/view/magento/setup/navigation/side-menu.phtml index 58d12a4de44..f34a6c7c72e 100644 --- a/setup/view/magento/setup/navigation/side-menu.phtml +++ b/setup/view/magento/setup/navigation/side-menu.phtml @@ -20,12 +20,8 @@ ng-show="<?= implode( '&&', $expressions) ?>" > <nav class="admin__menu" ng-controller="mainController"> - <span - class="logo logo-static" - data-edition="Community Edition"> - <img class="logo-img" - src="./pub/images/logo.svg" - alt="Magento Admin Panel"> + <span class="logo logo-static" data-edition="Community Edition"> + <img class="logo-img" src="<?= $this->basePath() ?>/pub/images/logo.svg" alt="Magento Admin Panel"> </span> <ul id="nav" role="menubar"> <li class="item-home level-0" ng-class="{_active: $state.current.name === 'root.home'}"> From fe3fd54c10a2e198684e418d743e50cd03fc99b8 Mon Sep 17 00:00:00 2001 From: Krzysztof Wolowski <hello@magently.com> Date: Tue, 18 Sep 2018 11:24:26 +0200 Subject: [PATCH 330/701] Fix table rate failing for zip+4 address #17770 --- .../Carrier/Tablerate/RateQuery.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php index 5b03ef0cb02..aa561bf4499 100644 --- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php +++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php @@ -42,6 +42,7 @@ public function prepareSelect(\Magento\Framework\DB\Select $select) ') OR (', [ "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :postcode", + "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :postcode_prefix", "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = ''", // Handle asterisk in dest_zip field @@ -51,7 +52,7 @@ public function prepareSelect(\Magento\Framework\DB\Select $select) "dest_country_id = '0' AND dest_region_id = 0 AND dest_zip = '*'", "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = ''", "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = :postcode", - "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = '*'" + "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = :postcode_prefix" ] ) . ')'; $select->where($orWhere); @@ -85,6 +86,7 @@ public function getBindings() ':country_id' => $this->request->getDestCountryId(), ':region_id' => (int)$this->request->getDestRegionId(), ':postcode' => $this->request->getDestPostcode(), + ':postcode_prefix' => $this->getDestPostcodePrefix() ]; // Render condition by condition name @@ -112,4 +114,18 @@ public function getRequest() { return $this->request; } + + /** + * Returns the entire postcode if it contains no dash + * or the part of it prior to the dash in the other case + * @return string + */ + private function getDestPostcodePrefix() + { + if (!preg_match("/^(.+)-(.+)$/", $this->request->getDestPostcode(), $zipParts)) { + return $this->request->getDestPostcode(); + } + + return $zipParts[1]; + } } From cfc2339f563c68bc3593f058670e85a729bcf85c Mon Sep 17 00:00:00 2001 From: Krzysztof Wolowski <hello@magently.com> Date: Mon, 10 Sep 2018 13:12:15 +0200 Subject: [PATCH 331/701] Fix category tree in cart price rule #17493 --- .../Catalog/view/adminhtml/web/js/category-checkbox-tree.js | 1 + .../Controller/Adminhtml/Promo/Widget/CategoriesJson.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/category-checkbox-tree.js b/app/code/Magento/Catalog/view/adminhtml/web/js/category-checkbox-tree.js index 2359d1499f8..0ec404a769f 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/category-checkbox-tree.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/category-checkbox-tree.js @@ -225,6 +225,7 @@ define([ categoryLoader.on('beforeload', function (treeLoader, node) { treeLoader.baseParams.id = node.attributes.id; + treeLoader.baseParams.selected = options.jsFormObject.updateElement.value; }); categoryLoader.on('load', function () { diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php index d049d74bd26..3d1ac9744ef 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php @@ -77,10 +77,11 @@ public function execute() if (!($category = $this->_initCategory())) { return; } + $selected = $this->getRequest()->getPost('selected', ''); $block = $this->_view->getLayout()->createBlock( \Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree::class )->setCategoryIds( - [$categoryId] + explode(',', $selected) ); $this->getResponse()->representJson( $block->getTreeJson($category) 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 332/701] 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 b9233c8b702..30ea9da1dd6 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 4e54af60c16d3e36bb486dfa500d75d665d97dc0 Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Wed, 10 Oct 2018 11:05:24 +0200 Subject: [PATCH 333/701] Fixed typo from filed to field --- app/code/Magento/Catalog/Model/ResourceModel/Category.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php index 1523809d9cc..5b420c33b31 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php @@ -923,7 +923,7 @@ public function changeParent( $childrenCount = $this->getChildrenCount($category->getId()) + 1; $table = $this->getEntityTable(); $connection = $this->getConnection(); - $levelFiled = $connection->quoteIdentifier('level'); + $levelField = $connection->quoteIdentifier('level'); $pathField = $connection->quoteIdentifier('path'); /** @@ -963,7 +963,7 @@ public function changeParent( $newPath . '/' ) . ')' ), - 'level' => new \Zend_Db_Expr($levelFiled . ' + ' . $levelDisposition) + 'level' => new \Zend_Db_Expr($levelField . ' + ' . $levelDisposition) ], [$pathField . ' LIKE ?' => $category->getPath() . '/%'] ); 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 334/701] 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 556939ec112..b5940e36aa7 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 028dca29f3b8e760a02953fa2650174bba65956d Mon Sep 17 00:00:00 2001 From: peterjaap <peterjaap@elgentos.nl> Date: Wed, 10 Oct 2018 11:39:11 +0200 Subject: [PATCH 335/701] Added missing throw tag for exception to docblock of construct --- app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php index 72fd8c3a63f..bb81f9ebb47 100644 --- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php +++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php @@ -61,6 +61,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory * @param \Magento\OfflineShipping\Model\ResourceModel\Carrier\TablerateFactory $tablerateFactory * @param array $data + * @throws LocalizedException * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function __construct( 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 336/701] 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 b546237b825..e85548b4222 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 337/701] 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 e85548b4222..353f3c8e1f0 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 338/701] 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 353f3c8e1f0..2373b5285ed 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 339/701] 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 e67d9f8ad18..5e70eb491b5 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 340/701] 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 7c56c266a64..2aae8fd8085 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 237d7660da9..0286cc184f0 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 00000000000..8ea6ab92a02 --- /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 341/701] 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 fb18fa1bfab..d0bc9591265 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 66807400903ad21d6269b6c1db9a8fab62617267 Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Wed, 10 Oct 2018 14:08:04 +0300 Subject: [PATCH 342/701] MAGETWO-91388: Enable caching of AJAX requests on Varnish/Fastly --- .../Swatches/Controller/Ajax/Media.php | 2 +- .../Test/Unit/Controller/Ajax/MediaTest.php | 22 ++++++++++++++++++- app/code/Magento/Swatches/composer.json | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Swatches/Controller/Ajax/Media.php b/app/code/Magento/Swatches/Controller/Ajax/Media.php index 5847846f4d5..7692245e9b2 100644 --- a/app/code/Magento/Swatches/Controller/Ajax/Media.php +++ b/app/code/Magento/Swatches/Controller/Ajax/Media.php @@ -12,7 +12,7 @@ /** * Class Media */ -class Media extends \Magento\Framework\App\Action\Action +class Media extends \Magento\Framework\App\Action\Action implements \Magento\Framework\App\Action\HttpGetActionInterface { /** * @var \Magento\Catalog\Model\Product Factory diff --git a/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php b/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php index 7a110c63da7..5a11e2787bc 100644 --- a/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php @@ -20,6 +20,9 @@ class MediaTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Catalog\Model\ProductFactory|\PHPUnit_Framework_MockObject_MockObject */ private $productModelFactoryMock; + /** @var \Magento\PageCache\Model\Config|\PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */ private $productMock; @@ -29,6 +32,9 @@ class MediaTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ private $requestMock; + /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $responseMock; + /** @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject */ private $resultFactory; @@ -57,11 +63,20 @@ protected function setUp() \Magento\Catalog\Model\ProductFactory::class, ['create'] ); + $this->config = $this->createMock(\Magento\PageCache\Model\Config::class); + $this->config->method('getTtl')->willReturn(1); + $this->productMock = $this->createMock(\Magento\Catalog\Model\Product::class); $this->contextMock = $this->createMock(\Magento\Framework\App\Action\Context::class); $this->requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class); $this->contextMock->method('getRequest')->willReturn($this->requestMock); + $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) + ->disableOriginalConstructor() + ->setMethods(['setPublicHeaders']) + ->getMockForAbstractClass(); + $this->responseMock->method('setPublicHeaders')->willReturnSelf(); + $this->contextMock->method('getResponse')->willReturn($this->responseMock); $this->resultFactory = $this->createPartialMock(\Magento\Framework\Controller\ResultFactory::class, ['create']); $this->contextMock->method('getResultFactory')->willReturn($this->resultFactory); @@ -73,7 +88,8 @@ protected function setUp() [ 'context' => $this->contextMock, 'swatchHelper' => $this->swatchHelperMock, - 'productModelFactory' => $this->productModelFactoryMock + 'productModelFactory' => $this->productModelFactoryMock, + 'config' => $this->config ] ); } @@ -86,6 +102,10 @@ public function testExecute() ->method('load') ->with(59) ->willReturn($this->productMock); + $this->productMock + ->expects($this->once()) + ->method('getIdentities') + ->willReturn(['tags']); $this->productModelFactoryMock ->expects($this->once()) diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json index 0940003b6a7..09d3e05008a 100644 --- a/app/code/Magento/Swatches/composer.json +++ b/app/code/Magento/Swatches/composer.json @@ -13,6 +13,7 @@ "magento/module-configurable-product": "*", "magento/module-customer": "*", "magento/module-eav": "*", + "magento/module-page-cache": "*", "magento/module-media-storage": "*", "magento/module-store": "*", "magento/module-theme": "*" 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 343/701] 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 68dc8d753b5..145d9e48a8a 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 344/701] 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 2aae8fd8085..6f8b2248d8d 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 345/701] 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 99ca7991e5e..6ce33f3be36 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 65cfb295e3ec4963c03b6c5bdcff39d5fa4c6501 Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Tue, 2 Oct 2018 18:25:45 +0300 Subject: [PATCH 346/701] MAGETWO-94671: Product Export fails --- .../Magento/CatalogImportExport/Model/Export/Product.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 23aa8d65ddb..41e74837f4c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -520,10 +520,13 @@ protected function getMediaGallery(array $productIds) if (empty($productIds)) { return []; } + + $productEntityJoinField = $this->getProductEntityLinkField(); + $select = $this->_connection->select()->from( ['mgvte' => $this->_resourceModel->getTableName('catalog_product_entity_media_gallery_value_to_entity')], [ - "mgvte.{$this->getProductEntityLinkField()}", + "mgvte.$productEntityJoinField", 'mgvte.value_id' ] )->joinLeft( @@ -535,7 +538,7 @@ protected function getMediaGallery(array $productIds) ] )->joinLeft( ['mgv' => $this->_resourceModel->getTableName('catalog_product_entity_media_gallery_value')], - '(mg.value_id = mgv.value_id)', + "(mg.value_id = mgv.value_id) and (mgvte.$productEntityJoinField = mgv.$productEntityJoinField)", [ 'mgv.label', 'mgv.position', From 1766f07493612123a4b5bddbc3652d55c168cb95 Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Tue, 2 Oct 2018 18:40:42 +0300 Subject: [PATCH 347/701] MAGETWO-94671: Product Export fails --- app/code/Magento/CatalogImportExport/Model/Export/Product.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 41e74837f4c..b2c3aeb096b 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -546,14 +546,14 @@ protected function getMediaGallery(array $productIds) 'mgv.store_id', ] )->where( - "mgvte.{$this->getProductEntityLinkField()} IN (?)", + "mgvte.$productEntityJoinField IN (?)", $productIds ); $rowMediaGallery = []; $stmt = $this->_connection->query($select); while ($mediaRow = $stmt->fetch()) { - $rowMediaGallery[$mediaRow[$this->getProductEntityLinkField()]][] = [ + $rowMediaGallery[$mediaRow[$productEntityJoinField]][] = [ '_media_attribute_id' => $mediaRow['attribute_id'], '_media_image' => $mediaRow['filename'], '_media_label' => $mediaRow['label'], 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 348/701] 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 00000000000..8d4aea135ea --- /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 32c901afe8e..c0d10c720f6 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 d6a5cb1cbc2..7449c9ea788 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 37e4c7b310a..31e89d424e3 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 6d3ad849125..14395bb9afe 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 dd430f8a033..00000000000 --- 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 e43a03e72d8..095e64ddf76 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 6fefe18cf89..00000000000 --- 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 e7a2d17586a..37ef6020886 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 349/701] 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 c0d10c720f6..a7add0ad87b 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 7449c9ea788..fef4999a117 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 31e89d424e3..100ad37273c 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 14395bb9afe..a76b72bfa41 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 095e64ddf76..9ffec68780a 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 350/701] 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 f8a1707e6c2..b91f796e6a1 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 09baa0e465469c59a0f649c46e607174315d6b83 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 10 Oct 2018 22:44:12 +0300 Subject: [PATCH 351/701] magento-engcom/magento2ce#2237: Fixed static tests failures --- .../Model/ResourceModel/Eav/Attribute.php | 41 ++++++++++--------- .../Product/Indexer/Eav/Source.php | 2 + .../ResourceModel/Product/Option/Value.php | 1 + .../Adminhtml/Promo/Widget/CategoriesJson.php | 7 +++- .../Model/System/Currencysymbol.php | 2 +- ...ductAttributeFormBuildFrontTabObserver.php | 5 +++ .../Carrier/Tablerate/RateQuery.php | 13 +++++- .../backend/web/css/source/forms/_fields.less | 4 ++ 8 files changed, 51 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php index 806da8f81e2..707ebbb2964 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Eav/Attribute.php @@ -167,6 +167,8 @@ public function __construct( } /** + * Init model + * * @return void */ protected function _construct() @@ -362,6 +364,7 @@ public function getStoreId() /** * Retrieve apply to products array + * * Return empty array if applied to all products * * @return string[] @@ -507,8 +510,8 @@ public function getIndexType() } /** + * @inheritdoc * @codeCoverageIgnoreStart - * {@inheritdoc} */ public function getIsWysiwygEnabled() { @@ -516,7 +519,7 @@ public function getIsWysiwygEnabled() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsHtmlAllowedOnFront() { @@ -524,7 +527,7 @@ public function getIsHtmlAllowedOnFront() } /** - * {@inheritdoc} + * @inheritdoc */ public function getUsedForSortBy() { @@ -532,7 +535,7 @@ public function getUsedForSortBy() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsFilterable() { @@ -540,7 +543,7 @@ public function getIsFilterable() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsFilterableInSearch() { @@ -548,7 +551,7 @@ public function getIsFilterableInSearch() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsUsedInGrid() { @@ -556,7 +559,7 @@ public function getIsUsedInGrid() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsVisibleInGrid() { @@ -564,7 +567,7 @@ public function getIsVisibleInGrid() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsFilterableInGrid() { @@ -572,7 +575,7 @@ public function getIsFilterableInGrid() } /** - * {@inheritdoc} + * @inheritdoc */ public function getPosition() { @@ -580,7 +583,7 @@ public function getPosition() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsSearchable() { @@ -588,7 +591,7 @@ public function getIsSearchable() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsVisibleInAdvancedSearch() { @@ -596,7 +599,7 @@ public function getIsVisibleInAdvancedSearch() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsComparable() { @@ -604,7 +607,7 @@ public function getIsComparable() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsUsedForPromoRules() { @@ -612,7 +615,7 @@ public function getIsUsedForPromoRules() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsVisibleOnFront() { @@ -620,7 +623,7 @@ public function getIsVisibleOnFront() } /** - * {@inheritdoc} + * @inheritdoc */ public function getUsedInProductListing() { @@ -628,7 +631,7 @@ public function getUsedInProductListing() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIsVisible() { @@ -638,7 +641,7 @@ public function getIsVisible() //@codeCoverageIgnoreEnd /** - * {@inheritdoc} + * @inheritdoc */ public function getScope() { @@ -720,7 +723,7 @@ public function setPosition($position) /** * Set apply to value for the element * - * @param string []|string + * @param string[]|string $applyTo * @return $this */ public function setApplyTo($applyTo) @@ -829,7 +832,7 @@ public function setScope($scope) } /** - * {@inheritdoc} + * @inheritdoc */ public function afterDelete() { 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 77836c58d50..3a61e7e3644 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 @@ -330,6 +330,8 @@ public function getIdxTable($table = null) } /** + * Save data from select + * * @param \Magento\Framework\DB\Select $select * @param array $options * @return void diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php index 5ffc9fbd575..318c9bd132c 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php @@ -85,6 +85,7 @@ protected function _construct() /** * Proceed operations after object is saved + * * Save options store data * * @param AbstractModel $object diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php index 3d1ac9744ef..18a58c0f854 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -9,8 +8,12 @@ use Magento\Backend\App\Action\Context; use Magento\Catalog\Model\Category; use Magento\Framework\Registry; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; -class CategoriesJson extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Widget +/** + * Categories json widget for catalog rule + */ +class CategoriesJson extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Widget implements HttpPostActionInterface { /** * Core registry diff --git a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php index 518e7fcf418..6c7019986cc 100644 --- a/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php +++ b/app/code/Magento/CurrencySymbol/Model/System/Currencysymbol.php @@ -187,7 +187,7 @@ public function getCurrencySymbolsData() /** * Save currency symbol to config * - * @param $symbols array + * @param array $symbols * @return $this */ public function setCurrencySymbolsData($symbols = []) 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 fc1edeb1e23..1bb601e3a4e 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -11,6 +11,9 @@ use Magento\Framework\Module\Manager; use Magento\Framework\Event\ObserverInterface; +/** + * Observer for Product Attribute Form + */ class ProductAttributeFormBuildFrontTabObserver implements ObserverInterface { /** @@ -34,6 +37,8 @@ public function __construct(Manager $moduleManager, Source\Yesno $optionList) } /** + * Execute + * * @param \Magento\Framework\Event\Observer $observer * @return void */ diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php index aa561bf4499..f7105b8e547 100644 --- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php +++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php @@ -6,6 +6,9 @@ namespace Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate; +/** + * Query builder for table rate + */ class RateQuery { /** @@ -24,6 +27,8 @@ public function __construct( } /** + * Prepare select + * * @param \Magento\Framework\DB\Select $select * @return \Magento\Framework\DB\Select */ @@ -77,6 +82,8 @@ public function prepareSelect(\Magento\Framework\DB\Select $select) } /** + * Returns query bindings + * * @return array */ public function getBindings() @@ -108,6 +115,8 @@ public function getBindings() } /** + * Returns rate request + * * @return \Magento\Quote\Model\Quote\Address\RateRequest */ public function getRequest() @@ -116,8 +125,8 @@ public function getRequest() } /** - * Returns the entire postcode if it contains no dash - * or the part of it prior to the dash in the other case + * Returns the entire postcode if it contains no dash or the part of it prior to the dash in the other case + * * @return string */ private function getDestPostcodePrefix() 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 4ce119e74b1..b3e4a91180b 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 @@ -59,7 +59,11 @@ } .abs-field-no-label { + /** + *@codingStandardsIgnoreStart + */ #mix-grid .return_length(@field-label-grid__column, @field-grid__columns, '+'); + //@codingStandardsIgnoreEnd margin-left: @_length; } 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 352/701] 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 760e0785a78..bd47391e2ed 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 353/701] 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 eef35abcc97..41b1e0d8118 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 6ea8d8a1672..2034c99fb4a 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 354/701] 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 37ea99d652f..3ff880c64e6 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 00000000000..cff605d7c90 --- /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 355/701] 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 b83bb97301b..1ac7675b102 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 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 356/701] 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 5d326e7c01d..ed6a4d1ad72 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 357/701] #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 62a2fa1c47e..cab923da492 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 358/701] 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 cab923da492..1cd0c41abb5 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 359/701] 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 b1af46b8055..038bea86e7d 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 5681284c06c78798e51b7c4bae1820e9f80e1828 Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Thu, 11 Oct 2018 11:16:04 +0300 Subject: [PATCH 360/701] MAGETWO-94671: Product Export fails --- .../Model/Export/Product.php | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index b2c3aeb096b..f90eba0bba2 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -349,12 +349,13 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity private $productEntityLinkField; /** + * Product constructor. * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Eav\Model\Config $config * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection + * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory * @param \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig * @param \Magento\Catalog\Model\ResourceModel\ProductFactory $productFactory * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $attrSetColFactory @@ -363,10 +364,10 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity * @param \Magento\Catalog\Model\ResourceModel\Product\Option\CollectionFactory $optionColFactory * @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeColFactory * @param Product\Type\Factory $_typeFactory - * @param \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider - * @param \Magento\CatalogImportExport\Model\Export\RowCustomizerInterface $rowCustomizer + * @param ProductEntity\LinkTypeProvider $linkTypeProvider + * @param RowCustomizerInterface $rowCustomizer * @param array $dateAttrCodes - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, @@ -695,7 +696,9 @@ protected function updateDataWithCategoryColumns(&$dataRow, &$rowCategories, $pr } /** - * {@inheritdoc} + * Get header columns + * + * @return string[] */ public function _getHeaderColumns() { @@ -754,7 +757,10 @@ protected function _getExportMainAttrCodes() } /** - * {@inheritdoc} + * Get entity collection + * + * @param bool $resetCollection + * @return \Magento\Framework\Data\Collection\AbstractDb */ protected function _getEntityCollection($resetCollection = false) { @@ -861,7 +867,10 @@ public function export() } /** - * {@inheritdoc} + * Apply filter to collection and add not skipped attributes to select. + * + * @param \Magento\Eav\Model\Entity\Collection\AbstractCollection $collection + * @return \Magento\Eav\Model\Entity\Collection\AbstractCollection * @since 100.2.0 */ protected function _prepareEntityCollection(\Magento\Eav\Model\Entity\Collection\AbstractCollection $collection) @@ -923,8 +932,7 @@ protected function getExportData() } /** - * Load products' data from the collection - * and filter it (if needed). + * Load products' data from the collection and filter it (if needed). * * @return array Keys are product IDs, values arrays with keys as store IDs * and values as store-specific versions of Product entity. @@ -1066,6 +1074,8 @@ private function wrapValue($value) } /** + * Collect multi raw data from + * * @return array */ protected function collectMultirawData() @@ -1107,6 +1117,8 @@ protected function collectMultirawData() } /** + * Check the current data has multiselect value + * * @param \Magento\Catalog\Model\Product $item * @param int $storeId * @return bool @@ -1119,6 +1131,8 @@ protected function hasMultiselectData($item, $storeId) } /** + * Collect multiselect values based on value + * * @param \Magento\Catalog\Model\Product $item * @param string $attrCode * @param int $storeId @@ -1143,6 +1157,8 @@ protected function collectMultiselectValues($item, $attrCode, $storeId) } /** + * Check attribute is valid + * * @param string $code * @param mixed $value * @return bool @@ -1162,6 +1178,8 @@ protected function isValidAttributeValue($code, $value) } /** + * Append multi row data + * * @param array $dataRow * @param array $multiRawData * @return array @@ -1291,6 +1309,8 @@ private function appendMultirowData(&$dataRow, $multiRawData) } /** + * Add multi row data to export + * * @deprecated 100.1.0 * @param array $dataRow * @param array $multiRawData @@ -1338,6 +1358,8 @@ protected function _customHeadersMapping($rowData) } /** + * Convert option row to cell string + * * @param array $option * @return string */ 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 361/701] #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 3527d4f6cdf..acfd321ea09 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 362/701] =?UTF-8?q?NGCOM-2997:=20#4942=20and=20bundle=20ch?= =?UTF-8?q?eckbox=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 1cd0c41abb5..fa488b073f5 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 f94cd83f4e7..4945308c26c 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 363/701] 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 145d9e48a8a..af4fa9dd3e6 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 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 364/701] 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 b2f96855388..b5ca0895d6d 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 365/701] 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 af4fa9dd3e6..4e55484e5dd 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 3b0b56013028082282bd6b86a4e291bf5a5b2f31 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 25 Sep 2018 16:35:51 -0500 Subject: [PATCH 366/701] 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 22d29eae165..1a7adcd531c 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 848e094ca48c27af2b9ab929d7bd249e7e79fec9 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 27 Sep 2018 14:15:04 -0500 Subject: [PATCH 367/701] 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 6e3e7f7d171..3ee6cef4773 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 8979a7e9f088edf8c7d3ae0ceee19c509f05c317 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 19 Sep 2018 10:16:13 -0500 Subject: [PATCH 368/701] 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 4765a54cf0f..6076af70f86 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -199,6 +199,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 75cc84f36adead11aedaa5d7fb162ad8304c1b08 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 20 Sep 2018 10:14:01 -0500 Subject: [PATCH 369/701] 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 6076af70f86..ba116e01396 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -207,14 +207,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 d7df4680663ad327c8f0c9d52898895e058a8592 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 17 Sep 2018 15:20:05 -0500 Subject: [PATCH 370/701] 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 f016b0dbefd..c81274337f4 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 c7080157e64310b85785c7df84a23f2cb0a39f67 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Thu, 4 Oct 2018 12:01:16 +0200 Subject: [PATCH 371/701] 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 4590af4f2d6..03012918f4a 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 81805746ba78819d13b569852a94613a511e323b Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 5 Oct 2018 09:37:14 -0500 Subject: [PATCH 372/701] MC-3857: Products Content Type is broken on Dynamic Block page - fix static test failures --- app/code/Magento/CatalogWidget/Block/Product/ProductsList.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index ba116e01396..b138ef765a7 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -397,7 +397,6 @@ public function getTitle() * Returns PriceCurrencyInterface instance * * @return PriceCurrencyInterface - * * @deprecated 100.2.0 */ private function getPriceCurrency() 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 373/701] 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 1ac7675b102..830b974e5ed 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 374/701] 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 ec21e06976b..9882a1ce9b0 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 375/701] 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 9cdc90bc46b..78c485c5bb6 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 376/701] 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 25519e5c830..a2db0f43061 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 677356e1014be1d6577c4ea041f9b535fb800c4e Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Thu, 11 Oct 2018 15:29:11 +0300 Subject: [PATCH 377/701] 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 8acf170d43c..57e29d11495 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 acfd321ea09..3527d4f6cdf 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 defec8bb1c1a053ab3af79dfdb1e0fa91387b9ac Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Thu, 11 Oct 2018 15:53:23 +0300 Subject: [PATCH 378/701] MAGETWO-94671: Product Export fails --- app/code/Magento/CatalogImportExport/Model/Export/Product.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index f90eba0bba2..096d8495d70 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -20,6 +20,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @since 100.0.2 */ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity 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 379/701] 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 3b02f534648..f289b97b91d 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 380/701] 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 37c0eb6ea12..d8f6bc3e4a7 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 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 381/701] 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 71b1392d539..e762a89dc15 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 0567c61f0db..c96df9cdd31 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 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 382/701] 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 cff605d7c90..0ca1d72a3ae 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 383/701] 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 830b974e5ed..497ed2fd499 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 b29eee9a47f..5a00f8bfbee 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 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 384/701] 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 37c0eb6ea12..03f3e93bb30 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 385/701] 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 04cbeb5bc59..6b2c3850292 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 00000000000..473b0c16630 --- /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 386/701] 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 3791b28917e..a63072f5a3d 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 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 387/701] 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 5ed6ba0f79f..1ef7403e94c 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 388/701] 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 2958708e51d..0244775fad0 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 389/701] 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 d8253505c42..54f7aa97053 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 c69fa97efc0..51062da6f2e 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 49233cb4b42..44145f92904 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 c1aeebfca52..a9083cb320c 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 30aa26b26ed..9d95b01b2f8 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 7ac69f82f79..1adf2d22be4 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 eb04ce04f07..42d84f13b9a 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 ca897bffe8b..e8b8c6cd9e6 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 83854c4a767..ae7d0eed739 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 60a19074317..c43aaf8d3c9 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 f98f7b40843..4e1944bed9b 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 6567beba198..8fb27a9dd1e 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 390/701] 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 916bfdd6020..79d03b6fad2 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 a58ee2bcb18..d3c5aa5aaa6 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 72379c3819d..949554506d5 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 8eeceba8209..85b1b136e78 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 1186dd6936c..b064eec3338 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 ca19e5e995c..1e609cdeac2 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 697fab65079..1690d9f3936 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 01108358da2..7e3de7534e8 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 21d67bdf53c..b65a0d6ca47 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 e99d75c25f5..9ea103e23d2 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 5fa5b0333c6..b168e728117 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 09591532f9f..e693807760e 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 e16f23ca09d..12ce0d63ac6 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 8771c92039f..e064f46655d 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 da7cfa1ea98..b066c118ef7 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 cfddc07bcee..db467552615 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 0eac2e3309a..b20fdde7c52 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 11bd746eb71..897b67d8d46 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 47d991274b9..4a5802dd44e 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 90220676e00..4fa2474d225 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 cba29ad6287..844cfc9f874 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 481b2252dbf..46828ab7a8c 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 840f9462218..e4cdb04052e 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 29fc6806b50..aced57c1001 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 78ff7b04fd3..547526be43c 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 6a817bcbddf..565b5eeef33 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 b18269335bc..c251265c694 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 ed5640d4227..ba41a535f45 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 4d255705bf7..756d9edc6fb 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 41d6b14b6a4..413af718141 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 3ca0e94852a..4e8854fad35 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 72495e68a26..0a340e7f76d 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 9a3c5596574..066d1832aef 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 5f4e0027a85..7dc74f39709 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 5146177783a..908d6ccc507 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 f275c4f1b1c..5455b91d730 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 80074ffc5e2..ce02bef244f 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 787866a2bca..6f8b63955a0 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 d4ee9542c59..d14bfdcb548 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 3ac755de2b8..c89ef50f3cb 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 308d1d56430..9a2776ac20b 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 ec3b88ad245..3da989333d6 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 a8bb8e255f2..32d134cfe8d 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 430b775337b..eb0bbc6f3b5 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 73c20406f35..fbd35455c22 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 fb4ff5d298c..e97a6690dbc 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 8e3758817ad..fb44e4037bc 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 a2446264d48..6796a1f995e 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 b694cd48a07..6ed3338c040 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 ba103e060ae..cb10de7bdcb 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 be8507838e4..9161a30f9bc 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 70fefec13dd..59ee4bb045b 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 8a269d8d95b..776dab93c2d 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 190d3a04ed2..1cc417f891c 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 4a7612fcc30..70aa749fd85 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 dcb977bfa2a..60ee2d57060 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 4a282faf317..208f6b39b9e 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 391/701] 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 2104f941a6b..692d08aae8d 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 0278e2b2d79..31d2a31ceae 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 d04b7e9b940..0020256dfb1 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 c89f581daac..2df87c39868 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 392/701] 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 a63072f5a3d..4f05279350a 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 e533dbfa0c8..994076baddd 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 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 393/701] 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 9dd2127fa28..6bde63d900c 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 394/701] 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 69af6f4fb1b..3e6046b0d11 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 395/701] 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 afe7ef3766f..1ccb75ad661 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 396/701] 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 00000000000..db103c0de05 --- /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 397/701] 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 db103c0de05..f86747aac12 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 398/701] 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 5a00f8bfbee..a488e306473 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 399/701] 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 3e6164208b4..7892e18b9ee 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 bcf0d0bfe26..de72485ddb8 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 00000000000..b68d5e6f62d --- /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 00000000000..21429bc5643 --- /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 00000000000..9cb773adf91 --- /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 00000000000..719af357263 --- /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 00000000000..b777eb7e96b --- /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 00000000000..77ef77aaf87 --- /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 87112032e1e..e34e62a7749 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 d1160329545..002a787fd03 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 7d2af3b31d9..8feb8eb6088 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 f97cc89c5c8..1b749fd7039 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 fdf23332fff..8e69001272b 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 00000000000..0661e86edce --- /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 00000000000..de824e4aeed --- /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 00000000000..8ae100f1774 --- /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 00000000000..7d0d5fccbcf --- /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 8c8b58943a5..00000000000 --- 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 ea64972868d..00000000000 --- 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 492fc708485..00000000000 --- 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 518cd548536..00000000000 --- 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 0b7bc187ecd..00000000000 --- 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 00000000000..a7773f0afda --- /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 00000000000..bd24fe6fa82 --- /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 00000000000..8199639fb80 --- /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 00000000000..5a7203bf30b --- /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 00000000000..fb87e0756d6 --- /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 9e012c14272..1ad42a55cbb 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 00000000000..81ce3bf0308 --- /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 afc0b6a0c6f..ab5486f3af2 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 00000000000..094148aa3e6 --- /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 d4839012f0b..beb1a675e89 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 00000000000..4449ec57523 --- /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 00000000000..14906fa5cee --- /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 00000000000..ecc46d2607c --- /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 00000000000..be8ef76e666 --- /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 00000000000..e5ec1ce445a --- /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 00000000000..7a4c06c56d0 --- /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 00000000000..ff029ff8610 --- /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 00000000000..8e754cddd3e --- /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 00000000000..9fe03d4cbab --- /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 00000000000..c4280505f11 --- /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 00000000000..118a440cdde --- /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 00000000000..89748d6428e --- /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 00000000000..2a68e3e2a37 --- /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 e78983c62f6..657605bbd01 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 4315597a3cf..be6462156c4 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 00000000000..a4503924c84 --- /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 00000000000..d4536e4a53b --- /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 00000000000..cd0b88e6ce5 --- /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 6ee32a58698..00000000000 --- 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 63c993e27c9..00000000000 --- 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 00000000000..ccefb2c4844 --- /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 00000000000..4907c89d35a --- /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 00000000000..497f3d957e1 --- /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 00000000000..9944874b97a --- /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 00000000000..2fe75d46eb3 --- /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 00000000000..c76bb8661d7 --- /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 00000000000..d1d6bb5a91c --- /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 00000000000..649244fd2a3 --- /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 00000000000..849bf0e35bf --- /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 00000000000..eec577988d0 --- /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 00000000000..43eff23702a --- /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 00000000000..983a1b941a2 --- /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 00000000000..757d830bb49 --- /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 00000000000..bd88b4bcc8a --- /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 00000000000..1efc31ac094 --- /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 8b7ac6abbb1..00000000000 --- 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 18772756b12..8e39e048cfb 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 400/701] 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 7892e18b9ee..2ff37dab4fd 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 de72485ddb8..8c4022604af 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 b68d5e6f62d..152c43d95e3 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 21429bc5643..78120185161 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 9cb773adf91..58215aec8e4 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 719af357263..c1456dc55b0 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 b777eb7e96b..d0ddd6115e5 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 77ef77aaf87..e27376f4156 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 e34e62a7749..463a7770357 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 8feb8eb6088..fc557d427fe 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 1ca24a0c730..f2082dd5fc2 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 0661e86edce..6cfe4a256b1 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 de824e4aeed..99fa1dc2c38 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 8ae100f1774..1ab9d974aa7 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 7d0d5fccbcf..3fc18ec925a 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 a7773f0afda..757591e2dbb 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 bd24fe6fa82..31da3fe7911 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 8199639fb80..968f73e2b5d 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 5a7203bf30b..c5fcf758da3 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 1ad42a55cbb..d270cee4311 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 81ce3bf0308..0a7b2ae9538 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 ab5486f3af2..b3f1a1d7165 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 094148aa3e6..d92730595ab 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 beb1a675e89..2e7ea841949 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 4449ec57523..89d43d7f591 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 14906fa5cee..813c6c71c9d 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 be8ef76e666..0c5f5299344 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 7a4c06c56d0..6e541f10608 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 ff029ff8610..3430288f594 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 8e754cddd3e..894834f30b4 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 9fe03d4cbab..e45989b54b9 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 c4280505f11..3fa24b3b2af 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 89748d6428e..d15040f24d7 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 be6462156c4..7ad6539e6b7 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 a4503924c84..9b0159332d6 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 d4536e4a53b..5f419dea1f2 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 cd0b88e6ce5..be8b2e30e5f 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 ccefb2c4844..39543150dd8 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 4907c89d35a..b62fab78e6a 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 497f3d957e1..96cebfe408d 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 9944874b97a..1cdeb0ac867 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 2fe75d46eb3..3d2ecadd284 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 c76bb8661d7..3178c430835 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 d1d6bb5a91c..104db78d3c0 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 649244fd2a3..584b7bf95f4 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 849bf0e35bf..6efd7acee66 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 eec577988d0..1a0fb93441a 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 43eff23702a..34c36bd456d 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 983a1b941a2..e086a959bdd 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 757d830bb49..435883c847b 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 bd88b4bcc8a..bb111f5f5f9 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 1efc31ac094..0937bc570a1 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 8e39e048cfb..db2d95553d4 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 401/701] 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 152c43d95e3..a5969f58c27 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 58215aec8e4..ae9db7c5c34 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 c1456dc55b0..b098d2aab79 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 1ab9d974aa7..bf8afb5e375 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 3fc18ec925a..f1622a900c7 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 757591e2dbb..877b81f367f 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 31da3fe7911..bbe72821671 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 d270cee4311..d5e2b09f4ea 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 0a7b2ae9538..5f48cc8b1a5 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 2e7ea841949..99c7f82be11 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 89d43d7f591..a7a4d506859 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 0c5f5299344..147abc893eb 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 6e541f10608..e2a0025625b 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 402/701] 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 b098d2aab79..bcc6a430e6f 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 99fa1dc2c38..85e8722627c 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 3178c430835..fbf7479d9aa 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 403/701] 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 2ff37dab4fd..eb7874a9361 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 8c4022604af..f0b73803972 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 78120185161..a7b839c9913 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 463a7770357..5aea87e5e6a 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 002a787fd03..3b7e79ae88b 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 fc557d427fe..108721fd856 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 1b749fd7039..875d384a205 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 f2082dd5fc2..24b740b554f 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 8e69001272b..772868e4e3e 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 bf8afb5e375..4338f4f1c84 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 877b81f367f..5e1cee9a0c3 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 c5fcf758da3..f6a0b2dfac9 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 d5e2b09f4ea..e248b3098d5 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 99c7f82be11..3869ef8b661 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 a7a4d506859..4b26d9a8e32 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 7ad6539e6b7..97f159d1352 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 5f419dea1f2..b5496628b3a 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 be8b2e30e5f..84adbdab7ac 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 71ad99bb5c3..899a65c3753 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 404/701] 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 a5969f58c27..b7f21696162 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 a7b839c9913..954deaec639 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 ae9db7c5c34..1f6e05c9e02 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 bcc6a430e6f..fed36ff6b1c 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 d0ddd6115e5..e5c8dd48c7a 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 e27376f4156..e522d4ae5e0 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 108721fd856..0e130c24e79 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 6cfe4a256b1..17ebf9c8390 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 85e8722627c..b8c0da53c53 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 4338f4f1c84..89c98d29ae0 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 f1622a900c7..8038c8c05bc 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 5e1cee9a0c3..c7e2a4beabb 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 bbe72821671..5abe4972e34 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 968f73e2b5d..02c4d29558d 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 f6a0b2dfac9..590430a7e24 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 fb87e0756d6..663b1d865fb 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 e248b3098d5..bc91f04ee38 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 5f48cc8b1a5..f1fed3f06fe 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 b3f1a1d7165..3208ca7fc61 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 d92730595ab..cbbd15083ee 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 3869ef8b661..044d5d8da9a 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 4b26d9a8e32..12e53ca2bd7 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 813c6c71c9d..4fa16db9863 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 ecc46d2607c..3d36e026f70 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 147abc893eb..88dab836987 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 e5ec1ce445a..3e7c3e9b592 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 e2a0025625b..e83502e4fe3 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 3430288f594..a4e3c634ce7 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 894834f30b4..be4a8cca288 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 e45989b54b9..a6681a7f676 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 3fa24b3b2af..7793f60cd1e 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 118a440cdde..43e512ecb02 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 d15040f24d7..b5c78cbc28f 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 2a68e3e2a37..aaafb699b33 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 9b0159332d6..98284e49ad8 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 b5496628b3a..39155e4f4fe 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 84adbdab7ac..0e33498a16f 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 39543150dd8..9ca65d8e675 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 b62fab78e6a..ba5e97aa14b 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 96cebfe408d..86bcfeb0648 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 1cdeb0ac867..5ebeac22844 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 3d2ecadd284..4fa99f3bf83 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 fbf7479d9aa..cdd8dde585a 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 104db78d3c0..dcfd4d02988 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 584b7bf95f4..244da5a42e0 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 6efd7acee66..dcbf64bbb20 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 1a0fb93441a..842007aee29 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 34c36bd456d..ca474c4bee1 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 e086a959bdd..72b5320a050 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 435883c847b..c69a6f35b1e 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 bb111f5f5f9..7570c8971b2 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 0937bc570a1..bf8b601ed43 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 405/701] 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 bc91f04ee38..5824aca6cdd 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 406/701] 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 f86747aac12..c7ff1d95617 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 a09220431c5ca8974bcca53231a38a3a95d5bb62 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 2 Oct 2018 16:08:46 +0300 Subject: [PATCH 407/701] MAGETWO-95412: [2.3] Add missed dependencies for catalogsearch_fulltext indexer --- app/code/Magento/Elasticsearch/etc/indexer.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Elasticsearch/etc/indexer.xml b/app/code/Magento/Elasticsearch/etc/indexer.xml index 8d75a59f840..f22eb8f0bd3 100644 --- a/app/code/Magento/Elasticsearch/etc/indexer.xml +++ b/app/code/Magento/Elasticsearch/etc/indexer.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd"> <indexer id="catalogsearch_fulltext"> <dependencies> + <indexer id="catalog_category_product" /> <indexer id="cataloginventory_stock" /> <indexer id="catalog_product_price" /> </dependencies> 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 408/701] 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 b6e53b3695f..57123d68426 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 03976dfcdc1..5527060a6e2 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 409/701] 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 9809a9ee4e4..6ccbba9f882 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 39db400d2d6..dbc666e49b6 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 410/701] 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 b433e3f19c8..f0abd15d106 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 411/701] 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 9ffec68780a..b87afa8e5d0 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 e1e201658be5c247334ef761ac028717cfe0b8a6 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 12 Oct 2018 15:48:14 +0300 Subject: [PATCH 412/701] 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 8d4aea135ea..c9afdf023b3 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 413/701] 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 51062da6f2e..92d221de9e1 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 44145f92904..3deb688de9c 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 a9083cb320c..ec835384a52 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 9d95b01b2f8..08a08275ee0 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 1adf2d22be4..a39530f7607 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 42d84f13b9a..1f7d849ac02 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 e8b8c6cd9e6..3eec020e263 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 ae7d0eed739..73b5d2546f4 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 c43aaf8d3c9..51d11b4e5cb 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 4e1944bed9b..9395e87c20e 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 8fb27a9dd1e..7c9c52e1c02 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 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 414/701] 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 84ad6d21167..2c74044416a 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 415/701] 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 6d1c1549216..e9cf007f721 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 416/701] 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 e9cf007f721..244964c0972 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 417/701] 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 1dcd8516af6..c3942054224 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 244964c0972..f11322f17ee 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 29e35c721a3..c0bbd32f938 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 9848a09540c..cb396e32509 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 bd1dc774b53..a142f87dcf6 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 418/701] 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 4262967aa8d..2fe49efd74a 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 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 419/701] 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 ae7e1e343b1..06fa6a2618f 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 44b3512090b..390bf7fb120 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 606c854d27a..ed91b22930a 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 4f735ae4ac2..f01eabb7898 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 24d51d170fb..a57fcad0779 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 270828c2a2c..60ae901d8f5 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 420/701] 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 2cb0e287404..7c12b546d13 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 5c05d4a8400..3480c88d652 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 421/701] 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 6bd78cecd3a..cd3bd2c5a7d 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 422/701] 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 6ce33f3be36..934fdf049bc 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 faffc69dc69..0e3a74fccf9 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 6b2c3850292..04cbeb5bc59 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 473b0c16630..00000000000 --- 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 54d392d0c06..e7a3d03f337 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 423/701] 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 934fdf049bc..6cbbb7ae220 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 424/701] 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 6aed5cd39aa..ecc9af83580 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 425/701] 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 3ca936afd40..e689738fb01 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 ae4064c0ab3..fb81fea9005 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 9f30342ed33..e6605a67a12 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 d2f5f5ce566..02ba396601c 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 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 426/701] 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 a5aefff656b..951989146e6 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 69f4a465e33..919f0cfda7c 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 c7e83819f25..c7071076bd5 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 d3825675b72..46d5bfea645 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 00000000000..a1dc418e156 --- /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 c5e704c2434..bbe96d89f57 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 00000000000..27ca8e7a044 --- /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 00000000000..f3bb3d0415a --- /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 427/701] 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 79f6024132b..7c8e65b2491 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 639c0aecb36..8a484d4cc79 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 1ac7ad37737..42da02f8ca4 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 7e0ad7c46d6..75910e17207 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 81b7414380b..7efe708a575 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 b49809cfc80..28f67a7829e 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 be2609ccc33..9e7737123b2 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 9ea4007c6bd..8a18c1bfcc5 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 2ead0ac0ac6..75bf4cbd0f3 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 0308fda6573..0d226acdc3d 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 f8863aca8db..c62d2a03356 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 1cdd9c5b9fa..f45ef11a863 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 cd0aa12f913..e4a20cc188f 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 02d533d7bcb..fcecb36e7d5 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 35f616f1096..a12ae8e69c3 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 d88e5627df0..05254a50aad 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 a660cf62b1a..948ae70793c 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 ff9aeb4fb44..0835fb66f87 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 79d03b6fad2..81121b9d21e 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 aff558c6d02..b958de91314 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 6e6aee08f92..0adc2fcecbf 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 413af718141..e56559563c3 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 428/701] 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 3480c88d652..5c05d4a8400 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 429/701] 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 d82f4a04fb2..e14916f731e 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 430/701] 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 e14916f731e..d82f4a04fb2 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 431/701] 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 d82f4a04fb2..8999b03b647 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 432/701] 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 a16e437c0d7..9f756696008 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 433/701] 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 a26a92df385..a919a54cf62 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 434/701] 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 71b1392d539..67620334122 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 435/701] 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 c106afb90a0..f6d08883d7a 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 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 436/701] 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 ee92fd7c19b..d12b280e234 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 13f0dbf79a1..b96aff148e7 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 096d8495d70..345d323e6e1 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 3f80e01802b..c3ec83d4dd9 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 3c36baf6f31..7a0eb6652d1 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 2fc0f0ab4c1..c5e3323716a 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 68112991664..31d8ba59ee4 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 81b7b8b3f96..c7023d0404f 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 5c7fcd38d6c..ad620e4e4b3 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 a0530389f90..d144b7f6b70 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 ca2b4b95b55..630c0966bc2 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 88f58c6d011..44080ebd130 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 7fc45eed356..8f606d17956 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 0add517ba94..59dc4db553e 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 e1c97c8912c..b6a3aede21a 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 6f578e44eae..d5cd69d6895 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 4684abdc9be..196e59c6593 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 5dc51518f0b..0aa2387e623 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 39a9ce7a8ef..c963084a1ec 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 abc344671ab..3aea20a090d 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 8991f7f06d1..3f045197136 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 adad931da5a..a02c998f856 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 eee00483ace..eccbfe1acee 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 bfd4b5e7470..ea19e25ba68 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 b310bf63bc9..3a1855b3a22 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 4eaaa3be8a8..50e7437396b 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 d4cfe544f47..3d66113ac61 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 b411f1c0cf8..bb7375ae832 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 4050d79e593..2994ac351fc 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 14ca52e92ad..bb47aeb3194 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 b285270c67e..5c131d27fb8 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 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 437/701] 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 9842f20cdc2..0a0cbd9db7e 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 438/701] 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 f70bab73d08..d37f97c38a4 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 5bbae772d5c..c8b075ffb49 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 0d62d120f80..5afac59b25d 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 a937c62dfc2..58903488601 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 439/701] 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 ca252aabe54..98a33b52f98 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 440/701] 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 98a33b52f98..964b0bde135 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 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 441/701] 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 e689738fb01..bdf8cfe5416 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 fb81fea9005..4aabd05a0ef 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 e6605a67a12..137c8b44081 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 02ba396601c..1d821ad041e 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 442/701] [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 f6d3ca36c1e..48ca12321a2 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 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 443/701] 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 5ba18af6b05..11b187db3d1 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 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 444/701] 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 54a13be864d..77368517a31 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 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 445/701] 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 75a399720cd..ed682a9e204 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 00000000000..125faa935f3 --- /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 1730996937c..76c0a9e1fe7 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 446/701] 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 6c54aa4e171..76f5dbd1bea 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 447/701] 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 8937a4920cb..cd7ce400a0b 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 5b96acae1d7..d8c5e4fc816 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 448/701] 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 d8c5e4fc816..e5de8e7d4aa 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 449/701] 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 ed682a9e204..92112661846 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 125faa935f3..5ae3f4af242 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 3c043b28801..836cba95a6d 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 450/701] 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 dafea71f872..1a54db0d59f 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 451/701] 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 5ba18af6b05..11b187db3d1 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 452/701] 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 2aa21059918..b184334b179 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 453/701] 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 964b0bde135..e6a1dcbc345 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 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 454/701] 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 7ea979df30a..535e0bba388 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 692d08aae8d..33bdf827f80 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 a2db0f43061..1680aee38dc 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 0020256dfb1..24cd0f4fcf6 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 2373b5285ed..26f32746889 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 1ccb75ad661..4ca126e659e 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 25cf8d3fb3b..582b0c8cf65 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 455/701] 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 4d274a071d0..4be4bb09efc 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 34cebde64d0..b9993b420f4 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 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 456/701] 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 93eaa23b89f..0366e01ee86 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 64a8f930d83..c1e6decf6af 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 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 457/701] 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 bb190260e47..5059d61eb3f 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 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 458/701] 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 c9376f00b71..a39de2d5b8a 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 459/701] 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 99c963501a9..68dc8d753b5 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 a7f859b23df..39129dee28c 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 460/701] 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 7ecaeb5ea7b..3d644a2a322 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 461/701] 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 b1c7a49da4a..531cf3d34ad 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 462/701] 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 ceff0ea2e5d..b3d39a48fe9 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 4321105a7e8..63b09de7f08 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 863f1fb7466..22f829063fb 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 463/701] 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 4f05279350a..e7776b3dcbe 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 464/701] 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 5ae3f4af242..84bc3865a00 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 836cba95a6d..2d784842ea4 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 af3de710de5d11d12548b8342f6978cc435ac9c0 Mon Sep 17 00:00:00 2001 From: slopukhov <lopukhov@adobe.com> Date: Wed, 17 Oct 2018 09:01:06 +0300 Subject: [PATCH 465/701] 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 57e29d11495..727e18280d7 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 466/701] 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 9563626ee25..90a0a1d21d8 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 467/701] 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 eb5d90f2fd7..48cb5d55061 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 468/701] 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 d12b280e234..26ffc6e0df3 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 c3ec83d4dd9..f29fa0611ef 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 7a0eb6652d1..cff6f54b3a7 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 c5e3323716a..eeef291fb6a 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 31d8ba59ee4..44ed4c001d2 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 c7023d0404f..a6e0eb0bcbc 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 c3942054224..4976ec54660 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 f11322f17ee..972cb63ed45 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 ad620e4e4b3..a26cfb96fe0 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 c0bbd32f938..43ae2db0c21 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 d144b7f6b70..9caa2988c5a 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 630c0966bc2..333e9e03706 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 44080ebd130..0e7a46125d8 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 8f606d17956..2f7065cbd63 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 59dc4db553e..a995667954c 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 b6a3aede21a..80824d45cb6 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 d5cd69d6895..73a4f691479 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 196e59c6593..33fe5ec3300 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 0aa2387e623..4fdc4cf8f7a 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 c963084a1ec..9a547c00324 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 3aea20a090d..701b4fc21d2 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 eccbfe1acee..d496b3955de 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 ea19e25ba68..db336d0c2f5 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 bdf8cfe5416..b45fddc7d73 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 4aabd05a0ef..2aee648ef7c 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 472153ba6c5..03b4f78b141 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 0c03b50b366..710c85f8773 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 50e7437396b..87e9d9e0060 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 3d66113ac61..ad3f4aad676 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 bb7375ae832..f580c5cd72b 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 bb47aeb3194..b4f761f03dd 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 469/701] 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 b9993b420f4..167ab91b9d0 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 470/701] 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 b5d60459714..fb10c175e3c 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 471/701] 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 e6923caa3d2..7ba4225ce2f 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 472/701] 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 ab6a34c4274..37e821f0268 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 473/701] 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 848a7daf71e..86d6c4dd105 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 474/701] 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 c85b484d51c..e6923caa3d2 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 1e0747acc36..ab6a34c4274 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 475/701] 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 e6923caa3d2..7ba4225ce2f 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 476/701] 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 ab6a34c4274..37e821f0268 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 477/701] 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 38b581da752..5d9badf4207 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 a45d6a62488..af2a43ceaed 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 478/701] 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 5519245ec24..61108c64dda 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 c72651a78da..186cbcb81bf 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 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 479/701] 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 86d6c4dd105..42b692ff9dd 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 00000000000..3a6cd6d60d3 --- /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 480/701] 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 39129dee28c..559c62e42de 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 481/701] 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 84bc3865a00..04115ccdcc4 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 482/701] 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 a488e306473..9f8d1786334 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 483/701] 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 7ba4225ce2f..23fe71aa668 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 37e821f0268..5468caf4902 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 484/701] 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 cbf499c8dad..5bcc712be6f 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 23fe71aa668..6fde4dded46 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 5468caf4902..0aa600b84dc 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 485/701] 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 a1dc418e156..ceaad3a0032 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 27ca8e7a044..53d30e834a0 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 f3bb3d0415a..ca0f379a03d 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 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 486/701] 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 4d1957991d1..681b7ecfb02 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 7c8e65b2491..9f25990594a 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 bc60a5c9b10..4942b36743c 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 145db146347..17d70e38d3b 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 df00e4c7106..fba4572cf2c 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 8f1f3fde142..cea42347dc3 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 425e6c00416..f2e1c3c4c42 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 5447ff635f9..1f11d265033 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 28f67a7829e..af0e9ff5528 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 d6110f4b3b2..fa42cadb8a2 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 c1c9997bc83..f014c6d1331 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 a8d46911193..03c3a50d171 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 83ad7acca84..86dccf8cfe5 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 ca701db7d2a..1218e3da9a7 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 c8dbd89017b..e250d112393 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 e971f59cf10..23ab52012f2 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 d8b3c19ddb9..d54d6c939cc 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 b9b44df6f40..841ee8708f2 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 47a8681a73c..b6639f76045 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 4ce286bf159..c24665f4808 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 7c15514f211..0998cf7a9b3 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 108f1b9f4fd..a19f53469ae 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 4ffd8ff4ba5..eb901498c4e 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 4f14b7daba1..98caccea2ae 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 db1d550c372..ea2d24aeadf 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 948ae70793c..b4b15554f60 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 81121b9d21e..e6cfe8ca112 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 b104fd03297..d8c92a4801e 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 487/701] 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 5dc51518f0b..b2ab1627b24 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 c700dbc362c..da0aa49d969 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 bdd54ce3559..381c18d3ee6 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 67c1826f40a..248dfc8e16d 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 28259c8f6d9..7d229bc3589 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 4b69bcd4615..87ba4d7c280 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 39ad80850dd..06a8a0accc7 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 2a6079d619d..0560158a826 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 472fff4f4f2..67518a6c7d1 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 d43c976431b..7c4b6984b3f 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 c5e7a7e9e7c..c793714f691 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 10b6a17ea57..27797d08679 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 ad0673ff5d7..c915d50741d 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 a4e3063abec..9112192f6eb 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 4095b12c9a6..0f6a402e260 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 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 488/701] 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 8896f84ce24..eb691d011a2 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 489/701] 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 b184334b179..793ad935363 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 490/701] 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 793ad935363..21f7f87875e 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 491/701] 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 4a5f651a108..95fc1c42210 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 492/701] 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 0366e01ee86..93eaa23b89f 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 c1e6decf6af..624001b4984 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 493/701] 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 bdf8cfe5416..b45fddc7d73 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 4aabd05a0ef..2aee648ef7c 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 137c8b44081..ccf8b4470d9 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 1d821ad041e..834d1e4694c 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 494/701] 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 6830aecb78f..00000000000 --- 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 9dc0dd68ee4..3caa79e68c2 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 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 495/701] 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 eb691d011a2..8f64d023c19 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 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 496/701] 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 0add517ba94..527260699e1 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 41be237efe5..a7914ceec12 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 497/701] 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 527260699e1..e99da345334 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 a7914ceec12..9c717ea240a 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 498/701] 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 a0f06cd406b..9ae22e5e1a3 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 2bc9b474ff2..087fae6e656 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 dbb8602678d..59a1f58b74c 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 2daebf96c6c..e2e8a744c4b 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 35959017606..1cc045745a0 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 397048cb046..66b639fb088 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 2f2b97bf1fa..6fd1e746697 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 0f441ee6268..552e30da892 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 be815c31456..5019e86b7af 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 d92d2931867..eb6fb2e812f 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 5a4c4b7ef52..18bab6571c2 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 5d129c199fc..1d2cabbb48a 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 90f7d993e36..eecf6cbe076 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 dcd611a1483..8796953e32f 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 7e3ee63d33a..5478f90fb7d 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 2b0c4058293..3cfdf455063 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 49cc746e79d..8be7f5be79f 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 f57db6b2cef..99ad7005d9d 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 8be61afbbce..d29171f557f 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 38d3c33a9a1..d3c165bbde1 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 74e062b7e07..5378801b6c2 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 9551e06264c..a12b72cd0a9 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 cb8741c88b0..5a3a3ca6ee9 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 eb76dd5fce0..798ac4074c1 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 29f7aa61ab8..145b0d1454a 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 c13a2560c6a..502d9532e8a 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 ef430108265..ba3b62f5547 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 a24a10d7433..115002b2376 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 3f0523e8fba..24ed4963728 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 fae1ee72ac3..0ee162e429f 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 1e826ef229f..402ce5f2f61 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 b13f7e570d8..0bffb9a9888 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 992709419fa..7d44ab782de 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 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 499/701] 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 7e60039e868..ee9087e082a 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 500/701] 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 ee9087e082a..00000000000 --- 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 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 501/701] 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 460cc29b183..8fbb64f4579 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 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 502/701] 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 76e3d911e7d..f1da0ed7916 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 503/701] 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 f1da0ed7916..f85a1385e08 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 504/701] 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 150c8adf0b2..b48ffa6f50b 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 505/701] 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 164109177d4..947f7b896f6 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 77c15fccfa8..ea841e86586 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 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 506/701] 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 b48ffa6f50b..0807a4c3949 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 507/701] 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 70a8c94fefa..e8af185b8c2 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 508/701] 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 f85a1385e08..54e49613197 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 509/701] 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 3d8325a3ecd..31009555bd9 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 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 510/701] 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 35e6045b607..29d928ced20 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 9fae4041109..2dd8c68e2d5 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 342326e6666..5cd55408838 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 45c02128bfc..a38828eb6ef 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 8092f34c533..6ff779518d3 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 fa9a14abb89..b8987363569 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 7b4e1a96add..07378f6a27f 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 8a6ae8d2d93..5ac7fedc5aa 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 f4c40a6930c..0ad71089bed 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 174173fa201..c8da5b59cf5 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 31b3111df98..09cd1c5b639 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 2b825544f56..3075601215f 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 3f55d582776..8aeac802fbd 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 7c6661a5f39..d6917e8c184 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 deff05d3eec..b3061eefa63 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 368ca417432..b3c15799011 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 72fd929b98a..c11e0ee525e 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 ed25628bcff..89d47644661 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 f930321e525..c27c3cb32c4 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 53ef349a383..dbb8855e9e5 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 518c6398e4c..4ae98799df0 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 ad3e03e490b..76c377544cf 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 01f20daabf0..df451318485 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 58c447f4d26..d7cb006a2cf 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 9e81b867d36..c2c2cedc665 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 9cbad4d32a8..7a20d2bd4df 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 02757afa53f..3850a6749a3 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 6f9ce29436f..ff23f321011 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 5084b8b6d01..5cb572f41b6 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 80f4b56a172..0510ce9b9b8 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 2703ee4f5be..2d7874453a6 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 68678fc60f0..5021d240417 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 ddf8be8a37e..62f0eda16af 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 ceaf4d7fbd8..bfe087d9a57 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 3bd7122e65d..8e399f03afe 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 367957fc177..6f3aa481f73 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 f6c8074411b..1321ebba4d3 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 1a2ff588180..65cc4d01fed 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 4b716e76109..6847b4681de 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 cdbd50c3f34..9c220d36d38 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 530a9a33b0c..0e580b85bd6 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 9b2dfb493db..754af7d246d 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 f14e6de79e8..ce7143582ce 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 7537f67cf55..b9551749dfc 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 6a31eacbb45..1cee590dec7 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 82a9b8ef514..b3c028b626b 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 3c2bc3e3c11..6eea94b8dee 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 c960f27b0fb..3dafbc38764 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 6e83a647919..f5227a9ef3a 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 ee1185e6e57..7f3a3fc6079 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 523ef3a1279..a0d08467acf 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 d07329df9eb..e2a04b0cdc7 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 af328873dee..6e001487320 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 df9b39a2788..c3356a96b94 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 d89bdb7e710..239e3b49983 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 ed1f2adba21..c647ea92b09 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 96c3be9740e..c0a8a342945 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 149bb27fcdb..a82e6aae202 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 73fcb7ce0ca..8a02f411ad0 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 be13c28ee02..d7af9091b23 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 db979f9b763..b374645240f 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 ed3f6326cd6..3882afb9f43 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 5319c469f04..00000000000 --- 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 830fcb293a8..735b8273019 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 bd835c35fd8..00000000000 --- 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 8c264bd95a0..3eed77c37ca 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 ead4fc5604f..d6436204a32 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 82db095d668..dbebdefbda0 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 66cd19d0512..54c8f197530 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 511/701] 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 3caa79e68c2..d1566162472 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 00000000000..5b752e71848 --- /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 00000000000..249f1dc40b1 --- /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 00000000000..d9136e742b1 --- /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 f87e524a26b..fb042c7e59c 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 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 512/701] 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 c4da59fd2ce..80d65e96625 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 0cfaba845fd..3ce2639674d 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 c4a0b55de9b..fecbf9c430f 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 00000000000..43e20aae8e6 --- /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 00000000000..982d00bd9f6 --- /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 513/701] 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 fecbf9c430f..d957f394ee7 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 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 514/701] 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 5b8a4c8f37c..1c4e7b6b6da 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 7384c4ed7ba..af66686e77b 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 4d3d51b9c02..8c42f9efd12 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 0adcd5c52f9..4f9a5ab6d5a 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 4b78f436eab..a3c4fe010fd 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 68f2810e8ee..93e6e13eb36 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 0a0131e5006..8a73d9e2255 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 e4a5ca05d02..479c4c87f61 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 6b92440ca92..1347a1ba8e3 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 b6ff634e6ef..9bd6c438455 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 4520cd9e4d4..8082157524a 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 9d868c01688..0eeff417487 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 4520cd9e4d4..8082157524a 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 b6ff634e6ef..9bd6c438455 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 9263004c6e7..d6be9376cb4 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 e39f0a04bcf..1b7d0dcb93c 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 4ecee622864..b42d74aea06 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 515/701] 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 80d65e96625..f9b64f3a3c6 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 d957f394ee7..c4a0b55de9b 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 43e20aae8e6..5572bac6add 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 516/701] 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 5b752e71848..e9020c2df53 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 d9136e742b1..c6659080ee9 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 517/701] 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 00000000000..f5b6d13c3cb --- /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 7dd8609bdca..04f8872557e 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 34d432e566f..33f4b170637 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 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 518/701] 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 f5b6d13c3cb..eebeb154adf 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 519/701] 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 04f8872557e..7dd8609bdca 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 520/701] 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 00000000000..fb25290f9d2 --- /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 521/701] 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 00000000000..5f7c44b988c --- /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 522/701] 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 a862fbb1306..bc66324c298 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 523/701] 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 c43adde2f19..eff07af0e6a 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 524/701] 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 00000000000..f82bc01c485 --- /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 525/701] 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 00000000000..adebee0d591 --- /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 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 526/701] 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 76fcf6b2fad..e3068c1bd76 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 cd42a1e8fc3..7271103e3e7 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 34d432e566f..856bdde4e98 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 1a9b42355f5..26bc2209d01 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 527/701] 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 8b69a44993f..9a0dd8f5b38 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 bfb95579106..057a551e1e4 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 528/701] 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 5b9905e0c9d..a0cfc084061 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 529/701] 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 057a551e1e4..8806612c0f5 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 530/701] 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 b30edc0c797..1832cfce7f1 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 1c4e7b6b6da..ae6c98e4627 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 77f2d741fc6..ef745d9e6fa 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 531/701] 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 d0c2144c951..7800d2363b3 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 06d3667f4d0..08c54844f27 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 4fa84e4e28f..ae0523d34fd 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 532/701] 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 04115ccdcc4..e0898065a9d 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 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 533/701] 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 4e4e146208a..3c3bc083fdf 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 534/701] 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 956c9695623..2086f41d27f 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 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 535/701] Updated links in README --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c292f1100f3..979e60a1677 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 536/701] 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 1dccc310c7a..dbd9d1cd4fe 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 537/701] 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 457b83c5294..90b47782654 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 538/701] 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 372008d0615..b73e3178359 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 7d961077e6f..0868ce73c49 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 539/701] 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 0868ce73c49..05226d8aa3a 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 540/701] 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 9a73dd5d65f..89cb3e4b303 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 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 541/701] 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 342326e6666..95bd9bdcab2 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 423b7553ced..9b6c0709e19 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 542/701] 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 f82bc01c485..7a3000f7c07 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 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 543/701] 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 04115ccdcc4..9d3b498dc6c 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 2d784842ea4..307999ce48e 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 544/701] 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 1832cfce7f1..9e1f9252c84 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 00000000000..af20619934d --- /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 735b8273019..34a99f26a4e 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 00000000000..a3e66b9cf39 --- /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 0e1ad0768c4..040549a5611 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 dd2acd76088..715f98c4177 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 57e5270b0c8..141e4a70832 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 4f020b1a032..11111ea5242 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 d6436204a32..cd08e3f43ad 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 54c8f197530..a2f8611c4bd 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 545/701] 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 00000000000..90eaf91b107 --- /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 00000000000..05ce3318ef7 --- /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 ef745d9e6fa..434c99cb987 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 00000000000..55005b82ab8 --- /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 00000000000..b4209edfe47 --- /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 546/701] 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 d31c0dca381..ca11fec7cd5 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 6b5d08c2641..6a2f329d095 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 547/701] 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 00000000000..a064678394e --- /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 33f4b170637..4145584f6e4 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 548/701] 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 d9bba3ca5db..3c71e2fde48 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 7271103e3e7..a064d096f6d 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 26bc2209d01..6d11542bb49 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 549/701] 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 793af65be9d..9d3b498dc6c 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 550/701] 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 ae6c98e4627..30cb5b4d166 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 00000000000..e10803af248 --- /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 a064678394e..f8860731aa8 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 00000000000..a65bb6aab1c --- /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 00000000000..a0b9bbe483b --- /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 bf50a5a2982..f6497e8e4b1 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 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 551/701] 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 bf73d6361d4..578267984f9 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 f8aa078f45e..6b479ad1cb2 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 78accc5569841afc37788f45847f11b52c0526c7 Mon Sep 17 00:00:00 2001 From: Mahesh Singh Date: Mon, 22 Oct 2018 23:36:21 +0530 Subject: [PATCH 552/701] 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 5abec8efbfd..fe80fe10549 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 553/701] 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 af20619934d..b57abaf816f 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 5bfc5686b05..00000000000 --- 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 2bb4bbcdb8d..80b0517f7bf 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 15dfcc74640..88cf36eded3 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 ee4331e7bfc..00000000000 --- 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 554/701] 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 30cb5b4d166..ae6c98e4627 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 555/701] 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 18927b5f4ec..7d5a097eeea 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 556/701] 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 9e1f9252c84..2155efa0170 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 b57abaf816f..5cdcc6eb99a 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 3882afb9f43..149ad996a5f 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 a3e66b9cf39..fe7d1a822da 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 557/701] 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 3a6cd6d60d3..772250eb7c6 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 558/701] 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 9d3b498dc6c..11bf03c1d5e 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 559/701] 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 88cf36eded3..4e0c1292040 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 560/701] 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 95bd9bdcab2..342326e6666 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 561/701] 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 7d5a097eeea..18927b5f4ec 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 562/701] 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 d1d8e94d7f2..72c36293bc1 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 563/701] 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 00000000000..ff2e5f2f360 --- /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 00000000000..f18bb46fa63 --- /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 8fa03232a0e..9442cf2f5f1 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 4ca7d75af9e..abecec39586 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 00000000000..dba4a94f3db --- /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 00000000000..32ac73aca7c --- /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 00000000000..ab0db2dac64 --- /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 bc131b2987a..cd5e62307fd 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 564/701] 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 609ae1cfe09..a001cae6454 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 aa85299deea..6d1d5b6f4b3 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 f65aa33ff93..d5cf5d91881 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 c75112fee86..2a23903a697 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 02cb304325c..c50f0e338c2 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 10ebd2b6d5f..0c101741096 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 ab0b1f20968..0b738c5e159 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 8d82ad94dfa..161734f47bf 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 e64956dce17..ee8c9331097 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 2c4967c4c2f..98da6cb7a5e 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 565/701] 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 90a0a1d21d8..e9b4bfa4489 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 e6a1dcbc345..14ec829d980 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 7ba4225ce2f..9326fa4fa3f 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 37e821f0268..6f2b6f37aca 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 2a7785f532f..32fab8d0b07 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 566/701] 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 4be4bb09efc..4a6cc09d119 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 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 567/701] 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 4a6cc09d119..0e08b0af928 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 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 568/701] 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 9a42090ad31..71a1e2f92df 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 569/701] 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 277900c46ba..edc07bee164 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 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 570/701] 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 f299fa01059..951989146e6 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 571/701] 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 58c5ba8a7e0..a3279f8c836 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 572/701] 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 8534e798481..6514c01f923 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 573/701] 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 721ed9a384d..420fd6e543e 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 574/701] 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 edc07bee164..d10bd5f2fef 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 575/701] 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 6514c01f923..cf747bfa2b7 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 576/701] 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 00000000000..2f3112e705c --- /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 577/701] 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 4aff80161ef..d1ac24c84be 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 578/701] 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 1f8c162ef92..4b08bf28ece 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 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 579/701] 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 cbf499c8dad..5bcc712be6f 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 9326fa4fa3f..6fde4dded46 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 6f2b6f37aca..0aa600b84dc 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 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 580/701] 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 00000000000..7574f684bb4 --- /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 581/701] 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 7574f684bb4..0abadf71534 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 582/701] 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 6c33ecc138a..7de78b6612a 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 00000000000..8dac2dee10d --- /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 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 583/701] 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 4e21648d00c..c7da840b7e6 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 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 584/701] 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 aaedaedb723..ace50aa3e6d 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 60df3f27fd6..08e859b11d1 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 4c194c63ec3..e2687f5f16b 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 585/701] 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 223b3e9888e..75f04eae821 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 2b4be8369de..7c93595b2b9 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 3c62a489af4..dce60079e43 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 943552e2b75..6cfcd485f76 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 abf38f1287b..88d1adf92ed 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 6eab92f6511..6d0716a6f1c 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 bbdee0ced86..a9507a6f4d3 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 b109b87e61b..8ce448d06b8 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 223b3e9888e..75f04eae821 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 994eeba317a..1279d9d9ccd 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 4c4b38132c8..7d00235c036 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 e83811042fd..c335b66505b 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 0b7c31a0922..c08ea7aa9e2 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 17cfdc31720..89f51931f8d 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 ffeca0f1609..bc190a8519a 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 22307b4d839..cd17183be7f 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 f204019988b..46bdd3dd666 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 c9d7c8a35b2..661f9f9c0ff 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 005f7bdd713..34f916674ca 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 03c7d85251a..2d8348f64a5 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 586/701] 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 624001b4984..a62e3d8f83b 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 587/701] 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 2f3112e705c..bc098cf1bd0 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 6bb825873812cff3ab77d71f1f3542d40aae2b85 Mon Sep 17 00:00:00 2001 From: ashutosh <ashutosh045@webkul.com> Date: Thu, 25 Oct 2018 01:07:09 +0530 Subject: [PATCH 588/701] 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 ed84e158819..6a095b4da14 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 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 589/701] 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 44862f1fce2..4a9b98f214e 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 6e9d5e5fcda4ce91ef25559bb946c8e52e777148 Mon Sep 17 00:00:00 2001 From: Janak <janak@krishtechnolabs.com> Date: Tue, 16 Oct 2018 14:26:48 +0530 Subject: [PATCH 590/701] 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 03976dfcdc1..c58c2bbf3ba 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 591/701] 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 66b1299b986..90482ab55fc 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 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 592/701] 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 123f358be40..5a290d5141e 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 00000000000..16e245ba640 --- /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 35356efc619f0165dfe04f5762e9af63816569a7 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Thu, 25 Oct 2018 14:53:30 +0200 Subject: [PATCH 593/701] 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 e7ffe408cc7..8dc551c4072 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 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 594/701] 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 16e245ba640..9c783e237ab 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 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 595/701] 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 760e0785a78..3526abefa23 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 596/701] 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 2b25e0efab8..862ef5fdebc 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 597/701] 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 2b65c279136..cc31b9ae6e2 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 598/701] 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 cc31b9ae6e2..7f61ded7d88 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 599/701] 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 7f61ded7d88..46b143fd15a 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 600/701] 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 46b143fd15a..7c072dcd1a2 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 601/701] 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 7c072dcd1a2..7f61ded7d88 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 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 602/701] 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 9cab91ce52b..2c003a67598 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 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 603/701] 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 d37f97c38a4..66a9132ae44 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 48ca12321a2..99edfe5bc72 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 c8b075ffb49..c3a88a505c5 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 21f7f87875e..4b7416f6ad9 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 a0cfc084061..55f4d672733 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 947f7b896f6..d2bd680aa38 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 78ad7b32330..bc055ca9f66 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 dce60079e43..aa65bf94f36 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 6cfcd485f76..445ba54ac4d 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 88d1adf92ed..e943fa2a3b0 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 6d0716a6f1c..fffa4503e14 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 e8af185b8c2..bc055e71c66 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 8ce448d06b8..7b346a232ab 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 4a9b98f214e..acd3430f5c2 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 58903488601..1b32238813f 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 34f916674ca..4c224a6c713 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 98da6cb7a5e..86a377c8edc 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 604/701] 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 0abadf71534..e71abf3a585 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 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 605/701] 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 e71abf3a585..20306d08a29 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 98715ca4060c262d90f48e31c1f1d202bd2d23b5 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Fri, 26 Oct 2018 13:16:58 +0200 Subject: [PATCH 606/701] 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 8f64d023c19..06b69c512a1 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 7db2cc9fbac6adc17e43be576aa149b7e7965b8a Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Fri, 26 Oct 2018 17:50:12 +0530 Subject: [PATCH 607/701] 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 862ef5fdebc..4922a9f365c 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 608/701] 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 e965e8ad207..74e2c562623 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 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 609/701] 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 e1345edcf14..9ba50738ebc 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 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 610/701] 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 b46e286e750..41ac72bd8da 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 dfa2f25534e05050fde25d2b4b960f5ecfa173bd Mon Sep 17 00:00:00 2001 From: Rus0 <andoni@space.bar> Date: Fri, 26 Oct 2018 14:50:55 -0500 Subject: [PATCH 611/701] 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 0cc4143e569..c62f6459a5e 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 612/701] 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 9fafbc9d967..1d12645019d 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 754d80302d4..6029a2b8200 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 f340d0b204b..ae479a9b34d 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 a196b10478c..ff7340f87f3 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 7cb5b03b038..9551cfe982b 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 2170864407e..f3e060ad5fc 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 22962aacc8d..49ed8a10bee 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 af47f627670..7933da7c5fe 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 e3d5528d62c..89fea2bec73 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 f62c07b149c..4532479c482 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 5cb265d3d62..c06e2626034 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 f91401e43ea..50d82b19d10 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 4b904cc2b55..bba4d67ddd1 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 11e305f806b..7ad2f21c89d 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 807a70ecd75..f39a91161c1 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 d694697284f..df74eeec972 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 76c5a6d0313..d429d0a0c99 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 613/701] 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 0cc4143e569..c62f6459a5e 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 614/701] 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 c62f6459a5e..d33374d5430 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 615/701] 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 d33374d5430..53faa4e2348 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 616/701] 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 53faa4e2348..749a12f7d8b 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 617/701] 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 18efef38b20..a9a859ea1b5 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 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 618/701] 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 8a7d13cf42b..17c8cb52abb 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 619/701] 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 5a290d5141e..068580927b9 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 620/701] 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 8d4580f90c7..bc1f36222dd 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 621/701] 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 b3e4a91180b..3503abcc304 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 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 622/701] 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 9c783e237ab..1866138cf16 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 623/701] 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 1866138cf16..1a1eebf30f7 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 624/701] 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 17c8cb52abb..00000000000 --- 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 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 625/701] 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 cc722b6d61b..b86c7b79a0c 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 9e9dbd3dd67..5571c20f526 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 878f9cb4dc4..eed4fbb643d 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 d49ad294114..5db5dc59b4e 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 333904e398c..b390e2fa7d1 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 70b01046f6a..ecea5716f65 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 260a38a481b..2b5f644e359 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 e061455acbe..cc12e138826 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 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 626/701] 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 9e3a28be4c9..cf7a9098895 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 22abbcbb6ac21b32ca25b93f55bba8079a2d56c9 Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Sun, 28 Oct 2018 15:37:38 +0530 Subject: [PATCH 627/701] 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 236585fa613..e43f35b072f 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 628/701] 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 e2a646275d9..7601bb34bb6 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 2550f70f0be..2ebd20b8485 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 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 629/701] 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 d073f3866bf..73b4f10b3b0 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 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 630/701] 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 11bf03c1d5e..4b3d5c92587 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 7601bb34bb6..770e93fd17e 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 2ebd20b8485..43777f5c948 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 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 631/701] 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 4945308c26c..58806126aee 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 632/701] 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 8999b03b647..988d61986e3 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 633/701] 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 df3766250ca..7b2fa1981bc 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 acd3430f5c2..97ecb778b8c 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 00000000000..50b28e2bac0 --- /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 00000000000..3b9e9b66427 --- /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 00000000000..7d7d85c71a9 --- /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 634/701] 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 74e2c562623..1fc3257ff2c 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 635/701] 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 06b69c512a1..e850f6af86c 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 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 636/701] 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 e4c0dce0c5b..18aedfa97f9 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 a66753c2adf..f7bd155fd2d 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 7a7a6d2124c..2f721f05f5e 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 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 637/701] 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 068580927b9..77f67480619 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 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 638/701] 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 1a1eebf30f7..cf24998590a 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 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 639/701] 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 5abec8efbfd..fe80fe10549 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 00000000000..ac5d8005180 --- /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 640/701] 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 f2a3ab8f83f..06c072276f0 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 a6ea2c13579..7f2f0b43903 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 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 641/701] 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 749a12f7d8b..06bfbcf24da 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 a9a859ea1b5..8a45aa8c795 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 cf7a9098895..58582d344e7 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 31009555bd9..7c975bea34a 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 642/701] 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 ed6a4d1ad72..7c63af0bd0e 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 643/701] 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 5e65faec60d..ddc3cb45540 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 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 644/701] 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 50b28e2bac0..00000000000 --- 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 645/701] 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 5afac59b25d..14ae38667d8 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 3eb5d688850..f34cfbbf5fd 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 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 646/701] 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 3b9e9b66427..00000000000 --- 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 7d7d85c71a9..00000000000 --- 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 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 647/701] 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 0dca0f8606a..6961a89b41e 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 91c3ce47fc8..023c7414927 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 648/701] 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 6961a89b41e..242947d19b3 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 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 649/701] 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 41ac72bd8da..d78c4f5e61a 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 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 650/701] 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 6408276630c..3ee284a705b 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 651/701] 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 9ba50738ebc..a8ca6969a6e 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 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 652/701] 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 1a1eebf30f7..4fce12dc2de 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 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 653/701] 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 7c975bea34a..ce9c98c9d25 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 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 654/701] 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 a8ca6969a6e..7a1a09efaa7 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 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 655/701] 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 06c072276f0..ed27dfd646c 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 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 656/701] 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 294490a665c..d9a5ccb00d8 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 657/701] 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 6a2f329d095..6f9a1a46826 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 658/701] 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 64b934061b6..69c369f1ec9 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 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 659/701] 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 fd0d1699671..e13d31342db 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 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 660/701] 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 0ca1d72a3ae..fb67838e941 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 dba4a94f3db..9698f9cef42 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 32ac73aca7c..0ca252aa735 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 661/701] 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 7c12b546d13..361c5031f33 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 d951d84bab7..f79cf8d7eb7 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 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 662/701] 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 2a5dc27328a..cf64c0140b9 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 0a463a95e31..158cb0ebc0e 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 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 663/701] #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 38879178235..ac19ad5116c 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 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 664/701] 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 21ecf10c1b1..98adcbb3a82 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 329c158d897..aa4b3472602 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 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 665/701] 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 5571c20f526..a450187dd09 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 eed4fbb643d..4d04d2fed8e 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 5db5dc59b4e..a0907726ccc 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 b390e2fa7d1..c7c1f93e8ca 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 ecea5716f65..11da740c466 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 988d61986e3..f11d16755ef 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 ff44a91a649..c889c58e3df 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 3ee284a705b..8848fabb9ea 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 dcd3bc93569..c639b607e27 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 a919a54cf62..0a49e012690 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 f34cfbbf5fd..e311eb924de 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 69c369f1ec9..e8ff8f09c34 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 666/701] 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 c6d14eb38bc..d4ac4fc091b 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 667/701] 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 bd7cdabb408..6c0629feaf6 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 33f26302394..38960ab6639 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 668/701] 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 b3c15799011..8178baef71a 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 c2c2cedc665..1f702bfe4bc 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 6847b4681de..ced999bb860 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 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 669/701] 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 007635b1243..5faf6ccbcde 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 3ee284a705b..19f91953a07 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 77d8330a725..8bc602c75db 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 ddf810f433f..db101b5e81a 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 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 670/701] #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 f64a80bf535..c75301018e1 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 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 671/701] 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 ffa8e250310..3d5213cb2a4 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 672/701] =?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 3d5213cb2a4..7994c22c148 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 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 673/701] 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 9173307a7d2..8beecffd1c8 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 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 674/701] =?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 7994c22c148..98ba6c0d718 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 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 675/701] 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 8b5d0612050..b94f1993053 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 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 676/701] 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 c2839651b58..22a61367370 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 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 677/701] 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 1bb601e3a4e..ce618f97883 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 678/701] 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 e4f03ff238d..5a985fc3380 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 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 679/701] #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 6507da5e1a9..29a0cc0f0c2 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 680/701] 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 5c05d4a8400..0edd8f4183f 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 681/701] 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 98ba6c0d718..ff1bf99162a 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 682/701] 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 c49fdc80da8..388b583f990 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 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 683/701] 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 b2ab1627b24..5dc51518f0b 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 da0aa49d969..c40387aba46 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 381c18d3ee6..7365195d0cd 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 248dfc8e16d..73b2f762057 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 7d229bc3589..24027cacd9e 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 87ba4d7c280..e3a948d6c63 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 06a8a0accc7..65512653ce3 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 0560158a826..fe15c06bdea 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 67518a6c7d1..748337443d7 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 7c4b6984b3f..3b706f8e97d 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 c793714f691..ff9413aa90f 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 27797d08679..e0cbab450f6 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 c915d50741d..14f55f32add 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 9112192f6eb..6867944d95f 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 0f6a402e260..6b53a1a4c15 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 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 684/701] 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 73b2f762057..2c41ce3d8b4 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 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 685/701] 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 5faf6ccbcde..78a49cd1e8b 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 8bc602c75db..083ec0089a5 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 db101b5e81a..4f795d949b8 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 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 686/701] 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 ca75e3b203f..a5408426514 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 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 687/701] 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 0967f1a0189..b0729647d7e 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 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 688/701] 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 8dc551c4072..ae4be4a1e62 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 5059d61eb3f..f2b8133e352 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 b94f1993053..cfa60558077 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 ac19ad5116c..d82109ac126 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 ff9413aa90f..0621c63acbd 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 e0cbab450f6..3e5f9bcf0bd 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 6867944d95f..cf38fd70884 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 6b53a1a4c15..4678af60d63 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 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 689/701] 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 249f1dc40b1..00000000000 --- 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 fb042c7e59c..5efe37d8f91 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 00000000000..dc7c4b1c030 --- /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 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 690/701] 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 c9f2e5264b9..791696b2fa2 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 691/701] 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 b0729647d7e..6d228e30b8a 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 692/701] 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 8b295c9f5fc..37e07d13195 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 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 693/701] 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 ceb4505c796..56ed42fbfbb 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 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 694/701] 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 e9020c2df53..f971e357426 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 c6659080ee9..3c19ce599a9 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 695/701] 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 cc91ba7ed39..a3c6298c70a 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 dc7c4b1c030..b55c6c1d914 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 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 696/701] 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 89d9b320c04..9742e37f2df 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 697/701] 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 e43f35b072f..3668bd17477 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 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 698/701] 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 22a61367370..cf05079b0a0 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 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 699/701] 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 6c0629feaf6..853bbeac8eb 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 ff1bf99162a..f889549a107 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 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 700/701] 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 e32e6b9e6ec..ff1e27a2efa 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 68fe8087c4f..05b85a3a55c 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 3b741e7bf79..b87ab626d39 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 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 701/701] 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 dcfdca9e8ed..4b18fc7b983 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"/>