Skip to content
Snippets Groups Projects
Commit c1497dfb authored by Mikael Meulle's avatar Mikael Meulle
Browse files

Merge branch '3494949-2.0.0-rc1-allow-identifier' into '2.0.x'

Resolve #3494949 "2.0.0 rc1 allow identifier"

See merge request !307
parents d87fec0b 7d1c1474
No related branches found
No related tags found
No related merge requests found
Pipeline #374220 passed
......@@ -19,6 +19,7 @@ use Drupal\ui_patterns\PropTypePluginBase;
label: new TranslatableMarkup('Identifier'),
description: new TranslatableMarkup('A string with restricted characters, suitable for an HTML ID.'),
default_source: 'textfield',
convert_from: ['string'],
schema: ['type' => 'string', 'pattern' => '(?:--|-?[A-Za-z_\x{00A0}-\x{10FFFF}])[A-Za-z0-9-_\x{00A0}-\x{10FFFF}\.]*'],
priority: 100
)]
......@@ -30,7 +31,22 @@ class IdentifierPropType extends PropTypePluginBase {
* {@inheritdoc}
*/
public static function normalize(mixed $value, ?array $definition = NULL): mixed {
return strip_tags(static::convertToString($value));
$value = strip_tags(static::convertToString($value));
// Clean the value.
$value = preg_replace('/[^A-Za-z0-9-_\x{00A0}-\x{10FFFF}\.]/u', '-', $value);
return $value;
}
/**
* {@inheritdoc}
*/
public static function convertFrom(string $prop_type, mixed $value): mixed {
// We allow conversion from string,
// normalize() will partially sanitize the value.
// Invalid identifiers throw exceptions.
return match ($prop_type) {
'string' => (string) $value,
};
}
}
......@@ -25,11 +25,7 @@ trait UnicodePatternValidatorTrait {
*/
public static function validateUnicodePattern(array &$element, FormStateInterface $form_state) : void {
if ($element['#value'] !== '') {
$pattern = $element['#pattern_unicode'];
// JavaScript-escaped Unicode characters to PCRE escape sequence format.
$pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $pattern);
$pattern = '{^(?:' . $pcre_pattern . ')$}u';
if (!preg_match($pattern, $element['#value'])) {
if (!static::pregMatchUnicodePattern($element['#pattern_unicode'], $element['#value'])) {
if (!empty($element['#pattern_error'])) {
$form_state->setError($element, $element['#pattern_error']);
}
......@@ -40,4 +36,34 @@ trait UnicodePatternValidatorTrait {
}
}
/**
* Match a string against a Unicode pattern.
*
* @param string $pattern
* Regular expression pattern.
* @param string $subject
* The string to match.
*
* @return bool
* TRUE if the pattern matches the subject, FALSE otherwise.
*/
public static function pregMatchUnicodePattern(string $pattern, string $subject): bool {
$pattern = '{^(?:' . static::convertRegexToPcreFormat($pattern) . ')$}u';
return (bool) preg_match($pattern, $subject);
}
/**
* JavaScript-escaped Unicode characters to PCRE escape sequence format.
*
* @param string $pattern
* Regular expression pattern.
*
* @return string
* PCRE format pattern.
*/
public static function convertRegexToPcreFormat(string $pattern): string {
// JavaScript-escaped Unicode characters to PCRE escape sequence format.
return preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $pattern);
}
}
......@@ -131,6 +131,20 @@ textfield_default:
elementTextEquals:
- [ 'css', '.ui-patterns-props-string', 'test input' ]
textfield_identifier:
component:
component_id: ui_patterns_test:test-component
props:
identifier:
source_id: textfield
source:
value: 'my identifier'
assertSession:
elementExists:
- [ 'css', '.ui-patterns-test-component' ]
elementTextEquals:
- [ 'css', '.ui-patterns-props-identifier', 'my-identifier' ]
select_string:
component:
......
......@@ -45,7 +45,7 @@ class IdentifierPropTypeTest extends PropTypeNormalizationTestBase {
"markup" => [['#markup' => "abc"], "abc"],
"string" => ["abc", "abc"],
"string with markup" => ["<b>abc</b>", "abc"],
"string with square brackets" => ["a[v][eee]", "a[v][eee]"],
"string with square brackets" => ["a[v][eee]", "a-v--eee-"],
];
}
......@@ -73,6 +73,10 @@ class IdentifierPropTypeTest extends PropTypeNormalizationTestBase {
"correct-value🔥",
'<div class="ui-patterns-props-identifier">correct-value🔥</div>',
],
"corrected value" => [
"value with space and /",
'<div class="ui-patterns-props-identifier">value-with-space-and--</div>',
],
];
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment