WP_Token_Map::from_array()public staticWP 6.6.0

Create a token map using an associative array of key/value pairs as the input.

Example:

$smilies = WP_Token_Map::from_array( array(
	 '8O' => '😯',
	 ':(' => '🙁',
	 ':)' => '🙂',
	 ':?' => '😕',
  ) );

Method of the class: WP_Token_Map{}

No Hooks.

Return

WP_Token_Map|null. Token map, unless unable to create it.

Usage

$result = WP_Token_Map::from_array( $mappings, $key_length ): ?WP_Token_Map;
$mappings(array) (required)
The keys transform into the values, both are strings.
$key_length(int)
Determines the group key length. Leave at the default value of 2 unless there's an empirical reason to change it.
Default: 2

Changelog

Since 6.6.0 Introduced.

WP_Token_Map::from_array() code WP 6.7.1

public static function from_array( array $mappings, int $key_length = 2 ): ?WP_Token_Map {
	$map             = new WP_Token_Map();
	$map->key_length = $key_length;

	// Start by grouping words.

	$groups = array();
	$shorts = array();
	foreach ( $mappings as $word => $mapping ) {
		if (
			self::MAX_LENGTH <= strlen( $word ) ||
			self::MAX_LENGTH <= strlen( $mapping )
		) {
			_doing_it_wrong(
				__METHOD__,
				sprintf(
					/* translators: 1: maximum byte length (a count) */
					__( 'Token Map tokens and substitutions must all be shorter than %1$d bytes.' ),
					self::MAX_LENGTH
				),
				'6.6.0'
			);
			return null;
		}

		$length = strlen( $word );

		if ( $key_length >= $length ) {
			$shorts[] = $word;
		} else {
			$group = substr( $word, 0, $key_length );

			if ( ! isset( $groups[ $group ] ) ) {
				$groups[ $group ] = array();
			}

			$groups[ $group ][] = array( substr( $word, $key_length ), $mapping );
		}
	}

	/*
	 * Sort the words to ensure that no smaller substring of a match masks the full match.
	 * For example, `Cap` should not match before `CapitalDifferentialD`.
	 */
	usort( $shorts, 'WP_Token_Map::longest_first_then_alphabetical' );
	foreach ( $groups as $group_key => $group ) {
		usort(
			$groups[ $group_key ],
			static function ( array $a, array $b ): int {
				return self::longest_first_then_alphabetical( $a[0], $b[0] );
			}
		);
	}

	// Finally construct the optimized lookups.

	foreach ( $shorts as $word ) {
		$map->small_words     .= str_pad( $word, $key_length + 1, "\x00", STR_PAD_RIGHT );
		$map->small_mappings[] = $mappings[ $word ];
	}

	$group_keys = array_keys( $groups );
	sort( $group_keys );

	foreach ( $group_keys as $group ) {
		$map->groups .= "{$group}\x00";

		$group_string = '';

		foreach ( $groups[ $group ] as $group_word ) {
			list( $word, $mapping ) = $group_word;

			$word_length    = pack( 'C', strlen( $word ) );
			$mapping_length = pack( 'C', strlen( $mapping ) );
			$group_string  .= "{$word_length}{$word}{$mapping_length}{$mapping}";
		}

		$map->large_words[] = $group_string;
	}

	return $map;
}