Automattic\WooCommerce\EmailEditor\Engine
Personalizer::parse_token
Parse a personalization tag to the token and attributes.
Method of the class: Personalizer{}
No Hooks.
Returns
Array{token:. string, arguments: array<string, string>} The parsed token.
Usage
// private - for code of main (parent) class only $result = $this->parse_token( $token ): array;
- $token(string) (required)
- The token to parse.
Personalizer::parse_token() Personalizer::parse token code WC 10.8.1
private function parse_token( string $token ): array {
$result = array(
'token' => '',
'arguments' => array(),
);
// Step 1: Separate the tag and attributes.
if ( preg_match( '/^\[(' . self::TAG_NAME_PATTERN . ')\s*(.*?)\]$/', trim( $token ), $matches ) ) {
$result['token'] = "[{$matches[1]}]"; // The tag part (e.g., "[mailpoet/subscriber-firstname]").
$attributes_string = $matches[2]; // The attributes part (e.g., 'default="subscriber"').
// Step 2: Extract attributes from the attribute string.
// Match quoted values (double or single quotes separately to avoid mixing) and unquoted values.
// Unquoted values can occur when esc_url() strips quotes from personalization tags.
// For unquoted values with spaces, capture until the next key= pattern or closing bracket.
// The negative lookahead (?!\w+=) is critical for preventing ReDoS:
// it ensures the inner loop terminates as soon as the next key= pattern appears,
// preventing excessive backtracking despite the nested quantifiers.
if ( preg_match_all( '/(\w+)=(?:"([^"]*)"|\'([^\']*)\'|([^\s\]]+(?:\s+(?!\w+=)[^\s\]]+)*))/', $attributes_string, $attribute_matches, PREG_SET_ORDER ) ) {
foreach ( $attribute_matches as $attribute ) {
// $attribute[2] is double-quoted value, $attribute[3] is single-quoted value,
// $attribute[4] is unquoted value (may contain spaces).
// Use null coalescing as only one of these will be populated depending on which pattern matched.
$double_quoted_value = $attribute[2] ?? '';
$single_quoted_value = $attribute[3] ?? '';
$unquoted_value = $attribute[4] ?? '';
if ( '' !== $double_quoted_value ) {
$result['arguments'][ $attribute[1] ] = $double_quoted_value;
} elseif ( '' !== $single_quoted_value ) {
$result['arguments'][ $attribute[1] ] = $single_quoted_value;
} else {
$result['arguments'][ $attribute[1] ] = $unquoted_value;
}
}
}
}
return $result;
}