Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 6862632

Browse files
author
Oleksii Korshenko
authored
Merge pull request #1773 from magento-engcom/2.2-develop-prs
Public Pull Requests magento/magento2#12328 9742: Default welcome message returns after being deleted #9742 by @RomaKis magento/magento2#12253 New validation: 3bytes characters filter (4 bytes characters cannot be stored using UTF8) by @KarlDeux magento/magento2#12133 Fix for issue 12127: Single quotation marks are now decoded properly in admin attribute option input fields by @erfanimani magento/magento2#11389 Attribute category_ids issue by @manuelson Fixed Public Issues magento/magento2#9742 Default welcome message returns after being deleted magento/magento2#12058 Can't save emoji in custom product options magento/magento2#12127 Apostrophe in attribute option value in admin is not handled properly magento/magento2#11341 Attribute category_ids issue
2 parents 3d628f8 + a0a2474 commit 6862632

File tree

10 files changed

+176
-6
lines changed

10 files changed

+176
-6
lines changed

app/code/Magento/Catalog/Block/Product/View/Attributes.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ public function getAdditionalData(array $excludeAttr = [])
8181
$attributes = $product->getAttributes();
8282
foreach ($attributes as $attribute) {
8383
if ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr)) {
84-
$value = $attribute->getFrontend()->getValue($product);
85-
84+
if (is_array($value = $attribute->getFrontend()->getValue($product))) {
85+
continue;
86+
}
8687
if (!$product->hasData($attribute->getAttributeCode())) {
8788
$value = __('N/A');
8889
} elseif ((string)$value == '') {
8990
$value = __('No');
9091
} elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) {
9192
$value = $this->priceCurrency->convertAndFormat($value);
9293
}
93-
9494
if ($value instanceof Phrase || (is_string($value) && strlen($value))) {
9595
$data[$attribute->getAttributeCode()] = [
9696
'label' => __($attribute->getStoreLabel()),

app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ $stores = $block->getStoresSortedBySortOrder();
8888
$values = [];
8989
foreach($block->getOptionValues() as $value) {
9090
$value = $value->getData();
91-
$values[] = is_array($value) ? array_map("htmlspecialchars_decode", $value) : $value;
91+
$values[] = is_array($value) ? array_map(function($str) {
92+
return htmlspecialchars_decode($str, ENT_QUOTES);
93+
}, $value) : $value;
9294
}
9395
?>
9496
<script type="text/x-magento-init">

app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
2929
if ($_option->getMaxCharacters()) {
3030
$_textValidate['maxlength'] = $_option->getMaxCharacters();
3131
}
32+
$_textValidate['validate-no-utf8mb4-characters'] = true;
3233
?>
3334
<input type="text"
3435
id="options_<?= /* @escapeNotVerified */ $_option->getId() ?>_text"
@@ -47,6 +48,7 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
4748
if ($_option->getMaxCharacters()) {
4849
$_textAreaValidate['maxlength'] = $_option->getMaxCharacters();
4950
}
51+
$_textAreaValidate['validate-no-utf8mb4-characters'] = true;
5052
?>
5153
<textarea id="options_<?= /* @escapeNotVerified */ $_option->getId() ?>_text"
5254
class="product-custom-option"

app/code/Magento/Theme/Model/Design/Config/Storage.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,13 @@ public function load($scope, $scopeId)
8787
$scopeId,
8888
$fieldData->getFieldConfig()
8989
);
90-
if ($value !== null) {
91-
$fieldData->setValue($value);
90+
91+
if ($value === null) {
92+
$value = '';
9293
}
94+
$fieldData->setValue($value);
9395
}
96+
9497
return $designConfig;
9598
}
9699

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Theme\Model\Design;
8+
9+
/**
10+
* Test for \Magento\Theme\Model\Design\Config\Storage.
11+
*/
12+
class ConfigTest extends \PHPUnit\Framework\TestCase
13+
{
14+
/**
15+
* @var \Magento\Theme\Model\Design\Config\Storage
16+
*/
17+
private $storage;
18+
19+
protected function setUp()
20+
{
21+
$this->storage = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
22+
\Magento\Theme\Model\Design\Config\Storage::class
23+
);
24+
}
25+
26+
/**
27+
* Test design/header/welcome if it is saved in db as empty(null) it should be shown on backend as empty.
28+
*
29+
* @magentoDataFixture Magento/Theme/_files/config_data.php
30+
*/
31+
public function testLoad()
32+
{
33+
$data = $this->storage->load('stores', 1);
34+
foreach ($data->getExtensionAttributes()->getDesignConfigData() as $configData) {
35+
if ($configData->getPath() == 'design/header/welcome') {
36+
$this->assertSame('', $configData->getValue());
37+
}
38+
}
39+
}
40+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Config\Model\Config\Factory;
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
10+
$objectManager = Bootstrap::getObjectManager();
11+
12+
/** @var Factory $configFactory */
13+
$configFactory = $objectManager->create(Factory::class);
14+
/** @var \Magento\Config\Model\Config $config */
15+
$config = $configFactory->create();
16+
$config->setScope('stores');
17+
$config->setStore('default');
18+
$config->setDataByPath('design/header/welcome', null);
19+
$config->save();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
8+
/** @var \Magento\Framework\App\ResourceConnection $resource */
9+
$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class);
10+
$connection = $resource->getConnection();
11+
$tableName = $resource->getTableName('core_config_data');
12+
13+
$connection->query("DELETE FROM $tableName WHERE path = 'design/header/welcome';");

dev/tests/js/jasmine/tests/lib/mage/validation.test.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,76 @@ define([
183183
)).toEqual(true);
184184
});
185185
});
186+
187+
describe('Testing 3 bytes characters only policy (UTF-8)', function () {
188+
it('rejects data, if any of the characters cannot be stored using UTF-8 collation', function () {
189+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
190+
$.validator.prototype, '😅😂', null
191+
)).toEqual(false);
192+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
193+
$.validator.prototype, '😅 test 😂', null
194+
)).toEqual(false);
195+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
196+
$.validator.prototype, '💩 👻 💀', null
197+
)).toEqual(false);
198+
});
199+
200+
it('approves data, if all the characters can be stored using UTF-8 collation', function () {
201+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
202+
$.validator.prototype, '', null
203+
)).toEqual(true);
204+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
205+
$.validator.prototype, '!$-_%ç&#?!', null
206+
)).toEqual(true);
207+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
208+
$.validator.prototype, '1234567890', null
209+
)).toEqual(true);
210+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
211+
$.validator.prototype, ' ', null
212+
)).toEqual(true);
213+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
214+
$.validator.prototype, 'test', null
215+
)).toEqual(true);
216+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
217+
$.validator.prototype, 'испытание', null
218+
)).toEqual(true);
219+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
220+
$.validator.prototype, 'тест', null
221+
)).toEqual(true);
222+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
223+
$.validator.prototype, 'փորձարկում', null
224+
)).toEqual(true);
225+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
226+
$.validator.prototype, 'परीक्षण', null
227+
)).toEqual(true);
228+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
229+
$.validator.prototype, 'テスト', null
230+
)).toEqual(true);
231+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
232+
$.validator.prototype, '테스트', null
233+
)).toEqual(true);
234+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
235+
$.validator.prototype, '测试', null
236+
)).toEqual(true);
237+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
238+
$.validator.prototype, '測試', null
239+
)).toEqual(true);
240+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
241+
$.validator.prototype, 'ทดสอบ', null
242+
)).toEqual(true);
243+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
244+
$.validator.prototype, 'δοκιμή', null
245+
)).toEqual(true);
246+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
247+
$.validator.prototype, 'اختبار', null
248+
)).toEqual(true);
249+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
250+
$.validator.prototype, 'تست', null
251+
)).toEqual(true);
252+
expect($.validator.methods['validate-no-utf8mb4-characters'].call(
253+
$.validator.prototype, 'מִבְחָן', null
254+
)).toEqual(true);
255+
});
256+
});
257+
186258
});

lib/web/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Submit,Submit
9999
"Password cannot be the same as email address.","Password cannot be the same as email address."
100100
"Please fix this field.","Please fix this field."
101101
"Please enter a valid email address.","Please enter a valid email address."
102+
"Please remove invalid characters: {0}.", "Please remove invalid characters: {0}."
102103
"Please enter a valid URL.","Please enter a valid URL."
103104
"Please enter a valid date (ISO).","Please enter a valid date (ISO)."
104105
"Please enter only digits.","Please enter only digits."

lib/web/mage/validation.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,24 @@
396396
$.mage.__('Please enter at least {0} characters')
397397
],
398398

399+
/* detect chars that would require more than 3 bytes */
400+
'validate-no-utf8mb4-characters': [
401+
function (value) {
402+
var validator = this,
403+
message = $.mage.__('Please remove invalid characters: {0}.'),
404+
matches = value.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF])/g),
405+
result = matches === null;
406+
407+
if (!result) {
408+
validator.charErrorMessage = message.replace('{0}', matches.join());
409+
}
410+
411+
return result;
412+
}, function () {
413+
return this.charErrorMessage;
414+
}
415+
],
416+
399417
/* eslint-disable max-len */
400418
'email2': [
401419
function (value, element) {

0 commit comments

Comments
 (0)