diff --git a/.gitignore b/.gitignore
index 68d38d9ca7817..8ec1104f25535 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,8 @@ atlassian*
/pub/media/import/*
!/pub/media/import/.htaccess
/pub/media/logo/*
+/pub/media/custom_options/*
+!/pub/media/custom_options/.htaccess
/pub/media/theme/*
/pub/media/theme_customization/*
!/pub/media/theme_customization/.htaccess
diff --git a/.htaccess b/.htaccess
index d22b5a1395cae..71a5cf708dbc5 100644
--- a/.htaccess
+++ b/.htaccess
@@ -27,6 +27,11 @@
#AddType x-mapp-php5 .php
#AddHandler x-mapp-php5 .php
+############################################
+## enable usage of methods arguments in backtrace
+
+ SetEnv MAGE_DEBUG_SHOW_ARGS 1
+
############################################
## default index file
@@ -364,6 +369,15 @@
Require all denied
+
= /* @escapeNotVerified */ __('Ordered') ?> | @@ -116,7 +125,7 @@
- canShowPriceInfo($_item)): ?>
+ canShowPriceInfo($_item) || $shipTogether): ?>
canEditQty()) : ?>
qty) {
return;
diff --git a/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php b/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php
index b904d3f62a748..211d625fbc754 100644
--- a/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php
+++ b/app/code/Magento/BundleGraphQl/Model/BundleProductTypeResolver.php
@@ -8,19 +8,22 @@
namespace Magento\BundleGraphQl\Model;
use Magento\Framework\GraphQl\Query\Resolver\TypeResolverInterface;
+use Magento\Bundle\Model\Product\Type as Type;
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
class BundleProductTypeResolver implements TypeResolverInterface
{
+ const BUNDLE_PRODUCT = 'BundleProduct';
+
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function resolveType(array $data) : string
{
- if (isset($data['type_id']) && $data['type_id'] == 'bundle') {
- return 'BundleProduct';
+ if (isset($data['type_id']) && $data['type_id'] == Type::TYPE_CODE) {
+ return self::BUNDLE_PRODUCT;
}
return '';
}
diff --git a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php
index 2152f842d4a29..b2aa0d000e9cf 100644
--- a/app/code/Magento/CacheInvalidate/Model/PurgeCache.php
+++ b/app/code/Magento/CacheInvalidate/Model/PurgeCache.php
@@ -118,6 +118,7 @@ private function splitTags($tagsPattern)
private function sendPurgeRequestToServers($socketAdapter, $servers, $formattedTagsChunk)
{
$headers = [self::HEADER_X_MAGENTO_TAGS_PATTERN => $formattedTagsChunk];
+ $unresponsiveServerError = [];
foreach ($servers as $server) {
$headers['Host'] = $server->getHost();
try {
@@ -131,10 +132,30 @@ private function sendPurgeRequestToServers($socketAdapter, $servers, $formattedT
$socketAdapter->read();
$socketAdapter->close();
} catch (\Exception $e) {
- $this->logger->critical($e->getMessage(), compact('server', 'formattedTagsChunk'));
+ $unresponsiveServerError[] = "Cache host: " . $server->getHost() . ":" . $server->getPort() .
+ "resulted in error message: " . $e->getMessage();
+ }
+ }
+
+ $errorCount = count($unresponsiveServerError);
+
+ if ($errorCount > 0) {
+ $loggerMessage = implode(" ", $unresponsiveServerError);
+
+ if ($errorCount == count($servers)) {
+ $this->logger->critical(
+ 'No cache server(s) could be purged ' . $loggerMessage,
+ compact('server', 'formattedTagsChunk')
+ );
return false;
}
+
+ $this->logger->warning(
+ 'Unresponsive cache server(s) hit' . $loggerMessage,
+ compact('server', 'formattedTagsChunk')
+ );
}
+
$this->logger->execute(compact('servers', 'formattedTagsChunk'));
return true;
}
diff --git a/app/code/Magento/Captcha/Observer/CheckUserLoginObserver.php b/app/code/Magento/Captcha/Observer/CheckUserLoginObserver.php
index bdc8dfa218972..dd4974c5d842c 100644
--- a/app/code/Magento/Captcha/Observer/CheckUserLoginObserver.php
+++ b/app/code/Magento/Captcha/Observer/CheckUserLoginObserver.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Captcha\Observer;
use Magento\Customer\Model\AuthenticationInterface;
@@ -11,7 +12,10 @@
use Magento\Customer\Api\CustomerRepositoryInterface;
/**
+ * Check captcha on user login page observer.
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class CheckUserLoginObserver implements ObserverInterface
{
@@ -140,7 +144,7 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$customer = $this->getCustomerRepository()->get($login);
$this->getAuthentication()->processAuthenticationFailure($customer->getId());
} catch (NoSuchEntityException $e) {
- //do nothing as customer existance is validated later in authenticate method
+ //do nothing as customer existence is validated later in authenticate method
}
$this->messageManager->addError(__('Incorrect CAPTCHA'));
$this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
diff --git a/app/code/Magento/Catalog/Api/ProductRenderListInterface.php b/app/code/Magento/Catalog/Api/ProductRenderListInterface.php
index f79efa4c814d7..954acd35a07db 100644
--- a/app/code/Magento/Catalog/Api/ProductRenderListInterface.php
+++ b/app/code/Magento/Catalog/Api/ProductRenderListInterface.php
@@ -4,18 +4,22 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Catalog\Api;
/**
- * Interface which provides product renders information for products
+ * Interface which provides product renders information for products.
+ *
* @api
* @since 101.1.0
*/
interface ProductRenderListInterface
{
/**
- * Collect and retrieve the list of product render info
- * This info contains raw prices and formated prices, product name, stock status, store_id, etc
+ * Collect and retrieve the list of product render info.
+ *
+ * This info contains raw prices and formatted prices, product name, stock status, store_id, etc.
+ *
* @see \Magento\Catalog\Api\Data\ProductRenderInfoDtoInterface
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/AbstractCategory.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/AbstractCategory.php
index 331679874629b..ffb648cdf438a 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/AbstractCategory.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/AbstractCategory.php
@@ -67,6 +67,8 @@ public function getCategory()
}
/**
+ * Get category id
+ *
* @return int|string|null
*/
public function getCategoryId()
@@ -78,6 +80,8 @@ public function getCategoryId()
}
/**
+ * Get category name
+ *
* @return string
*/
public function getCategoryName()
@@ -86,6 +90,8 @@ public function getCategoryName()
}
/**
+ * Get category path
+ *
* @return mixed
*/
public function getCategoryPath()
@@ -97,6 +103,8 @@ public function getCategoryPath()
}
/**
+ * Check store root category
+ *
* @return bool
*/
public function hasStoreRootCategory()
@@ -109,6 +117,8 @@ public function hasStoreRootCategory()
}
/**
+ * Get store from request
+ *
* @return Store
*/
public function getStore()
@@ -118,6 +128,8 @@ public function getStore()
}
/**
+ * Get root category for tree
+ *
* @param mixed|null $parentNodeCategory
* @param int $recursionLevel
* @return Node|array|null
@@ -149,10 +161,11 @@ public function getRoot($parentNodeCategory = null, $recursionLevel = 3)
$root = $tree->getNodeById($rootId);
- if ($root && $rootId != \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
+ if ($root) {
$root->setIsVisible(true);
- } elseif ($root && $root->getId() == \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
- $root->setName(__('Root'));
+ if ($root->getId() == \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
+ $root->setName(__('Root'));
+ }
}
$this->_coreRegistry->register('root', $root);
@@ -162,6 +175,8 @@ public function getRoot($parentNodeCategory = null, $recursionLevel = 3)
}
/**
+ * Get Default Store Id
+ *
* @return int
*/
protected function _getDefaultStoreId()
@@ -170,6 +185,8 @@ protected function _getDefaultStoreId()
}
/**
+ * Get category collection
+ *
* @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
*/
public function getCategoryCollection()
@@ -227,6 +244,8 @@ public function getRootByIds($ids)
}
/**
+ * Get category node for tree
+ *
* @param mixed $parentNodeCategory
* @param int $recursionLevel
* @return Node
@@ -249,6 +268,8 @@ public function getNode($parentNodeCategory, $recursionLevel = 2)
}
/**
+ * Get category save url
+ *
* @param array $args
* @return string
*/
@@ -260,6 +281,8 @@ public function getSaveUrl(array $args = [])
}
/**
+ * Get category edit url
+ *
* @return string
*/
public function getEditUrl()
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Fieldset/Element.php b/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Fieldset/Element.php
index ad6df27b89334..8f1d1dcf7eedf 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Fieldset/Element.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Fieldset/Element.php
@@ -4,13 +4,13 @@
* See COPYING.txt for license details.
*/
+namespace Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset;
+
/**
* Catalog fieldset element renderer
*
* @author Magento Core Team
@@ -132,7 +139,7 @@
diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml
index 65090fa3ac461..578281f44c4cf 100644
--- a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml
+++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml
@@ -190,6 +190,13 @@
+
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
index 2daca51a2f5da..fb128a891aea2 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
@@ -97,7 +97,7 @@
= $block->escapeHtml(__($_data['label'])) ?> |
- = /* @escapeNotVerified */ $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?> |
+ = $block->escapeHtml($_data['label']) ?> |
+ = /* @escapeNotVerified */ $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?> |
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js
index ce1527b3d72d6..1920bc4d7ac41 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js
@@ -14,7 +14,8 @@ define([
$.widget('mage.updateShoppingCart', {
options: {
validationURL: '',
- eventName: 'updateCartItemQty'
+ eventName: 'updateCartItemQty',
+ updateCartActionContainer: ''
},
/** @inheritdoc */
@@ -31,7 +32,9 @@ define([
* @return {Boolean}
*/
onSubmit: function (event) {
- if (!this.options.validationURL) {
+ var action = this.element.find(this.options.updateCartActionContainer).val();
+
+ if (!this.options.validationURL || action === 'empty_cart') {
return true;
}
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js
new file mode 100644
index 0000000000000..4b30ad8075274
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js
@@ -0,0 +1,16 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+ 'Magento_Customer/js/customer-data'
+], function (customerData) {
+ 'use strict';
+
+ var cartData = customerData.get('cart');
+
+ if (cartData().items && cartData().items.length !== 0) {
+ customerData.reload(['cart'], false);
+ }
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
index 2510d1aced3d3..3486a92736617 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
@@ -7,7 +7,8 @@
*/
define([
'ko',
- 'underscore'
+ 'underscore',
+ 'domReady!'
], function (ko, _) {
'use strict';
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js
index 3ea49cd981d90..eecfa65b189d1 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js
@@ -14,7 +14,11 @@ define([
_create: function () {
var items, i, reload;
- $(this.options.emptyCartButton).on('click', $.proxy(function () {
+ $(this.options.emptyCartButton).on('click', $.proxy(function (event) {
+ if (event.detail === 0) {
+ return;
+ }
+
$(this.options.emptyCartButton).attr('name', 'update_cart_action_temp');
$(this.options.updateCartActionContainer)
.attr('name', 'update_cart_action').attr('value', 'empty_cart');
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 6f9a1a46826da..d68b0682eb511 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
@@ -202,6 +202,13 @@ function (
}
},
+ /**
+ * Manage cancel button visibility
+ */
+ canUseCancelBillingAddress: ko.computed(function () {
+ return quote.billingAddress() || lastSelectedBillingAddress;
+ }),
+
/**
* Restore billing address
*/
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
index a2f8c8c56ff33..5e29fa209a641 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
@@ -81,6 +81,7 @@ define([
maxItemsToDisplay: window.checkout.maxItemsToDisplay,
cart: {},
+ // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
/**
* @override
*/
@@ -101,12 +102,16 @@ define([
self.isLoading(true);
});
- if (cartData()['website_id'] !== window.checkout.websiteId) {
+ if (cartData().website_id !== window.checkout.websiteId ||
+ cartData().store_id !== window.checkout.storeId
+ ) {
customerData.reload(['cart'], false);
}
return this._super();
},
+ //jscs:enable requireCamelCaseOrUpperCaseIdentifiers
+
isLoading: ko.observable(false),
initSidebar: initSidebar,
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
index 5f735fbb4daa9..63edb5057b933 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
@@ -22,7 +22,7 @@
-
= /* @escapeNotVerified */ $html ?>
diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml
index a2b91a5eeb99f..40f86c7e68d6c 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml
@@ -14,7 +14,7 @@
-getProduct()->getFinalPrice()):?>
+getProduct()->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)->getAmount()):?>
= $block->getChildHtml('meta.currency') ?>
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js
index c0637cb672dc6..755e777a01f77 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js
@@ -13,7 +13,8 @@ define([
$.widget('mage.productValidate', {
options: {
bindSubmit: false,
- radioCheckboxClosest: '.nested'
+ radioCheckboxClosest: '.nested',
+ addToCartButtonSelector: '.action.tocart'
},
/**
@@ -41,6 +42,7 @@ define([
return false;
}
});
+ $(this.options.addToCartButtonSelector).attr('disabled', false);
}
});
diff --git a/app/code/Magento/CatalogAnalytics/composer.json b/app/code/Magento/CatalogAnalytics/composer.json
index 5c97261d483d8..805be8a17765f 100644
--- a/app/code/Magento/CatalogAnalytics/composer.json
+++ b/app/code/Magento/CatalogAnalytics/composer.json
@@ -4,7 +4,8 @@
"require": {
"php": "~7.1.3||~7.2.0",
"magento/framework": "*",
- "magento/module-catalog": "*"
+ "magento/module-catalog": "*",
+ "magento/module-analytics": "*"
},
"type": "magento2-module",
"license": [
diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php b/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
index dbe58a9c77cd0..b5d02511da4e7 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
@@ -26,7 +26,7 @@ public function calculate(FieldNode $fieldNode) : int
$depth = count($selections) ? 1 : 0;
$childrenDepth = [0];
foreach ($selections as $node) {
- if ($node->kind === 'InlineFragment') {
+ if ($node->kind === 'InlineFragment' || null !== $node->alias) {
continue;
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php
index 4e3a8403f3132..1783a5cd9a7e5 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryTree.php
@@ -11,6 +11,7 @@
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
+use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
/**
@@ -72,11 +73,12 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
$rootCategoryId = $this->getCategoryId($args);
$categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId);
- if (!empty($categoriesTree)) {
- $result = $this->extractDataFromCategoryTree->execute($categoriesTree);
- return current($result);
- } else {
- return null;
+
+ if (empty($categoriesTree) || ($categoriesTree->count() == 0)) {
+ throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist'));
}
+
+ $result = $this->extractDataFromCategoryTree->execute($categoriesTree);
+ return current($result);
}
}
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 3c19ce599a9b3..23a8c2d15c09e 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php
@@ -9,6 +9,7 @@
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\ImageFactory;
+use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Image\Placeholder as PlaceholderProvider;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
@@ -23,14 +24,21 @@ class Url implements ResolverInterface
* @var ImageFactory
*/
private $productImageFactory;
+ /**
+ * @var PlaceholderProvider
+ */
+ private $placeholderProvider;
/**
* @param ImageFactory $productImageFactory
+ * @param PlaceholderProvider $placeholderProvider
*/
public function __construct(
- ImageFactory $productImageFactory
+ ImageFactory $productImageFactory,
+ PlaceholderProvider $placeholderProvider
) {
$this->productImageFactory = $productImageFactory;
+ $this->placeholderProvider = $placeholderProvider;
}
/**
@@ -55,23 +63,27 @@ public function resolve(
$product = $value['model'];
$imagePath = $product->getData($value['image_type']);
- $imageUrl = $this->getImageUrl($value['image_type'], $imagePath);
- return $imageUrl;
+ return $this->getImageUrl($value['image_type'], $imagePath);
}
/**
- * Get image url
+ * Get image URL
*
* @param string $imageType
- * @param string|null $imagePath Null if image is not set
+ * @param string|null $imagePath
* @return string
+ * @throws \Exception
*/
private function getImageUrl(string $imageType, ?string $imagePath): string
{
$image = $this->productImageFactory->create();
$image->setDestinationSubdir($imageType)
->setBaseFile($imagePath);
- $imageUrl = $image->getUrl();
- return $imageUrl;
+
+ if ($image->isBaseFilePlaceholder()) {
+ return $this->placeholderProvider->getPlaceholder($imageType);
+ }
+
+ return $image->getUrl();
}
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php
index e910a5c8be4cd..24c5e664831e4 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php
@@ -7,7 +7,6 @@
namespace Magento\CatalogGraphQl\Model\Resolver;
-use Magento\Framework\Exception\InputException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search;
@@ -17,7 +16,6 @@
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\SearchFilter;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Catalog\Model\Layer\Resolver;
-use Magento\Framework\Api\Search\SearchCriteriaInterface;
/**
* Products field resolver, used for GraphQL request processing.
@@ -82,10 +80,10 @@ public function resolve(
} elseif (isset($args['search'])) {
$layerType = Resolver::CATALOG_LAYER_SEARCH;
$this->searchFilter->add($args['search'], $searchCriteria);
- $searchResult = $this->getSearchResult($this->searchQuery, $searchCriteria, $info);
+ $searchResult = $this->searchQuery->getResult($searchCriteria, $info);
} else {
$layerType = Resolver::CATALOG_LAYER_CATEGORY;
- $searchResult = $this->getSearchResult($this->filterQuery, $searchCriteria, $info);
+ $searchResult = $this->filterQuery->getResult($searchCriteria, $info);
}
//possible division by 0
if ($searchCriteria->getPageSize()) {
@@ -117,25 +115,4 @@ public function resolve(
return $data;
}
-
- /**
- * Get search result.
- *
- * @param Filter|Search $query
- * @param SearchCriteriaInterface $searchCriteria
- * @param ResolveInfo $info
- *
- * @return \Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult
- * @throws GraphQlInputException
- */
- private function getSearchResult($query, SearchCriteriaInterface $searchCriteria, ResolveInfo $info)
- {
- try {
- $searchResult = $query->getResult($searchCriteria, $info);
- } catch (InputException $e) {
- throw new GraphQlInputException(__($e->getMessage()));
- }
-
- return $searchResult;
- }
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
index f2634574a2d15..fc5a563c82b4e 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
@@ -101,11 +101,21 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId): \Iterato
$collection->addFieldToFilter('level', ['gt' => $level]);
$collection->addFieldToFilter('level', ['lteq' => $level + $depth - self::DEPTH_OFFSET]);
+ $collection->addAttributeToFilter('is_active', 1, "left");
$collection->setOrder('level');
+ $collection->setOrder(
+ 'position',
+ $collection::SORT_ORDER_DESC
+ );
$collection->getSelect()->orWhere(
- $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField() . ' = ?',
+ $collection->getSelect()
+ ->getConnection()
+ ->quoteIdentifier(
+ 'e.' . $this->metadata->getMetadata(CategoryInterface::class)->getIdentifierField()
+ ) . ' = ?',
$rootCategoryId
);
+
return $collection->getIterator();
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php
index ac8d5709c85b3..3525ccbb6a2d1 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ExtractDataFromCategoryTree.php
@@ -20,6 +20,16 @@ class ExtractDataFromCategoryTree
*/
private $categoryHydrator;
+ /**
+ * @var CategoryInterface
+ */
+ private $iteratingCategory;
+
+ /**
+ * @var int
+ */
+ private $startCategoryFetchLevel = 1;
+
/**
* @param Hydrator $categoryHydrator
*/
@@ -42,14 +52,60 @@ public function execute(\Iterator $iterator): array
/** @var CategoryInterface $category */
$category = $iterator->current();
$iterator->next();
- $nextCategory = $iterator->current();
- $tree[$category->getId()] = $this->categoryHydrator->hydrateCategory($category);
- $tree[$category->getId()]['model'] = $category;
- if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) {
- $tree[$category->getId()]['children'] = $this->execute($iterator);
+ $pathElements = explode("/", $category->getPath());
+ if (empty($tree)) {
+ $this->startCategoryFetchLevel = count($pathElements) - 1;
+ }
+ $this->iteratingCategory = $category;
+ $currentLevelTree = $this->explodePathToArray($pathElements, $this->startCategoryFetchLevel);
+ if (empty($tree)) {
+ $tree = $currentLevelTree;
+ }
+ $tree = $this->mergeCategoriesTrees($currentLevelTree, $tree);
+ }
+ return $tree;
+ }
+
+ /**
+ * Merge together complex categories trees
+ *
+ * @param array $tree1
+ * @param array $tree2
+ * @return array
+ */
+ private function mergeCategoriesTrees(array &$tree1, array &$tree2): array
+ {
+ $mergedTree = $tree1;
+ foreach ($tree2 as $currentKey => &$value) {
+ if (is_array($value) && isset($mergedTree[$currentKey]) && is_array($mergedTree[$currentKey])) {
+ $mergedTree[$currentKey] = $this->mergeCategoriesTrees($mergedTree[$currentKey], $value);
+ } else {
+ $mergedTree[$currentKey] = $value;
}
}
+ return $mergedTree;
+ }
+ /**
+ * Recursive method to generate tree for one category path
+ *
+ * @param array $pathElements
+ * @param int $index
+ * @return array
+ */
+ private function explodePathToArray(array $pathElements, int $index): array
+ {
+ $tree = [];
+ $tree[$pathElements[$index]]['id'] = $pathElements[$index];
+ if ($index === count($pathElements) - 1) {
+ $tree[$pathElements[$index]] = $this->categoryHydrator->hydrateCategory($this->iteratingCategory);
+ $tree[$pathElements[$index]]['model'] = $this->iteratingCategory;
+ }
+ $currentIndex = $index;
+ $index++;
+ if (isset($pathElements[$index])) {
+ $tree[$pathElements[$currentIndex]]['children'] = $this->explodePathToArray($pathElements, $index);
+ }
return $tree;
}
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php
new file mode 100644
index 0000000000000..f5cf2a9ef82ff
--- /dev/null
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php
@@ -0,0 +1,59 @@
+placeholderFactory = $placeholderFactory;
+ $this->assetRepository = $assetRepository;
+ }
+
+ /**
+ * Get placeholder
+ *
+ * @param string $imageType
+ * @return string
+ */
+ public function getPlaceholder(string $imageType): string
+ {
+ $imageAsset = $this->placeholderFactory->create(['type' => $imageType]);
+
+ // check if placeholder defined in config
+ if ($imageAsset->getFilePath()) {
+ return $imageAsset->getUrl();
+ }
+
+ return $this->assetRepository->getUrl(
+ "Magento_Catalog::images/product/placeholder/{$imageType}.jpg"
+ );
+ }
+}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php
new file mode 100644
index 0000000000000..dc48c5ef69346
--- /dev/null
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php
@@ -0,0 +1,71 @@
+scopeConfig = $scopeConfig;
+ $this->storeManager = $storeManager;
+ $this->themeProvider = $themeProvider;
+ }
+
+ /**
+ * Get theme model
+ *
+ * @return array
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
+ */
+ public function getThemeData(): array
+ {
+ $themeId = $this->scopeConfig->getValue(
+ \Magento\Framework\View\DesignInterface::XML_PATH_THEME_ID,
+ \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+ $this->storeManager->getStore()->getId()
+ );
+
+ /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+ $theme = $this->themeProvider->getThemeById($themeId);
+
+ $data = $theme->getData();
+ $data['themeModel'] = $theme;
+
+ return $data;
+ }
+}
diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
index 7e18ac34f0fcc..b5622e948b7cd 100644
--- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
+++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
@@ -38,11 +38,15 @@
@@ -49,6 +51,6 @@
getResultCount()): ?>
- = $block->getProductListHtml() ?>
+ = /* @escapeNotVerified */ $productList ?>
getSearchCriterias(); ?>
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Products/AdaptUrlRewritesToVisibilityAttribute.php b/app/code/Magento/CatalogUrlRewrite/Model/Products/AdaptUrlRewritesToVisibilityAttribute.php
new file mode 100644
index 0000000000000..f5851cf1e11b1
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Products/AdaptUrlRewritesToVisibilityAttribute.php
@@ -0,0 +1,127 @@
+productCollectionFactory = $collectionFactory;
+ $this->urlRewriteGenerator = $urlRewriteGenerator;
+ $this->urlPersist = $urlPersist;
+ $this->urlPathGenerator = $urlPathGenerator;
+ }
+
+ /**
+ * Process Url Rewrites according to the products visibility attribute
+ *
+ * @param array $productIds
+ * @param int $visibility
+ * @throws UrlAlreadyExistsException
+ */
+ public function execute(array $productIds, int $visibility): void
+ {
+ $products = $this->getProductsByIds($productIds);
+
+ /** @var Product $product */
+ foreach ($products as $product) {
+ if ($visibility == Visibility::VISIBILITY_NOT_VISIBLE) {
+ $this->urlPersist->deleteByData(
+ [
+ UrlRewrite::ENTITY_ID => $product->getId(),
+ UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+ ]
+ );
+ } elseif ($visibility !== Visibility::VISIBILITY_NOT_VISIBLE) {
+ $product->setVisibility($visibility);
+ $productUrlPath = $this->urlPathGenerator->getUrlPath($product);
+ $productUrlRewrite = $this->urlRewriteGenerator->generate($product);
+ $product->unsUrlPath();
+ $product->setUrlPath($productUrlPath);
+
+ try {
+ $this->urlPersist->replace($productUrlRewrite);
+ } catch (UrlAlreadyExistsException $e) {
+ throw new UrlAlreadyExistsException(
+ __(
+ 'Can not change the visibility of the product with SKU equals "%1". '
+ . 'URL key "%2" for specified store already exists.',
+ $product->getSku(),
+ $product->getUrlKey()
+ ),
+ $e,
+ $e->getCode(),
+ $e->getUrls()
+ );
+ }
+ }
+ }
+ }
+
+ /**
+ * Get Product Models by Id's
+ *
+ * @param array $productIds
+ * @return array
+ */
+ private function getProductsByIds(array $productIds): array
+ {
+ $productCollection = $this->productCollectionFactory->create();
+ $productCollection->addAttributeToSelect(ProductInterface::VISIBILITY);
+ $productCollection->addAttributeToSelect('url_key');
+ $productCollection->addFieldToFilter(
+ 'entity_id',
+ ['in' => array_unique($productIds)]
+ );
+
+ return $productCollection->getItems();
+ }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php
index 9aaa384776855..7b60c85049767 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php
@@ -263,6 +263,7 @@ protected function _populateForUrlGeneration($rowData)
if ($this->isGlobalScope($product->getStoreId())) {
$this->populateGlobalProduct($product);
} else {
+ $this->storesCache[$product->getStoreId()] = true;
$this->addProductToImport($product, $product->getStoreId());
}
return $this;
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProcessUrlRewriteOnChangeProductVisibilityObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProcessUrlRewriteOnChangeProductVisibilityObserver.php
new file mode 100644
index 0000000000000..2337bb3646bd7
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProcessUrlRewriteOnChangeProductVisibilityObserver.php
@@ -0,0 +1,54 @@
+adaptUrlRewritesToVisibility = $adaptUrlRewritesToVisibility;
+ }
+
+ /**
+ * Generate urls for UrlRewrites and save it in storage
+ *
+ * @param Observer $observer
+ * @return void
+ * @throws UrlAlreadyExistsException
+ */
+ public function execute(Observer $observer)
+ {
+ $event = $observer->getEvent();
+ $attrData = $event->getAttributesData();
+ $productIds = $event->getProductIds();
+ $visibility = $attrData[ProductInterface::VISIBILITY] ?? 0;
+
+ if (!$visibility || !$productIds) {
+ return;
+ }
+
+ $this->adaptUrlRewritesToVisibility->execute($productIds, (int)$visibility);
+ }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php
index fc2056e83ec70..44b47faf3d4b8 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php
@@ -13,7 +13,12 @@
use Magento\Store\Model\Store;
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
+use Magento\Store\Api\StoreWebsiteRelationInterface;
+use Magento\Framework\App\ObjectManager;
+/**
+ * Observer to assign the products to website
+ */
class ProductToWebsiteChangeObserver implements ObserverInterface
{
/**
@@ -36,22 +41,31 @@ class ProductToWebsiteChangeObserver implements ObserverInterface
*/
protected $request;
+ /**
+ * @var StoreWebsiteRelationInterface
+ */
+ private $storeWebsiteRelation;
+
/**
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
* @param ProductRepositoryInterface $productRepository
* @param RequestInterface $request
+ * @param StoreWebsiteRelationInterface $storeWebsiteRelation
*/
public function __construct(
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
UrlPersistInterface $urlPersist,
ProductRepositoryInterface $productRepository,
- RequestInterface $request
+ RequestInterface $request,
+ StoreWebsiteRelationInterface $storeWebsiteRelation = null
) {
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
$this->urlPersist = $urlPersist;
$this->productRepository = $productRepository;
$this->request = $request;
+ $this->storeWebsiteRelation = $storeWebsiteRelation ?:
+ ObjectManager::getInstance()->get(StoreWebsiteRelationInterface::class);
}
/**
@@ -69,12 +83,21 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$this->request->getParam('store_id', Store::DEFAULT_STORE_ID)
);
- $this->urlPersist->deleteByData([
- UrlRewrite::ENTITY_ID => $product->getId(),
- UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
- ]);
- if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) {
- $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
+ if (!empty($this->productUrlRewriteGenerator->generate($product))) {
+ if ($this->request->getParam('remove_website_ids')) {
+ foreach ($this->request->getParam('remove_website_ids') as $webId) {
+ foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeId) {
+ $this->urlPersist->deleteByData([
+ UrlRewrite::ENTITY_ID => $product->getId(),
+ UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
+ UrlRewrite::STORE_ID => $storeId
+ ]);
+ }
+ }
+ }
+ if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) {
+ $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
+ }
}
}
}
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml
new file mode 100644
index 0000000000000..30a4290d882fb
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml
@@ -0,0 +1,82 @@
+
+
+
+
-
+
-
+
- |
---|
diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html b/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html
index df1677f56a500..bb181126724da 100644
--- a/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html
+++ b/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html
@@ -51,7 +51,7 @@ {{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship |
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml b/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml
new file mode 100644
index 0000000000000..91414663951d3
--- /dev/null
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml
@@ -0,0 +1,13 @@
+
+
+ | diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html index d0b12549bd66d..e5d73a62b329e 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html @@ -58,7 +58,7 @@ |
+
+
- |
diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html
index 68f1886986c5b..385110f8f037e 100644
--- a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html
+++ b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html
@@ -49,7 +49,7 @@ {{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship |
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 1e4a92fa0701f..1be46c8239ee2 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
@@ -343,16 +343,22 @@
}
.product-item-name {
- display: inline-block;
+ float: left;
+ width: calc(100% - 20px);
+ }
+ .product-item::after {
+ clear: both;
+ content: '';
+ display: table;
}
-
.product-item {
.label {
&:extend(.abs-visually-hidden all);
}
.field.item {
- display: inline-block;
+ float: left;
+ width: 20px;
}
}
}
@@ -392,6 +398,17 @@
&.orders-recent {
&:extend(.abs-account-table-margin-mobile all);
&:extend(.abs-no-border-top all);
+ .table-order-items {
+ &.table {
+ tbody {
+ > tr {
+ > td.col {
+ padding-left: 0;
+ }
+ }
+ }
+ }
+ }
}
}
@@ -555,13 +572,13 @@
margin: 0 @tab-control__margin-right 0 0;
a {
- padding: @tab-control__padding-top @tab-control__padding-right;
+ padding: @tab-control__padding-top @indent__base;
}
strong {
border-bottom: 0;
margin-bottom: -1px;
- padding: @tab-control__padding-top @tab-control__padding-right @tab-control__padding-bottom + 1 @tab-control__padding-left;
+ padding: @tab-control__padding-top @indent__base @tab-control__padding-bottom + 1 @indent__base;
}
}
}
@@ -687,3 +704,19 @@
}
}
}
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) {
+ .order-links {
+ .item {
+ margin: 0 @tab-control__margin-right 0 0;
+
+ a {
+ padding: @tab-control__padding-top @tab-control__padding-right;
+ }
+
+ strong {
+ padding: @tab-control__padding-top @tab-control__padding-right @tab-control__padding-bottom + 1 @tab-control__padding-left;
+ }
+ }
+ }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less
index baf5468b18485..3435736a54a6a 100644
--- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less
@@ -10,6 +10,14 @@
& when (@media-common = true) {
.form.send.friend {
&:extend(.abs-add-fields all);
+
+ .fieldset {
+ .field {
+ .control {
+ width: 100%;
+ }
+ }
+ }
}
.product-social-links .action.mailto.friend {
@@ -44,3 +52,18 @@
}
}
}
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
+ .form.send.friend {
+ .fieldset {
+ padding-bottom: @indent__xs;
+ }
+
+ .action {
+ &.remove {
+ margin-left: 0;
+ right: 0;
+ top: 100%;
+ }
+ }
+ }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
index 32bb22a632177..1f1ea93d0b54a 100644
--- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
@@ -77,6 +77,14 @@
.lib-vendor-prefix-flex-grow(1);
}
+ .page-main {
+ > .page-title-wrapper {
+ .page-title {
+ word-break: break-all;
+ }
+ }
+ }
+
//
// Header
// ---------------------------------------------
@@ -445,7 +453,7 @@
}
}
-.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
.logo {
margin-bottom: 13px;
margin-top: 4px;
@@ -458,7 +466,7 @@
.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
.cms-page-view .page-main {
- padding-top: 41px;
+ padding-top: 0;
position: relative;
}
}
diff --git a/app/design/frontend/Magento/luma/Magento_Wishlist/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Wishlist/web/css/source/_module.less
index 3658902feb3a6..85e8aeb0b515c 100644
--- a/app/design/frontend/Magento/luma/Magento_Wishlist/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Wishlist/web/css/source/_module.less
@@ -182,6 +182,30 @@
}
}
}
+ .products-grid.wishlist {
+ .product-item-actions {
+ .action {
+ &.edit,
+ &.delete {
+ .lib-icon-font(
+ @icon-edit,
+ @_icon-font-size: 18px,
+ @_icon-font-line-height: 20px,
+ @_icon-font-text-hide: true,
+ @_icon-font-color: @minicart-icons-color,
+ @_icon-font-color-hover: @primary__color,
+ @_icon-font-color-active: @minicart-icons-color
+ );
+ }
+
+ &.delete {
+ .lib-icon-font-symbol(
+ @_icon-font-content: @icon-trash
+ );
+ }
+ }
+ }
+ }
}
//
@@ -229,15 +253,7 @@
&:last-child {
margin-right: 0;
}
-
- &.edit {
- float: left;
- }
-
- &.delete {
- float: right;
- }
-
+
&.edit,
&.delete {
margin-top: 7px;
@@ -379,9 +395,7 @@
width: auto;
}
}
-}
-.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.wishlist-index-index {
.product-item-inner {
@_shadow: 3px 4px 4px 0 rgba(0, 0, 0, .3);
diff --git a/app/design/frontend/Magento/luma/etc/view.xml b/app/design/frontend/Magento/luma/etc/view.xml
index 55d43272caad9..7aa2e51481bd9 100644
--- a/app/design/frontend/Magento/luma/etc/view.xml
+++ b/app/design/frontend/Magento/luma/etc/view.xml
@@ -256,7 +256,7 @@
166
370
- 0
+ 1
|