Skip to content

Commit cfed47e

Browse files
authored
Merge pull request #8892 from magento-gl/community_prs_april
[Bluetooth] Community Pull Requests delivery April
2 parents c893121 + a9532e1 commit cfed47e

File tree

29 files changed

+958
-79
lines changed

29 files changed

+958
-79
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trim_trailing_whitespace = false
1414
[*.{yml,yaml,json}]
1515
indent_size = 2
1616

17-
[{composer, auth}.json]
17+
[{composer,auth}.json]
1818
indent_size = 4
1919

2020
[db_schema_whitelist.json]

app/code/Magento/Catalog/Block/Product/Widget/NewWidget.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Catalog\Block\Product\Widget;
77

8+
use Magento\Framework\App\Http\Context as HttpContext;
9+
810
/**
911
* New products widget
1012
*/
@@ -13,29 +15,29 @@ class NewWidget extends \Magento\Catalog\Block\Product\NewProduct implements \Ma
1315
/**
1416
* Display products type - all products
1517
*/
16-
const DISPLAY_TYPE_ALL_PRODUCTS = 'all_products';
18+
public const DISPLAY_TYPE_ALL_PRODUCTS = 'all_products';
1719

1820
/**
1921
* Display products type - new products
2022
*/
21-
const DISPLAY_TYPE_NEW_PRODUCTS = 'new_products';
23+
public const DISPLAY_TYPE_NEW_PRODUCTS = 'new_products';
2224

2325
/**
2426
* Default value whether show pager or not
2527
*/
26-
const DEFAULT_SHOW_PAGER = false;
28+
public const DEFAULT_SHOW_PAGER = false;
2729

2830
/**
2931
* Default value for products per page
3032
*/
31-
const DEFAULT_PRODUCTS_PER_PAGE = 5;
33+
public const DEFAULT_PRODUCTS_PER_PAGE = 5;
3234

3335
/**
3436
* Name of request parameter for page number value
3537
*
3638
* @deprecated
3739
*/
38-
const PAGE_VAR_NAME = 'np';
40+
public const PAGE_VAR_NAME = 'np';
3941

4042
/**
4143
* Instance of pager block
@@ -134,13 +136,15 @@ public function getCurrentPage()
134136
*/
135137
public function getCacheKeyInfo()
136138
{
139+
$store = $this->_storeManager->getStore();
137140
return array_merge(
138141
parent::getCacheKeyInfo(),
139142
[
140143
$this->getDisplayType(),
141144
$this->getProductsPerPage(),
142145
(int) $this->getRequest()->getParam($this->getData('page_var_name'), 1),
143-
$this->serializer->serialize($this->getRequest()->getParams())
146+
$this->serializer->serialize($this->getRequest()->getParams()),
147+
$this->httpContext->getValue(HttpContext::CONTEXT_CURRENCY) ?: $store->getDefaultCurrency()->getCode()
144148
]
145149
);
146150
}
@@ -268,7 +272,7 @@ public function getProductPriceHtml(
268272
? $arguments['display_minimal_price']
269273
: true;
270274

271-
/** @var \Magento\Framework\Pricing\Render $priceRender */
275+
/** @var \Magento\Framework\Pricing\Render $priceRender */
272276
$priceRender = $this->getLayout()->getBlock('product.price.render.default');
273277

274278
$price = '';

app/code/Magento/Catalog/Model/ProductRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal
307307
*/
308308
public function getById($productId, $editMode = false, $storeId = null, $forceReload = false)
309309
{
310-
$cacheKey = $this->getCacheKey([$editMode, $storeId]);
310+
$cacheKey = $this->getCacheKey([$editMode, $storeId === null ? $storeId : (int) $storeId]);
311311
if (!isset($this->instancesById[$productId][$cacheKey]) || $forceReload) {
312312
$product = $this->productFactory->create();
313313
if ($editMode) {

app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -969,24 +969,13 @@ public function cacheKeyDataProvider(): array
969969
[
970970
'identifier' => 25,
971971
'editMode' => true,
972-
'storeId' => $anyObject
972+
'storeId' => '1'
973973
],
974974
[
975975
'identifier' => 'test-sku',
976976
'editMode' => true,
977-
'storeId' => $anyObject
977+
'storeId' => 1
978978
],
979-
[
980-
'identifier' => 25,
981-
'editMode' => false,
982-
'storeId' => $anyObject
983-
],
984-
[
985-
986-
'identifier' => 'test-sku',
987-
'editMode' => false,
988-
'storeId' => $anyObject
989-
]
990979
];
991980
}
992981

app/code/Magento/Catalog/view/base/web/template/product/price/regular_price.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* See COPYING.txt for license details.
55
*/
66
-->
7-
<if args="isSalable($row())">
87
<if args="getRegularPrice($row())">
98
<span css="'old-price': hasSpecialPrice($row()), 'regular-price': !hasSpecialPrice($row())">
109
<span class="price-container"
@@ -28,4 +27,3 @@
2827
</span>
2928
</span>
3029
</if>
31-
</if>

app/code/Magento/Catalog/view/base/web/template/product/price/special_price.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* See COPYING.txt for license details.
55
*/
66
-->
7-
<if args="isSalable($row()) && hasSpecialPrice($row())">
7+
<if args="hasSpecialPrice($row())">
88
<span class="special-price">
99
<span class="price-container"
1010
css="getAdjustmentCssClasses($row())">
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="AdminAddRecentlyViewedProductWidgetToSeeProductPriceTest">
12+
<annotations>
13+
<features value="Cms"/>
14+
<stories value="Admin Add Recently Viewed Product Widget To SeeProduct PriceTest"/>
15+
<group value="Cms"/>
16+
<title value="Admin Add Recently Viewed Product Widget To SeeProduct PriceTest in frontend"/>
17+
<description value="Admin Add Recently Viewed Product Widget To SeeProduct PriceTest in frontend"/>
18+
<severity value="BLOCKER"/>
19+
<testCaseId value="git-38159"/>
20+
</annotations>
21+
<before>
22+
<createData entity="_defaultCategory" stepKey="createPreReqCategory"/>
23+
<createData entity="SimpleOutOfStockProduct" stepKey="createPreReqProduct">
24+
<requiredEntity createDataKey="createPreReqCategory"/>
25+
</createData>
26+
<actionGroup ref="AdminLoginActionGroup" stepKey="login"/>
27+
<actionGroup ref="EnabledWYSIWYGActionGroup" stepKey="enableWYSIWYG"/>
28+
<actionGroup ref="CliEnableTinyMCEActionGroup" stepKey="enableTinyMCE" />
29+
<!-- Configure Magento to show out of stock products and to allow backorders -->
30+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/>
31+
</before>
32+
<!--Main test-->
33+
<actionGroup ref="AdminOpenCreateNewCMSPageActionGroup" stepKey="navigateToPage"/>
34+
<fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/>
35+
<click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" />
36+
<waitForElementVisible selector="{{TinyMCESection.TinyMCE}}" stepKey="waitForTinyMCE"/>
37+
<executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/>
38+
<seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" />
39+
<click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" />
40+
<waitForPageLoad stepKey="waitForPageLoad" />
41+
<see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" />
42+
<!--see Insert Widget button disabled-->
43+
<see selector="{{WidgetSection.InsertWidgetBtnDisabled}}" userInput="Insert Widget" stepKey="seeInsertWidgetDisabled" />
44+
<!--see Cancel button enabled-->
45+
<see selector="{{WidgetSection.CancelBtnEnabled}}" userInput="Cancel" stepKey="seeCancelBtnEnabled" />
46+
<!--Select "Widget Type"-->
47+
<selectOption selector="{{WidgetSection.WidgetType}}" userInput="Recently Viewed Products" stepKey="selectRecentlyViewedProducts" />
48+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear" />
49+
<!--see Insert Widget button enabled-->
50+
<see selector="{{WidgetSection.InsertWidgetBtnEnabled}}" userInput="Insert Widget" stepKey="seeInsertWidgetEnabled" />
51+
<fillField selector="{{WidgetSection.PageSize}}" userInput="5" stepKey="fillNoOfProductDisplay" />
52+
<selectOption selector="{{WidgetSection.ProductAttribute}}" parameterArray="['Name','Image','Price','Learn More Link']" stepKey="selectProductAttributes" />
53+
<selectOption selector="{{WidgetSection.ButtonToShow}}" parameterArray="['Add to Cart', 'Add To Compare', 'Add To Wishlist']" stepKey="selectBtnToShow" />
54+
<selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="Viewed Products Grid Template" stepKey="selectTemplate" />
55+
<actionGroup ref="AdminClickInsertWidgetActionGroup" stepKey="clickInsertWidget"/>
56+
<scrollTo selector="{{CmsNewPagePageSeoSection.header}}" stepKey="scrollToSearchEngineTab" />
57+
<click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/>
58+
<fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{_defaultCmsPage.identifier}}" stepKey="fillFieldUrlKey"/>
59+
<actionGroup ref="SaveCmsPageActionGroup" stepKey="clickSavePage"/>
60+
<amOnPage url="$$createPreReqProduct.custom_attributes[url_key]$$.html" stepKey="amOnProductPage" />
61+
<waitForPageLoad stepKey="waitForPage" />
62+
<amOnPage url="{{_defaultCmsPage.identifier}}" stepKey="amOnPageTestPage"/>
63+
<waitForPageLoad stepKey="wait5" />
64+
<!--see widget on Storefront-->
65+
<see userInput="Hello CMS Page!" stepKey="seeContent"/>
66+
<waitForPageLoad stepKey="wait6" />
67+
<waitForText userInput="$$createPreReqProduct.name$$" stepKey="waitForProductVisible" />
68+
<see userInput="$$createPreReqProduct.name$$" stepKey="seeProductName" />
69+
<see userInput="$$createPreReqProduct.price$$" stepKey="seeProductPrice" />
70+
<after>
71+
<deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" />
72+
<deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct" />
73+
<actionGroup ref="DisabledWYSIWYGActionGroup" stepKey="disableWYSIWYG"/>
74+
<!-- Set Magento back to default configuration -->
75+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/>
76+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
77+
</after>
78+
</test>
79+
</tests>

app/code/Magento/Customer/Block/Address/Edit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ protected function _prepareLayout()
125125
if ($postedData = $this->_customerSession->getAddressFormData(true)) {
126126
$postedData['region'] = [
127127
'region_id' => isset($postedData['region_id']) ? $postedData['region_id'] : null,
128-
'region' => $postedData['region'],
128+
'region' => $postedData['region'] ?? null,
129129
];
130130
$this->dataObjectHelper->populateWithArray(
131131
$this->_address,

app/code/Magento/Customer/Model/Url.php

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,29 @@
1717
* Class Customer url model
1818
*
1919
* @api
20+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2021
*/
2122
class Url
2223
{
24+
/**
25+
* No-route url constants
26+
*/
27+
private const XML_PATH_WEB_DEFAULT_NO_ROUTE = 'web/default/no_route';
28+
2329
/**
2430
* Route for customer account login page
2531
*/
26-
const ROUTE_ACCOUNT_LOGIN = 'customer/account/login';
32+
public const ROUTE_ACCOUNT_LOGIN = 'customer/account/login';
2733

2834
/**
2935
* Config name for Redirect Customer to Account Dashboard after Logging in setting
3036
*/
31-
const XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD = 'customer/startup/redirect_dashboard';
37+
public const XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD = 'customer/startup/redirect_dashboard';
3238

3339
/**
3440
* Query param name for last url visited
3541
*/
36-
const REFERER_QUERY_PARAM_NAME = 'referer';
42+
public const REFERER_QUERY_PARAM_NAME = 'referer';
3743

3844
/**
3945
* @var UrlInterface
@@ -126,8 +132,10 @@ public function getLoginUrlParams()
126132
&& !$this->customerSession->getNoReferer()
127133
&& $this->request->isGet()
128134
) {
129-
$referer = $this->urlBuilder->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true]);
130-
$referer = $this->urlEncoder->encode($referer);
135+
$refererUrl = $this->urlBuilder->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true]);
136+
if (!$this->isNoRouteUrl($refererUrl)) {
137+
$referer = $this->urlEncoder->encode($refererUrl);
138+
}
131139
}
132140

133141
if ($referer) {
@@ -246,6 +254,8 @@ public function getEmailConfirmationUrl($email = null)
246254
}
247255

248256
/**
257+
* Getting request referrer
258+
*
249259
* @return mixed|null
250260
*/
251261
private function getRequestReferrer()
@@ -256,4 +266,23 @@ private function getRequestReferrer()
256266
}
257267
return null;
258268
}
269+
270+
/**
271+
* Check if Referrer url is no route url
272+
*
273+
* @param string $url
274+
* @return bool
275+
*/
276+
private function isNoRouteUrl($url)
277+
{
278+
$defaultNoRouteUrl = $this->scopeConfig->getValue(
279+
self::XML_PATH_WEB_DEFAULT_NO_ROUTE,
280+
ScopeInterface::SCOPE_STORE
281+
);
282+
$noRouteUrl = $this->urlBuilder->getUrl($defaultNoRouteUrl);
283+
if (strpos($url, $noRouteUrl) !== false) {
284+
return true;
285+
}
286+
return false;
287+
}
259288
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Model\Validator;
9+
10+
use Magento\Customer\Model\Customer;
11+
use Magento\Framework\Validator\AbstractValidator;
12+
13+
/**
14+
* Customer city fields validator.
15+
*/
16+
class City extends AbstractValidator
17+
{
18+
/**
19+
* Allowed characters:
20+
*
21+
* \p{L}: Unicode letters.
22+
* \p{M}: Unicode marks (diacritic marks, accents, etc.).
23+
* ': Apostrophe mark.
24+
* \s: Whitespace characters (spaces, tabs, newlines, etc.).
25+
*/
26+
private const PATTERN_CITY = '/(?:[\p{L}\p{M}\s\-\']{1,100})/u';
27+
28+
/**
29+
* Validate city fields.
30+
*
31+
* @param Customer $customer
32+
* @return bool
33+
*/
34+
public function isValid($customer)
35+
{
36+
if (!$this->isValidCity($customer->getCity())) {
37+
parent::_addMessages([[
38+
'city' => "Invalid City. Please use A-Z, a-z, 0-9, -, ', spaces"
39+
]]);
40+
}
41+
42+
return count($this->_messages) == 0;
43+
}
44+
45+
/**
46+
* Check if city field is valid.
47+
*
48+
* @param string|null $cityValue
49+
* @return bool
50+
*/
51+
private function isValidCity($cityValue)
52+
{
53+
if ($cityValue != null) {
54+
if (preg_match(self::PATTERN_CITY, $cityValue, $matches)) {
55+
return $matches[0] == $cityValue;
56+
}
57+
}
58+
59+
return true;
60+
}
61+
}

0 commit comments

Comments
 (0)