From cc1e013ff822aacccf9c8bf9c6c320f5a9f1f606 Mon Sep 17 00:00:00 2001 From: Burlacu Vasilii Date: Sun, 1 Apr 2018 13:48:22 +0300 Subject: [PATCH 01/51] Updated Magento_Rule rules.js file Added calendar initializaton for Conditional Rules when a rule is created for the 1st time --- app/code/Magento/Rule/view/adminhtml/web/rules.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Rule/view/adminhtml/web/rules.js b/app/code/Magento/Rule/view/adminhtml/web/rules.js index 5c4be367b9cb3..8127ae77c3a13 100644 --- a/app/code/Magento/Rule/view/adminhtml/web/rules.js +++ b/app/code/Magento/Rule/view/adminhtml/web/rules.js @@ -220,6 +220,8 @@ define([ var elem = Element.down(elemContainer, 'input.input-text'); + jQuery(elem).trigger('contentUpdated'); + if (elem) { elem.focus(); From ff4b005c34c541951d31691515f1e5c33c75798e Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu Date: Sat, 11 Aug 2018 20:42:10 +0300 Subject: [PATCH 02/51] Disabled autocomplete for datepicker (calendar) input field --- lib/web/mage/calendar.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index 51ee9b3a8891a..90810ec511cfa 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -377,6 +377,9 @@ .addClass('v-middle') .text('') // Remove jQuery UI datepicker generated image .append('' + pickerButtonText + ''); + + $(element).attr('autocomplete', 'off'); + this._setCurrentDate(element); }, From 172ecf6f1d37825bfb72db4517c1653b047c01c3 Mon Sep 17 00:00:00 2001 From: Ian Date: Mon, 15 Oct 2018 13:59:21 +0100 Subject: [PATCH 03/51] 18615 updates structure for last_trans_id to be varchar 255 which is inline with klarna_core_order order_id and amazon_sales_order amazon_order_reference_id. Limit was 32 characters where as a klarna_order reference is 36 characters at present. --- app/code/Magento/Sales/Setup/InstallSchema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Setup/InstallSchema.php b/app/code/Magento/Sales/Setup/InstallSchema.php index 3c1da7add06ec..444d99f0ec3ca 100644 --- a/app/code/Magento/Sales/Setup/InstallSchema.php +++ b/app/code/Magento/Sales/Setup/InstallSchema.php @@ -2007,7 +2007,7 @@ public function install(SchemaSetupInterface $setup, ModuleContextInterface $con )->addColumn( 'last_trans_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, - 32, + 255, [], 'Last Trans Id' )->addColumn( From 8718a606c76de371554b004ef84b264fa68a509d Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko Date: Fri, 12 Oct 2018 15:06:28 +0300 Subject: [PATCH 04/51] 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 c7ce4b2f2f11b..131eca5f33487 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); } @@ -118,6 +132,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()) @@ -128,7 +145,7 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select, [ 'customer_id' => $customer->getId(), - 'store_id' => $customer->getStoreId() + 'store_id' => $storeId ] ); @@ -146,7 +163,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 b916f20dbe770..806d518c43b1f 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -610,16 +610,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 2a7e00f14cb789722a72b147d6da8725b7c2c86f Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko Date: Fri, 12 Oct 2018 15:07:02 +0300 Subject: [PATCH 05/51] 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 99b23de5b6b6c..9c543c831ded3 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php @@ -211,6 +211,7 @@ public function testSubscribeNotLoggedIn() public function testUpdateSubscription() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -232,7 +233,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) @@ -246,6 +247,7 @@ public function testUpdateSubscription() public function testUnsubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -263,7 +265,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(); @@ -272,6 +274,7 @@ public function testUnsubscribeCustomerById() public function testSubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -289,7 +292,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(); @@ -298,6 +301,7 @@ public function testSubscribeCustomerById() public function testSubscribeCustomerById1() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -315,7 +319,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()) @@ -329,6 +333,7 @@ public function testSubscribeCustomerById1() public function testSubscribeCustomerByIdAfterConfirmation() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -346,7 +351,7 @@ public function testSubscribeCustomerByIdAfterConfirmation() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); $this->customerAccountManagement->expects($this->never())->method('getConfirmationStatus'); diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php index 39db400d2d637..dbc666e49b6cf 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php @@ -167,4 +167,42 @@ private function verifySubscriptionNotExist($email) $this->assertEquals(0, (int)$subscriber->getId()); return $subscriber; } + + /** + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + */ + public function testCustomerWithZeroStoreIdIsSubscribed() + { + $objectManager = Bootstrap::getObjectManager(); + + $currentStore = $objectManager->get( + \Magento\Store\Model\StoreManagerInterface::class + )->getStore()->getId(); + + $subscriber = $objectManager->create(\Magento\Newsletter\Model\Subscriber::class); + /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ + $subscriber->setStoreId($currentStore) + ->setCustomerId(0) + ->setSubscriberEmail('customer@example.com') + ->setSubscriberStatus(\Magento\Newsletter\Model\Subscriber::STATUS_SUBSCRIBED) + ->save(); + + /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory */ + $customerFactory = $objectManager->get(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); + $customerDataObject = $customerFactory->create() + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->setStoreId(0) + ->setEmail('customer@example.com'); + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ + $customer = $this->accountManagement->createAccount($customerDataObject); + + $this->customerRepository->save($customer); + + $subscriber->loadByEmail('customer@example.com'); + + $this->assertEquals($customer->getId(), (int)$subscriber->getCustomerId()); + $this->assertEquals($currentStore, (int)$subscriber->getStoreId()); + } } From 3590785e68331e7ab30dbc2f6c974f8f7a45b58a Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 16 Oct 2018 21:14:05 +0100 Subject: [PATCH 06/51] revert change to last_trans_id length in InstallSchema, move to Upgrade Schema --- app/code/Magento/Sales/Setup/InstallSchema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Setup/InstallSchema.php b/app/code/Magento/Sales/Setup/InstallSchema.php index 444d99f0ec3ca..3c1da7add06ec 100644 --- a/app/code/Magento/Sales/Setup/InstallSchema.php +++ b/app/code/Magento/Sales/Setup/InstallSchema.php @@ -2007,7 +2007,7 @@ public function install(SchemaSetupInterface $setup, ModuleContextInterface $con )->addColumn( 'last_trans_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, - 255, + 32, [], 'Last Trans Id' )->addColumn( From 3a88a38399cf011c737f067be9ec5cb60f99fbd9 Mon Sep 17 00:00:00 2001 From: rahul Date: Sun, 28 Oct 2018 15:30:07 +0530 Subject: [PATCH 07/51] 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 09d5372291a0a..5c7fdb0630186 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -35,6 +35,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 38bfe669e125dd6116fa2581009796439b0ee36a Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Sun, 28 Oct 2018 12:22:57 +0200 Subject: [PATCH 08/51] Fix the issue with missing asterisk for admin required fields #18904 --- .../Magento/Ui/view/base/web/templates/form/field.html | 8 +++++--- .../Magento/backend/web/css/source/forms/_extends.less | 2 ++ .../Magento/backend/web/css/source/forms/_fields.less | 4 ++-- 3 files changed, 9 insertions(+), 5 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 144825967401e..6a095b4da14ed 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html @@ -8,9 +8,11 @@ visible="visible" css="$data.additionalClasses" attr="'data-index': index"> - - +
+ +
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less index 01b5ae080130f..24779dc8baa30 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_extends.less @@ -54,6 +54,8 @@ &._required { > .admin__field-label { span { + padding-left: 1.5rem; + &:after { left: 0; margin-left: @temp_gutter; 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 8107c81030590..aa706645cc9aa 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 @@ -221,7 +221,7 @@ overflow: hidden; } - label { + span { display: inline-block; line-height: @field-label__line-height; vertical-align: middle; @@ -239,7 +239,7 @@ .required > &, // ToDo UI: change classes 'required' to '_required'. ._required > & { - > label { + span { &:after { color: @validation__color; content: '*'; From bc485de186bd2422d3f7e872dfcf81a50e7cb519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torben=20Ho=CC=88hn?= Date: Tue, 30 Oct 2018 23:19:17 +0100 Subject: [PATCH 09/51] local themes should be added to git repo --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 94c3bf76a2bd1..75e5f11d8a8e7 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,6 @@ atlassian* /.php_cs /.php_cs.cache /grunt-config.json -/dev/tools/grunt/configs/local-themes.js /pub/media/*.* !/pub/media/.htaccess From 7d2dd6519c8be94a8d0b59f834fbd2f307d22e80 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Fri, 2 Nov 2018 00:41:08 +0200 Subject: [PATCH 10/51] Fix the functional tests failures #18904 --- .../Section/AdminProductCustomizableOptionsSection.xml | 10 +++++----- .../Test/Mftf/Section/AdminProductFormSection.xml | 6 +++--- .../Magento/Ui/view/base/web/templates/form/field.html | 4 ++-- .../Magento/backend/web/css/source/forms/_fields.less | 4 ++-- .../Edit/Section/ProductDetails/NewCategoryIds.xml | 2 +- .../Test/Block/Adminhtml/Product/ProductForm.php | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml index 81c6a80e7e3a7..fec0a9f672990 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml @@ -14,13 +14,13 @@ - - - + + + - + - + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 0cbb0cb519751..b91fd5d3b2a61 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -15,8 +15,8 @@ - - + + @@ -33,7 +33,7 @@ - +
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 6a095b4da14ed..ed84e158819a2 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"> -
-
- +
From f15ddaf1fdf9cbc49aa38837c943d0617412062b Mon Sep 17 00:00:00 2001 From: godvsdeity Date: Wed, 24 Oct 2018 02:00:10 +0300 Subject: [PATCH 28/51] performance improvements Get rid of unnecessary reviews queries on product listing: "select review_entity_summary.* from review_entity_summary where (review_entity_summary.entity_pk_value = ?) and (store_id = ?)" This query was executed for each product on listing which didn't have a review summary(@see: Magento\Review\Block\Product\ReviewRenderer::getReviewsSummaryHtml) --- app/code/Magento/Review/Model/Review.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Review/Model/Review.php b/app/code/Magento/Review/Model/Review.php index c00af3fc61407..e689d4ed460ac 100644 --- a/app/code/Magento/Review/Model/Review.php +++ b/app/code/Magento/Review/Model/Review.php @@ -5,6 +5,7 @@ */ namespace Magento\Review\Model; +use Magento\Framework\DataObject; use Magento\Catalog\Model\Product; use Magento\Framework\DataObject\IdentityInterface; use Magento\Review\Model\ResourceModel\Review\Product\Collection as ProductCollection; @@ -327,6 +328,9 @@ public function appendSummary($collection) $item->setRatingSummary($summary); } } + if (!$item->getRatingSummary()) { + $item->setRatingSummary(new DataObject()); + } } return $this; From cb7b67e9239601dda25d0cc14abc3e29c313b374 Mon Sep 17 00:00:00 2001 From: Bernard van der Esch Date: Fri, 2 Nov 2018 11:29:18 +0100 Subject: [PATCH 29/51] missing use statement in layout generator --- lib/internal/Magento/Framework/View/Layout/Generator/Block.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php index e995b2c20a6ab..358c6b4442b79 100755 --- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php @@ -6,6 +6,7 @@ namespace Magento\Framework\View\Layout\Generator; use Magento\Framework\App\State; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\ObjectManager\Config\Reader\Dom; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Layout; From 0cc9a11f044efab995e622512de9a82020f555d5 Mon Sep 17 00:00:00 2001 From: Bernard van der Esch Date: Fri, 2 Nov 2018 11:43:29 +0100 Subject: [PATCH 30/51] import class to the use statement --- lib/internal/Magento/Framework/View/Layout/Generator/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php index 358c6b4442b79..0b90be3ddfc7e 100755 --- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php +++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php @@ -273,7 +273,7 @@ protected function getBlockInstance($block, array $arguments = []) } } if (!$block instanceof \Magento\Framework\View\Element\AbstractBlock) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( new \Magento\Framework\Phrase( 'Invalid block type: %1', [is_object($block) ? get_class($block) : (string) $block] From 20922a02cd1ed9a70bae9dee530b5ef0b712b436 Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin Date: Sat, 10 Nov 2018 20:06:15 +0200 Subject: [PATCH 31/51] 19082-Fatal-error-Uncaught-Error-Cannot-call-abstract-method-Magento-Framework-App-ActionInterface-execute add method to prevent fatal error when go to catalog/product/compare/ --- app/code/Magento/Catalog/Controller/Product/Compare.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php index 1ee146e5aaa70..63478080bce1a 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare.php @@ -139,4 +139,13 @@ public function setCustomerId($customerId) $this->_customerId = $customerId; return $this; } + + /** + * {@inheritdoc} + */ + public function execute() + { + return $this->_redirect('catalog/product_compare'); + } + } From 27c265daa106c269e18f164c5dbb6ac7c1d5a965 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Sun, 18 Nov 2018 17:19:20 +0200 Subject: [PATCH 32/51] Fix the issue: Content overlaps the close button #19263 --- lib/web/css/source/components/_modals.less | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/web/css/source/components/_modals.less b/lib/web/css/source/components/_modals.less index 80b1c85ceb46e..bd7cf728baa12 100644 --- a/lib/web/css/source/components/_modals.less +++ b/lib/web/css/source/components/_modals.less @@ -100,6 +100,16 @@ left: 0; overflow-y: auto; + &.confirm { + .modal-inner-wrap { + .lib-css(width, @modal-popup-confirm__width); + + .modal-content { + padding-right: 7rem; + } + } + } + &._show { .modal-inner-wrap { -webkit-transform: translateY(0); From 33b0a51a9b9629c635b99b45d10016a22be68ca8 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Thu, 22 Nov 2018 14:28:56 +0200 Subject: [PATCH 33/51] MAGETWO-93424: Permanent Redirect for old URL missing via API or no documentation --- .../Controller/Rest/InputParamsResolver.php | 88 +++++++++++++ .../Rest/InputParamsResolverTest.php | 116 ++++++++++++++++++ .../Magento/CatalogUrlRewrite/composer.json | 3 + .../CatalogUrlRewrite/etc/webapi_rest/di.xml | 3 + 4 files changed, 210 insertions(+) create mode 100644 app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php new file mode 100644 index 0000000000000..4e8e3840693a5 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -0,0 +1,88 @@ +request = $request; + } + + /** + * Add 'save_rewrites_history' param to the product data + * + * @see \Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization\Helper + * @param \Magento\Webapi\Controller\Rest\InputParamsResolver $subject + * @param array $result + * @return array + */ + public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver $subject, array $result): array + { + $route = $subject->getRoute(); + $serviceMethodName = $route->getServiceMethod(); + $serviceClassName = $route->getServiceClass(); + $requestBodyParams = $this->request->getBodyParams(); + + if ($this->isProductSaveCalled($serviceClassName, $serviceMethodName) + && $this->isCustomAttributesExists($requestBodyParams)) { + foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) { + if ($attribute['attribute_code'] === 'save_rewrites_history') { + foreach ($result as $resultItem) { + if ($resultItem instanceof \Magento\Catalog\Model\Product) { + $resultItem->setData('save_rewrites_history', (bool)$attribute['value']); + break 2; + } + } + break; + } + } + } + return $result; + } + + /** + * Check that product save method called + * + * @param string $serviceClassName + * @param string $serviceMethodName + * @return bool + */ + private function isProductSaveCalled(string $serviceClassName, string $serviceMethodName): bool + { + return $serviceClassName === ProductRepositoryInterface::class && $serviceMethodName === 'save'; + } + + /** + * Check is any custom options exists in product data + * + * @param array $requestBodyParams + * @return bool + */ + private function isCustomAttributesExists(array $requestBodyParams): bool + { + return !empty($requestBodyParams['product']['custom_attributes']); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php new file mode 100644 index 0000000000000..8e705b2c09f6b --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php @@ -0,0 +1,116 @@ +saveRewritesHistory = 'save_rewrites_history'; + $this->requestBodyParams = [ + 'product' => [ + 'sku' => 'test', + 'custom_attributes' => [ + ['attribute_code' => $this->saveRewritesHistory, 'value' => 1] + ] + ] + ]; + + $this->route = $this->createPartialMock(Route::class, ['getServiceMethod', 'getServiceClass']); + $this->request = $this->createPartialMock(RestRequest::class, ['getBodyParams']); + $this->request->expects($this->any())->method('getBodyParams')->willReturn($this->requestBodyParams); + $this->subject = $this->createPartialMock(InputParamsResolver::class, ['getRoute']); + $this->subject->expects($this->any())->method('getRoute')->willReturn($this->route); + $this->product = $this->createPartialMock(Product::class, ['setData']); + + $this->result = [false, $this->product, 'test']; + + $this->objectManager = new ObjectManager($this); + $this->plugin = $this->objectManager->getObject( + InputParamsResolverPlugin::class, + [ + 'request' => $this->request + ] + ); + } + + public function testAfterResolve() + { + $this->route->expects($this->once()) + ->method('getServiceClass') + ->willReturn(ProductRepositoryInterface::class); + $this->route->expects($this->once()) + ->method('getServiceMethod') + ->willReturn('save'); + $this->product->expects($this->once()) + ->method('setData') + ->with($this->saveRewritesHistory, true); + + $this->plugin->afterResolve($this->subject, $this->result); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index 66011fcac287e..f6d3f2102940c 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -13,6 +13,9 @@ "magento/framework": "101.0.*", "magento/module-ui": "101.0.*" }, + "suggest": { + "magento/module-webapi": "*" + }, "type": "magento2-module", "version": "100.2.5", "license": [ diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml index ac8beb362f0fb..34b7487725d76 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml @@ -7,4 +7,7 @@ --> + + + From d332f71867ee011b743f2b88a9235e4be117ec1c Mon Sep 17 00:00:00 2001 From: Henryk Tews Date: Fri, 19 Oct 2018 13:14:10 +0200 Subject: [PATCH 34/51] Changed get product way in blocks with related products --- .../Magento/Catalog/Block/Product/ProductList/Crosssell.php | 2 +- app/code/Magento/Catalog/Block/Product/ProductList/Related.php | 2 +- app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php index 0c547f81c85d6..043704a9f2bca 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Crosssell.php @@ -25,7 +25,7 @@ class Crosssell extends \Magento\Catalog\Block\Product\AbstractProduct */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getCrossSellProductCollection()->addAttributeToSelect( diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 3f9dac98033aa..efa4fe4330c84 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -82,7 +82,7 @@ public function __construct( */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect( diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index 40afd44305262..5890164b304b6 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -97,7 +97,7 @@ public function __construct( */ protected function _prepareData() { - $product = $this->_coreRegistry->registry('product'); + $product = $this->getProduct(); /* @var $product \Magento\Catalog\Model\Product */ $this->_itemCollection = $product->getUpSellProductCollection()->setPositionOrder()->addStoreFilter(); if ($this->moduleManager->isEnabled('Magento_Checkout')) { From fe930343b0f7db7c588d6d1a21edbaa391ad07ca Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Fri, 23 Nov 2018 09:54:04 +0200 Subject: [PATCH 35/51] MAGETWO-93424: Permanent Redirect for old URL missing via API or no documentation --- .../Controller/Rest/InputParamsResolver.php | 5 +++-- .../Rest/InputParamsResolverTest.php | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php index 4e8e3840693a5..c4a39f4a7f620 100644 --- a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -10,6 +10,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\Webapi\Rest\Request as RestRequest; +use Magento\Webapi\Controller\Rest\InputParamsResolver as InputParamsResolverController; /** * Plugin for InputParamsResolver @@ -35,11 +36,11 @@ public function __construct(RestRequest $request) * Add 'save_rewrites_history' param to the product data * * @see \Magento\CatalogUrlRewrite\Plugin\Catalog\Controller\Adminhtml\Product\Initialization\Helper - * @param \Magento\Webapi\Controller\Rest\InputParamsResolver $subject + * @param InputParamsResolverController $subject * @param array $result * @return array */ - public function afterResolve(\Magento\Webapi\Controller\Rest\InputParamsResolver $subject, array $result): array + public function afterResolve(InputParamsResolverController $subject, array $result): array { $route = $subject->getRoute(); $serviceMethodName = $route->getServiceMethod(); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php index 8e705b2c09f6b..1091515da1168 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php @@ -15,6 +15,7 @@ use Magento\Catalog\Model\Product; use Magento\Webapi\Controller\Rest\Router\Route; use Magento\Catalog\Api\ProductRepositoryInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Unit test for InputParamsResolver plugin @@ -42,22 +43,22 @@ class InputParamsResolverTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * @var InputParamsResolver|\PHPUnit_Framework_MockObject_MockObject + * @var InputParamsResolver|MockObject */ private $subject; /** - * @var RestRequest|\PHPUnit_Framework_MockObject_MockObject + * @var RestRequest|MockObject */ private $request; /** - * @var Product|\PHPUnit_Framework_MockObject_MockObject + * @var Product|MockObject */ private $product; /** - * @var Route|\PHPUnit_Framework_MockObject_MockObject + * @var Route|MockObject */ private $route; @@ -76,16 +77,21 @@ protected function setUp() 'product' => [ 'sku' => 'test', 'custom_attributes' => [ - ['attribute_code' => $this->saveRewritesHistory, 'value' => 1] + [ + 'attribute_code' => $this->saveRewritesHistory, + 'value' => 1 + ] ] ] ]; $this->route = $this->createPartialMock(Route::class, ['getServiceMethod', 'getServiceClass']); $this->request = $this->createPartialMock(RestRequest::class, ['getBodyParams']); - $this->request->expects($this->any())->method('getBodyParams')->willReturn($this->requestBodyParams); + $this->request->method('getBodyParams') + ->willReturn($this->requestBodyParams); $this->subject = $this->createPartialMock(InputParamsResolver::class, ['getRoute']); - $this->subject->expects($this->any())->method('getRoute')->willReturn($this->route); + $this->subject->method('getRoute') + ->willReturn($this->route); $this->product = $this->createPartialMock(Product::class, ['setData']); $this->result = [false, $this->product, 'test']; From 132a754013526eaaeaad4d80270a654d594295b3 Mon Sep 17 00:00:00 2001 From: Abrar pathan Date: Sat, 3 Nov 2018 11:58:43 +0530 Subject: [PATCH 36/51] fixed-18887-notifications-counter --- .../css/source/module/header/actions-group/_notifications.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index c9c97930297cb..93fc0d3eb4948 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -103,6 +103,7 @@ padding: .3em .5em; position: absolute; top: 50%; + width: 18px; } } From 91fc40c4eeafefddba2bcee6c0ae18d9fb95ea22 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets Date: Mon, 19 Nov 2018 12:24:14 +0200 Subject: [PATCH 37/51] Update _notifications.less --- .../css/source/module/header/actions-group/_notifications.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index 93fc0d3eb4948..ceeb8d8eeb2b3 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -103,7 +103,8 @@ padding: .3em .5em; position: absolute; top: 50%; - width: 18px; + min-width: 18px; + height: 18px; } } From 7559e3e1e3005b37750f07f791f8efaa0a0a6264 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Fri, 2 Nov 2018 17:09:46 +0200 Subject: [PATCH 38/51] #13157 - Last Ordered Items block - bad js code --- .../view/frontend/templates/reorder/sidebar.phtml | 14 +++++++++----- .../frontend/web/js/view/last-ordered-items.js | 12 ++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 5ecf1ebe893bc..370e034ead64a 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -26,14 +26,18 @@
  1. -
    +
    @@ -46,8 +50,8 @@
-
+
diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index f393cc3fcd3bc..9897666653df9 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -12,18 +12,14 @@ define([ return Component.extend({ /** @inheritdoc */ initialize: function () { - var isShowAddToCart = false, - item; + var isShowAddToCart; this._super(); this.lastOrderedItems = customerData.get('last-ordered-items'); - for (item in this.lastOrderedItems.items) { - if (item['is_saleable']) { - isShowAddToCart = true; - break; - } - } + isShowAddToCart = _.some(this.lastOrderedItems().items, { + 'is_saleable': true + }); this.lastOrderedItems.isShowAddToCart = isShowAddToCart; } From 58550b9a406536cf8b6db8af2ca62d9f8a18aec9 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Tue, 6 Nov 2018 13:03:59 +0200 Subject: [PATCH 39/51] #13157 - Last Ordered Items block - bad js code --- .../Sales/view/frontend/web/js/view/last-ordered-items.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index 9897666653df9..74465128f8c72 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -5,8 +5,9 @@ define([ 'uiComponent', - 'Magento_Customer/js/customer-data' -], function (Component, customerData) { + 'Magento_Customer/js/customer-data', + 'underscore' +], function (Component, customerData, _) { 'use strict'; return Component.extend({ From f1bb98ec0b2ffe12cd91b161f83bfd76cda0827f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Tue, 13 Nov 2018 13:25:39 -0600 Subject: [PATCH 40/51] #13157 - Last Ordered Items block - bad js code --- .../frontend/templates/reorder/sidebar.phtml | 2 +- .../web/js/view/last-ordered-items.js | 27 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 370e034ead64a..9b3633fde60b4 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -51,7 +51,7 @@
+ data-bind="visible: isShowAddToCart"> diff --git a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js index 74465128f8c72..17e61a77d98a3 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js +++ b/app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js @@ -11,18 +11,37 @@ define([ 'use strict'; return Component.extend({ + defaults: { + isShowAddToCart: false + }, + /** @inheritdoc */ initialize: function () { - var isShowAddToCart; - this._super(); this.lastOrderedItems = customerData.get('last-ordered-items'); + this.lastOrderedItems.subscribe(this.checkSalableItems.bind(this)); + this.checkSalableItems(); + + return this; + }, + + /** @inheritdoc */ + initObservable: function () { + this._super() + .observe('isShowAddToCart'); + + return this; + }, - isShowAddToCart = _.some(this.lastOrderedItems().items, { + /** + * Check if items is_saleable and change add to cart button visibility. + */ + checkSalableItems: function () { + var isShowAddToCart = _.some(this.lastOrderedItems().items, { 'is_saleable': true }); - this.lastOrderedItems.isShowAddToCart = isShowAddToCart; + this.isShowAddToCart(isShowAddToCart); } }); }); From f4250a0f3f26dea7a7b946af3261b70cf4ae0df1 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Wed, 21 Nov 2018 14:39:46 +0200 Subject: [PATCH 41/51] Fix the issue with repetitive "tbody" tag for order items table --- .../Magento/Sales/view/frontend/templates/order/items.phtml | 5 +++-- .../Magento/luma/Magento_Sales/web/css/source/_module.less | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml index e43d32760febb..dc179b6ee4ac1 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml @@ -29,9 +29,10 @@ getItems(); ?> + getParentItem()) continue; ?> - + getItemHtml($item) ?> helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $item) && $item->getGiftMessageId()): ?> helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($item); ?> @@ -62,8 +63,8 @@ - + isPagerDisplayed()): ?> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index 692f91ef463b1..2c75b71bebe9d 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -612,10 +612,6 @@ padding: 25px; .col { - &.name { - padding-left: 0; - } - &.price { text-align: center; } From 043b52f9759c88059b41f1d07f0934d164707132 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Thu, 22 Nov 2018 13:27:12 +0200 Subject: [PATCH 42/51] ENGCOM-3357: MTF tests fix. --- .../Mtf/Client/Element/ConditionsElement.php | 27 ++++++++++++++----- .../Mtf/Client/Element/DatepickerElement.php | 7 +++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php index d1fd351302414..6dbf2b1aa6a12 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php @@ -6,9 +6,9 @@ namespace Magento\Mtf\Client\Element; -use Magento\Mtf\ObjectManager; -use Magento\Mtf\Client\Locator; use Magento\Mtf\Client\ElementInterface; +use Magento\Mtf\Client\Locator; +use Magento\Mtf\ObjectManager; /** * Typified element class for conditions. @@ -135,6 +135,13 @@ class ConditionsElement extends SimpleElement */ protected $chooserGridLocator = 'div[id*=chooser]'; + /** + * Datepicker xpath. + * + * @var string + */ + private $datepicker = './/*[contains(@class,"ui-datepicker-trigger")]'; + /** * Key of last find param. * @@ -189,10 +196,7 @@ class ConditionsElement extends SimpleElement protected $exception; /** - * Set value to conditions. - * - * @param string $value - * @return void + * @inheritdoc */ public function setValue($value) { @@ -411,7 +415,16 @@ protected function fillText($rule, ElementInterface $param) { $value = $param->find('input', Locator::SELECTOR_TAG_NAME); if ($value->isVisible()) { - $value->setValue($rule); + if (!$value->getAttribute('readonly')) { + $value->setValue($rule); + } else { + $datepicker = $param->find( + $this->datepicker, + Locator::SELECTOR_XPATH, + DatepickerElement::class + ); + $datepicker->setValue($rule); + } $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH); if ($apply->isVisible()) { diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/DatepickerElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/DatepickerElement.php index a0e350cb3da43..eb277c2cc43dd 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/DatepickerElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/DatepickerElement.php @@ -66,13 +66,16 @@ public function setValue($value) $date = $this->parseDate($value); $date[1] = ltrim($date[1], '0'); $this->click(); - $this->find($this->datePickerButton, Locator::SELECTOR_XPATH)->click(); $datapicker = $this->find($this->datePickerBlock, Locator::SELECTOR_XPATH); + $datepickerClose = $datapicker->find($this->datePickerButtonClose, Locator::SELECTOR_XPATH); + if (!$datepickerClose->isVisible()) { + $this->find($this->datePickerButton, Locator::SELECTOR_XPATH)->click(); + } $datapicker->find($this->datePickerYear, Locator::SELECTOR_XPATH, 'select')->setValue($date[2]); $datapicker->find($this->datePickerMonth, Locator::SELECTOR_XPATH, 'select')->setValue($date[0]); $datapicker->find(sprintf($this->datePickerCalendar, $date[1]), Locator::SELECTOR_XPATH)->click(); if ($datapicker->isVisible()) { - $datapicker->find($this->datePickerButtonClose, Locator::SELECTOR_XPATH)->click(); + $datepickerClose->click(); } } From fc510d3fc68f599c86b6757146c0734549965c7e Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Fri, 23 Nov 2018 13:20:06 +0200 Subject: [PATCH 43/51] MAGETWO-93424: Permanent Redirect for old URL missing via API or no documentation --- .../Plugin/Webapi/Controller/Rest/InputParamsResolver.php | 3 ++- .../Webapi/Controller/Rest/InputParamsResolverTest.php | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php index c4a39f4a7f620..5908bde7c5a5f 100644 --- a/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Webapi/Controller/Rest/InputParamsResolver.php @@ -9,6 +9,7 @@ namespace Magento\CatalogUrlRewrite\Plugin\Webapi\Controller\Rest; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; use Magento\Framework\Webapi\Rest\Request as RestRequest; use Magento\Webapi\Controller\Rest\InputParamsResolver as InputParamsResolverController; @@ -52,7 +53,7 @@ public function afterResolve(InputParamsResolverController $subject, array $resu foreach ($requestBodyParams['product']['custom_attributes'] as $attribute) { if ($attribute['attribute_code'] === 'save_rewrites_history') { foreach ($result as $resultItem) { - if ($resultItem instanceof \Magento\Catalog\Model\Product) { + if ($resultItem instanceof Product) { $resultItem->setData('save_rewrites_history', (bool)$attribute['value']); break 2; } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php index 1091515da1168..9e611039e97cc 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Webapi/Controller/Rest/InputParamsResolverTest.php @@ -107,11 +107,9 @@ protected function setUp() public function testAfterResolve() { - $this->route->expects($this->once()) - ->method('getServiceClass') + $this->route->method('getServiceClass') ->willReturn(ProductRepositoryInterface::class); - $this->route->expects($this->once()) - ->method('getServiceMethod') + $this->route->method('getServiceMethod') ->willReturn('save'); $this->product->expects($this->once()) ->method('setData') From 57d6b3b325f6c82f46ae0cc9e60e279d171b8e04 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets Date: Fri, 23 Nov 2018 15:34:02 +0200 Subject: [PATCH 44/51] Code style fixes --- app/code/Magento/Catalog/Controller/Product/Compare.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php index 63478080bce1a..ff51a76c56d78 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare.php @@ -147,5 +147,4 @@ public function execute() { return $this->_redirect('catalog/product_compare'); } - } From 053291aae79a5720e6b888242e598dd691884ff9 Mon Sep 17 00:00:00 2001 From: Daniel Ruf Date: Thu, 22 Nov 2018 09:50:38 +0100 Subject: [PATCH 45/51] fix: remove old code in tabs, always set tabindex to 0 when tabs are initialized --- lib/web/mage/tabs.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index e7e04a26b29c1..b441477ab8d8a 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -83,7 +83,7 @@ define([ /** * When the widget gets instantiated, the first tab that is not disabled receive focusable property - * Updated: for accessibility all tabs receive tabIndex 0 + * All tabs receive tabIndex 0 * @private */ _processTabIndex: function () { @@ -91,17 +91,8 @@ define([ self.triggers.attr('tabIndex', 0); $.each(this.collapsibles, function (i) { - if (!$(this).collapsible('option', 'disabled')) { - self.triggers.eq(i).attr('tabIndex', 0); - - return false; - } - }); - $.each(this.collapsibles, function (i) { - $(this).on('beforeOpen', function () { - self.triggers.attr('tabIndex', 0); - self.triggers.eq(i).attr('tabIndex', 0); - }); + self.triggers.attr('tabIndex', 0); + self.triggers.eq(i).attr('tabIndex', 0); }); }, From 31851233ee6612c5550d2a2e1d617e819a697007 Mon Sep 17 00:00:00 2001 From: Tiago Sampaio Date: Fri, 23 Nov 2018 15:45:12 -0200 Subject: [PATCH 46/51] Fixing a test for Magento Newsletter. --- app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php index 889fc11d71d7e..1de3e6096cd96 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/ProblemTest.php @@ -68,6 +68,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->subscriberFactoryMock = $this->getMockBuilder(SubscriberFactory::class) + ->disableOriginalConstructor() ->getMock(); $this->subscriberMock = $this->getMockBuilder(Subscriber::class) ->disableOriginalConstructor() From 306cc65ee146f5d081dc761f0cf771f9733ede0c Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Sat, 24 Nov 2018 11:14:01 +0200 Subject: [PATCH 47/51] Removed obsolete _redirect method call --- app/code/Magento/Catalog/Controller/Product/Compare.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php index 63478080bce1a..c13328f4abdf1 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare.php @@ -141,11 +141,11 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function execute() { - return $this->_redirect('catalog/product_compare'); + return $this->resultRedirectFactory->create()->setPath('catalog/product_compare'); } } From ce701af9462ddd55e007c0a1c226b570ab0b2500 Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin Date: Sat, 24 Nov 2018 11:55:51 +0200 Subject: [PATCH 48/51] back-port-pull-19024 Back-port https://github.com/magento/magento2/pull/19024 from 2.3 to 2.2 --- .../Model/Import/Product.php | 31 +++++++++++++++++-- .../Import/Product/RowValidatorInterface.php | 2 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 3cf167e9e37e7..84fa13e6599d9 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -129,6 +129,16 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ const COL_NAME = 'name'; + /** + * Column new_from_date. + */ + const COL_NEW_FROM_DATE = 'new_from_date'; + + /** + * Column new_to_date. + */ + const COL_NEW_TO_DATE = 'new_to_date'; + /** * Column product website. */ @@ -292,7 +302,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_MEDIA_PATH_NOT_ACCESSIBLE => 'Imported resource (image) does not exist in the local media storage', ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE => 'Imported resource (image) could not be downloaded from external resource due to timeout or access permissions', ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid', - ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually' + ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', + ValidatorInterface::ERROR_NEW_TO_DATE => 'Make sure new_to_date is later than or the same as new_from_date', ]; /** @@ -313,8 +324,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity Product::COL_TYPE => 'product_type', Product::COL_PRODUCT_WEBSITES => 'product_websites', 'status' => 'product_online', - 'news_from_date' => 'new_from_date', - 'news_to_date' => 'new_to_date', + 'news_from_date' => self::COL_NEW_FROM_DATE, + 'news_to_date' => self::COL_NEW_TO_DATE, 'options_container' => 'display_product_options_in', 'minimal_price' => 'map_price', 'msrp' => 'msrp_price', @@ -2477,6 +2488,20 @@ public function validateRow(array $rowData, $rowNum) } } } + + if (!empty($rowData[self::COL_NEW_FROM_DATE]) && !empty($rowData[self::COL_NEW_TO_DATE]) + ) { + $newFromTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_FROM_DATE], false)); + $newToTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_TO_DATE], false)); + if ($newFromTimestamp > $newToTimestamp) { + $this->addRowError( + ValidatorInterface::ERROR_NEW_TO_DATE, + $rowNum, + $rowData[self::COL_NEW_TO_DATE] + ); + } + } + return !$this->getErrorAggregator()->isRowInvalid($rowNum); } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php index 17f7fae28ba75..49ffdebe7724d 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php @@ -85,6 +85,8 @@ interface RowValidatorInterface extends \Magento\Framework\Validator\ValidatorIn const ERROR_DUPLICATE_URL_KEY = 'duplicatedUrlKey'; + const ERROR_NEW_TO_DATE = 'invalidNewToDateValue'; + /** * Value that means all entities (e.g. websites, groups etc.) */ From 95a3136aea5e969a93f123eebbbd394aa1b9f2b1 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" Date: Mon, 26 Nov 2018 09:42:05 +0200 Subject: [PATCH 49/51] MAGETWO-94112: Configurable "As low As" Product Price Not Updating Correctly --- .../Catalog/view/base/web/js/price-box.js | 6 +- .../view/frontend/web/js/configurable.js | 68 ++++++++++++++++++- .../view/frontend/web/js/swatch-renderer.js | 48 ++++++++++++- 3 files changed, 118 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index 783d39cddbc76..de68d769885fd 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -78,7 +78,11 @@ define([ pricesCode = [], priceValue, origin, finalPrice; - this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; + if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty('prices')) { + this.cache.additionalPriceObject = {}; + } else { + this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; + } if (newPrices) { $.extend(this.cache.additionalPriceObject, newPrices); diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 6b6c1762fadd9..78974877dd90d 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -477,7 +477,9 @@ define([ _getPrices: function () { var prices = {}, elements = _.toArray(this.options.settings), - hasProductPrice = false; + hasProductPrice = false, + optionPriceDiff = 0, + allowedProduct, optionPrices, basePrice, optionFinalPrice; _.each(elements, function (element) { var selected = element.options[element.selectedIndex], @@ -485,8 +487,23 @@ define([ priceValue = {}; if (config && config.allowedProducts.length === 1 && !hasProductPrice) { + prices = {}; priceValue = this._calculatePrice(config); hasProductPrice = true; + } else if (element.value) { + allowedProduct = this._getAllowedProductWithMinPrice(config.allowedProducts); + optionPrices = this.options.spConfig.optionPrices; + basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount); + + if (!_.isEmpty(allowedProduct)) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + } + + if (optionPriceDiff !== 0) { + prices = {}; + priceValue = this._calculatePriceDifference(allowedProduct); + } } prices[element.attributeId] = priceValue; @@ -495,6 +512,55 @@ define([ return prices; }, + /** + * Get product with minimum price from selected options. + * + * @param {Array} allowedProducts + * @returns {String} + * @private + */ + _getAllowedProductWithMinPrice: function (allowedProducts) { + var optionPrices = this.options.spConfig.optionPrices, + product = {}, + optionMinPrice, optionFinalPrice; + + _.each(allowedProducts, function (allowedProduct) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + + if (_.isEmpty(product)) { + optionMinPrice = optionFinalPrice; + product = allowedProduct; + } + + if (optionFinalPrice < optionMinPrice) { + product = allowedProduct; + } + }, this); + + return product; + }, + + /** + * Calculate price difference for allowed product + * + * @param {*} allowedProduct - Product + * @returns {*} + * @private + */ + _calculatePriceDifference: function (allowedProduct) { + var displayPrices = $(this.options.priceHolderSelector).priceBox('option').prices, + newPrices = this.options.spConfig.optionPrices[allowedProduct]; + + _.each(displayPrices, function (price, code) { + + if (newPrices[code]) { + displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount; + } + }); + + return displayPrices; + }, + /** * Returns prices for configured products * diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 1aabab8b1d5d6..5e4c0a2c84f14 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 @@ -974,13 +974,29 @@ define([ * @private */ _getPrices: function (newPrices, displayPrices) { - var $widget = this; + var $widget = this, + optionPriceDiff = 0, + allowedProduct, optionPrices, basePrice, optionFinalPrice; if (_.isEmpty(newPrices)) { - newPrices = $widget.options.jsonConfig.prices; + allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()); + optionPrices = this.options.jsonConfig.optionPrices; + basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount); + + if (!_.isEmpty(allowedProduct)) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + } + + if (optionPriceDiff !== 0) { + newPrices = this.options.jsonConfig.optionPrices[allowedProduct]; + } else { + newPrices = $widget.options.jsonConfig.prices; + } } _.each(displayPrices, function (price, code) { + if (newPrices[code]) { displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount; } @@ -989,6 +1005,34 @@ define([ return displayPrices; }, + /** + * Get product with minimum price from selected options. + * + * @param {Array} allowedProducts + * @returns {String} + * @private + */ + _getAllowedProductWithMinPrice: function (allowedProducts) { + var optionPrices = this.options.jsonConfig.optionPrices, + product = {}, + optionFinalPrice, optionMinPrice; + + _.each(allowedProducts, function (allowedProduct) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + + if (_.isEmpty(product)) { + optionMinPrice = optionFinalPrice; + product = allowedProduct; + } + + if (optionFinalPrice < optionMinPrice) { + product = allowedProduct; + } + }, this); + + return product; + }, + /** * Gets all product media and change current to the needed one * From 89b5f5ea541699b25b1693ae19ec314d76604e0d Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Tue, 27 Nov 2018 12:39:08 +0200 Subject: [PATCH 50/51] Properties sorted alphabetically --- .../source/module/header/actions-group/_notifications.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less index ceeb8d8eeb2b3..40ebb6f3c4569 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_notifications.less @@ -97,14 +97,14 @@ display: inline-block; font-size: @notifications__font-size; font-weight: @font-weight__bold; + height: 18px; left: 50%; margin-left: .3em; margin-top: -1.1em; + min-width: 18px; padding: .3em .5em; position: absolute; top: 50%; - min-width: 18px; - height: 18px; } } From d7eafc2c9c4f9605146ad4ae9e7a51b77210e459 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi Date: Tue, 27 Nov 2018 17:07:44 +0200 Subject: [PATCH 51/51] MAGETWO-91070: Missing Swatch Images Break Catalog Pages --- app/code/Magento/Swatches/Helper/Media.php | 19 ++++++--- .../Swatches/Test/Unit/Helper/MediaTest.php | 42 +++++++++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Swatches/Helper/Media.php b/app/code/Magento/Swatches/Helper/Media.php index eb932f723c154..5019b9928ab1e 100644 --- a/app/code/Magento/Swatches/Helper/Media.php +++ b/app/code/Magento/Swatches/Helper/Media.php @@ -11,6 +11,7 @@ /** * Helper to move images from tmp to catalog directory + * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 @@ -19,7 +20,6 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper { /** * Swatch area inside media folder - * */ const SWATCH_MEDIA_PATH = 'attribute/swatch'; @@ -100,6 +100,8 @@ public function __construct( } /** + * Get swatch attribute image + * * @param string $swatchType * @param string $file * @return string @@ -110,13 +112,17 @@ public function getSwatchAttributeImage($swatchType, $file) $absoluteImagePath = $this->mediaDirectory ->getAbsolutePath($this->getSwatchMediaPath() . '/' . $generationPath); if (!file_exists($absoluteImagePath)) { - $this->generateSwatchVariations($file); + try { + $this->generateSwatchVariations($file); + } catch (\Exception $e) { + return ''; + } } return $this->getSwatchMediaUrl() . '/' . $generationPath; } /** - * move image from tmp to catalog dir + * Move image from tmp to catalog dir * * @param string $file * @return string path @@ -152,7 +158,7 @@ public function moveImageFromTmp($file) /** * Check whether file to move exists. Getting unique name * - * @param $file + * @param string $file * @return string */ protected function getUniqueFileName($file) @@ -176,6 +182,7 @@ protected function getUniqueFileName($file) * * @param string $imageUrl * @return $this + * @throws \Exception */ public function generateSwatchVariations($imageUrl) { @@ -234,7 +241,7 @@ protected function generateNamePath($imageConfig, $imageUrl, $swatchType) * Generate folder name WIDTHxHEIGHT based on config in view.xml * * @param string $swatchType - * @param null $imageConfig + * @param array|null $imageConfig * @return string */ public function getFolderNameSize($swatchType, $imageConfig = null) @@ -336,6 +343,8 @@ protected function prepareFile($file) } /** + * Get registered themes + * * @return \Magento\Theme\Model\ResourceModel\Theme\Collection */ private function getRegisteredThemes() diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php index aed9c1da41289..aebfbc2cbf0d4 100644 --- a/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Helper/MediaTest.php @@ -91,6 +91,8 @@ protected function setUp() /** * @dataProvider dataForFullPath + * @param string $swatchType + * @param string $expectedResult */ public function testGetSwatchAttributeImage($swatchType, $expectedResult) { @@ -98,7 +100,6 @@ public function testGetSwatchAttributeImage($swatchType, $expectedResult) ->expects($this->once()) ->method('getStore') ->willReturn($this->storeMock); - $this->storeMock ->expects($this->once()) ->method('getBaseUrl') @@ -107,11 +108,41 @@ public function testGetSwatchAttributeImage($swatchType, $expectedResult) $this->generateImageConfig(); - $this->testGenerateSwatchVariations(); + $image = $this->createPartialMock(\Magento\Framework\Image::class, [ + 'resize', + 'save', + 'keepTransparency', + 'constrainOnly', + 'keepFrame', + 'keepAspectRatio', + 'backgroundColor', + 'quality' + ]); + $this->imageFactoryMock->expects($this->atLeastOnce()) + ->method('create') + ->willReturn($image); + $image->expects($this->atLeastOnce()) + ->method('resize') + ->will($this->returnSelf()); + $image->expects($this->atLeastOnce()) + ->method('backgroundColor') + ->with([255, 255, 255]) + ->willReturnSelf(); $result = $this->mediaHelperObject->getSwatchAttributeImage($swatchType, '/f/i/file.png'); + $this->assertEquals($expectedResult, $result); + } + + public function testGetSwatchAttributeImageWithMissingFile() + { + $this->generateImageConfig(); + + $this->imageFactoryMock->expects($this->atLeastOnce()) + ->method('create') + ->willThrowException(new \Exception('')); - $this->assertEquals($result, $expectedResult); + $result = $this->mediaHelperObject->getSwatchAttributeImage('swatch_image', '/f/i/file.png'); + $this->assertEquals('', $result); } /** @@ -195,6 +226,9 @@ public function testGetSwatchMediaUrl() /** * @dataProvider dataForFolderName + * @param string $swatchType + * @param array|null $imageConfig + * @param string $expectedResult */ public function testGetFolderNameSize($swatchType, $imageConfig, $expectedResult) { @@ -293,6 +327,8 @@ public function testGetSwatchMediaPath() /** * @dataProvider getSwatchTypes + * @param string $swatchType + * @param string $expectedResult */ public function testGetSwatchCachePath($swatchType, $expectedResult) {