WP_Block_Parser::next_token()publicWP 5.0.0

Scans the document from where we last left off and finds the next valid token to parse if it exists

Returns the type of the find: kind of find, block information, attributes

Метод класса: WP_Block_Parser{}

Хуков нет.

Возвращает

Массив.

Использование

$WP_Block_Parser = new WP_Block_Parser();
$WP_Block_Parser->next_token();

Список изменений

С версии 5.0.0 Введена.
С версии 4.6.1 fixed a bug in attribute parsing which caused catastrophic backtracking on invalid block comments

Код WP_Block_Parser::next_token() WP 6.5.2

public function next_token() {
	$matches = null;

	/*
	 * aye the magic
	 * we're using a single RegExp to tokenize the block comment delimiters
	 * we're also using a trick here because the only difference between a
	 * block opener and a block closer is the leading `/` before `wp:` (and
	 * a closer has no attributes). we can trap them both and process the
	 * match back in PHP to see which one it was.
	 */
	$has_match = preg_match(
		'/<!--\s+(?P<closer>\/)?wp:(?P<namespace>[a-z][a-z0-9_-]*\/)?(?P<name>[a-z][a-z0-9_-]*)\s+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*+)?}\s+)?(?P<void>\/)?-->/s',
		$this->document,
		$matches,
		PREG_OFFSET_CAPTURE,
		$this->offset
	);

	// if we get here we probably have catastrophic backtracking or out-of-memory in the PCRE.
	if ( false === $has_match ) {
		return array( 'no-more-tokens', null, null, null, null );
	}

	// we have no more tokens.
	if ( 0 === $has_match ) {
		return array( 'no-more-tokens', null, null, null, null );
	}

	list( $match, $started_at ) = $matches[0];

	$length    = strlen( $match );
	$is_closer = isset( $matches['closer'] ) && -1 !== $matches['closer'][1];
	$is_void   = isset( $matches['void'] ) && -1 !== $matches['void'][1];
	$namespace = $matches['namespace'];
	$namespace = ( isset( $namespace ) && -1 !== $namespace[1] ) ? $namespace[0] : 'core/';
	$name      = $namespace . $matches['name'][0];
	$has_attrs = isset( $matches['attrs'] ) && -1 !== $matches['attrs'][1];

	/*
	 * Fun fact! It's not trivial in PHP to create "an empty associative array" since all arrays
	 * are associative arrays. If we use `array()` we get a JSON `[]`
	 */
	$attrs = $has_attrs
		? json_decode( $matches['attrs'][0], /* as-associative */ true )
		: array();

	/*
	 * This state isn't allowed
	 * This is an error
	 */
	if ( $is_closer && ( $is_void || $has_attrs ) ) {
		// we can ignore them since they don't hurt anything.
	}

	if ( $is_void ) {
		return array( 'void-block', $name, $attrs, $started_at, $length );
	}

	if ( $is_closer ) {
		return array( 'block-closer', $name, null, $started_at, $length );
	}

	return array( 'block-opener', $name, $attrs, $started_at, $length );
}