WP_Speculation_Rules
云策文档标注
概述
WP_Speculation_Rules 是 WordPress 6.8.0 引入的类,用于管理推测规则(speculation rules),支持预取(prefetch)和预渲染(prerender)模式。它实现了 JsonSerializable 接口,提供规则添加、验证和序列化功能。
关键要点
- 类 WP_Speculation_Rules 用于处理推测规则,支持模式(mode)、ID、来源(source)和急切程度(eagerness)的验证。
- 主要方法包括 add_rule() 添加规则、has_rule() 检查规则存在性、jsonSerialize() 序列化规则为 JSON 格式。
- 验证方法如 is_valid_mode()、is_valid_eagerness()、is_valid_source() 和 is_valid_id() 确保规则参数的有效性。
- 规则存储为数组结构,按模式分组,每个规则需包含 'where' 或 'urls' 键,且不能同时存在。
- 支持的模式包括 'prefetch' 和 'prerender',来源包括 'list' 和 'document',急切程度包括 'immediate'、'eager'、'moderate' 和 'conservative'。
代码示例
final class WP_Speculation_Rules implements JsonSerializable {
private $rules_by_mode = array();
private static $mode_allowlist = array(
'prefetch' => true,
'prerender' => true,
);
private static $eagerness_allowlist = array(
'immediate' => true,
'eager' => true,
'moderate' => true,
'conservative' => true,
);
private static $source_allowlist = array(
'list' => true,
'document' => true,
);
public function add_rule( string $mode, string $id, array $rule ): bool {
// 验证逻辑和规则添加代码
}
public function has_rule( string $mode, string $id ): bool {
return isset( $this->rules_by_mode[$mode][$id] );
}
#[ReturnTypeWillChange]
public function jsonSerialize() {
return array_map(
static function ( array $rules ) {
return array_values( $rules );
},
array_filter( $this->rules_by_mode )
);
}
private function is_valid_id( string $id ): bool {
return (bool) preg_match( '/^[a-z][a-z0-9_-]+$/', $id );
}
public static function is_valid_mode( string $mode ): bool {
return isset( self::$mode_allowlist[$mode] );
}
public static function is_valid_eagerness( string $eagerness ): bool {
return isset( self::$eagerness_allowlist[$eagerness] );
}
public static function is_valid_source( string $source ): bool {
return isset( self::$source_allowlist[$source] );
}
}注意事项
- 添加规则时需确保模式、ID、来源和急切程度的有效性,否则会触发 _doing_it_wrong() 警告并返回 false。
- 规则必须包含 'where' 或 'urls' 键之一,且不能同时存在;'where' 对应 'document' 来源,'urls' 对应 'list' 来源。
- 急切程度 'immediate' 不允许用于 'document' 来源的规则。
- ID 必须匹配正则表达式 /^[a-z][a-z0-9_-]+$/ 以确保唯一性和有效性。
- 序列化时,规则 ID 会被移除,因为 Speculation Rules API 不需要它们。
原文内容
Class representing a set of speculation rules.
Methods
| Name | Description |
|---|---|
| WP_Speculation_Rules::add_rule | Adds a speculation rule to the speculation rules to consider. |
| WP_Speculation_Rules::has_rule | Checks whether a speculation rule for the given mode and ID already exists. |
| WP_Speculation_Rules::is_valid_eagerness | Checks whether the given speculation rules eagerness is valid. |
| WP_Speculation_Rules::is_valid_id | Checks whether the given ID is valid. |
| WP_Speculation_Rules::is_valid_mode | Checks whether the given speculation rules mode is valid. |
| WP_Speculation_Rules::is_valid_source | Checks whether the given speculation rules source is valid. |
| WP_Speculation_Rules::jsonSerialize | – |
Source
final class WP_Speculation_Rules implements JsonSerializable {
/**
* Stored rules, as a map of `$mode => $rules` pairs.
*
* Every `$rules` value is a map of `$id => $rule` pairs.
*
* @since 6.8.0
* @var array<string, array<string, mixed>>
*/
private $rules_by_mode = array();
/**
* The allowed speculation rules modes as a map, used for validation.
*
* @since 6.8.0
* @var array<string, bool>
*/
private static $mode_allowlist = array(
'prefetch' => true,
'prerender' => true,
);
/**
* The allowed speculation rules eagerness levels as a map, used for validation.
*
* @since 6.8.0
* @var array<string, bool>
*/
private static $eagerness_allowlist = array(
'immediate' => true,
'eager' => true,
'moderate' => true,
'conservative' => true,
);
/**
* The allowed speculation rules sources as a map, used for validation.
*
* @since 6.8.0
* @var array<string, bool>
*/
private static $source_allowlist = array(
'list' => true,
'document' => true,
);
/**
* Adds a speculation rule to the speculation rules to consider.
*
* @since 6.8.0
*
* @param string $mode Speculative loading mode. Either 'prefetch' or 'prerender'.
* @param string $id Unique string identifier for the speculation rule.
* @param array<string, mixed> $rule Associative array of rule arguments.
* @return bool True on success, false if invalid parameters are provided.
*/
public function add_rule( string $mode, string $id, array $rule ): bool {
if ( ! self::is_valid_mode( $mode ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: invalid mode value */
__( 'The value "%s" is not a valid speculation rules mode.' ),
esc_html( $mode )
),
'6.8.0'
);
return false;
}
if ( ! $this->is_valid_id( $id ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: invalid ID value */
__( 'The value "%s" is not a valid ID for a speculation rule.' ),
esc_html( $id )
),
'6.8.0'
);
return false;
}
if ( $this->has_rule( $mode, $id ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: invalid ID value */
__( 'A speculation rule with ID "%s" already exists.' ),
esc_html( $id )
),
'6.8.0'
);
return false;
}
/*
* Perform some basic speculation rule validation.
* Every rule must have either a 'where' key or a 'urls' key, but not both.
* The presence of a 'where' key implies a 'source' of 'document', while the presence of a 'urls' key implies
* a 'source' of 'list'.
*/
if (
( ! isset( $rule['where'] ) && ! isset( $rule['urls'] ) ) ||
( isset( $rule['where'] ) && isset( $rule['urls'] ) )
) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: 1: allowed key, 2: alternative allowed key */
__( 'A speculation rule must include either a "%1$s" key or a "%2$s" key, but not both.' ),
'where',
'urls'
),
'6.8.0'
);
return false;
}
if ( isset( $rule['source'] ) ) {
if ( ! self::is_valid_source( $rule['source'] ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: invalid source value */
__( 'The value "%s" is not a valid source for a speculation rule.' ),
esc_html( $rule['source'] )
),
'6.8.0'
);
return false;
}
if ( 'list' === $rule['source'] && isset( $rule['where'] ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: 1: source value, 2: forbidden key */
__( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ),
'list',
'where'
),
'6.8.0'
);
return false;
}
if ( 'document' === $rule['source'] && isset( $rule['urls'] ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: 1: source value, 2: forbidden key */
__( 'A speculation rule of source "%1$s" must not include a "%2$s" key.' ),
'document',
'urls'
),
'6.8.0'
);
return false;
}
}
// If there is an 'eagerness' key specified, make sure it's valid.
if ( isset( $rule['eagerness'] ) ) {
if ( ! self::is_valid_eagerness( $rule['eagerness'] ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: invalid eagerness value */
__( 'The value "%s" is not a valid eagerness for a speculation rule.' ),
esc_html( $rule['eagerness'] )
),
'6.8.0'
);
return false;
}
if ( isset( $rule['where'] ) && 'immediate' === $rule['eagerness'] ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: forbidden eagerness value */
__( 'The eagerness value "%s" is forbidden for document-level speculation rules.' ),
'immediate'
),
'6.8.0'
);
return false;
}
}
if ( ! isset( $this->rules_by_mode[ $mode ] ) ) {
$this->rules_by_mode[ $mode ] = array();
}
$this->rules_by_mode[ $mode ][ $id ] = $rule;
return true;
}
/**
* Checks whether a speculation rule for the given mode and ID already exists.
*
* @since 6.8.0
*
* @param string $mode Speculative loading mode. Either 'prefetch' or 'prerender'.
* @param string $id Unique string identifier for the speculation rule.
* @return bool True if the rule already exists, false otherwise.
*/
public function has_rule( string $mode, string $id ): bool {
return isset( $this->rules_by_mode[ $mode ][ $id ] );
}
/**
* Returns the speculation rules data ready to be JSON-encoded.
*
* @since 6.8.0
*
* @return array<string, array<string, mixed>> Speculation rules data.
*/
#[ReturnTypeWillChange]
public function jsonSerialize() {
// Strip the IDs for JSON output, since they are not relevant for the Speculation Rules API.
return array_map(
static function ( array $rules ) {
return array_values( $rules );
},
array_filter( $this->rules_by_mode )
);
}
/**
* Checks whether the given ID is valid.
*
* @since 6.8.0
*
* @param string $id Unique string identifier for the speculation rule.
* @return bool True if the ID is valid, false otherwise.
*/
private function is_valid_id( string $id ): bool {
return (bool) preg_match( '/^[a-z][a-z0-9_-]+$/', $id );
}
/**
* Checks whether the given speculation rules mode is valid.
*
* @since 6.8.0
*
* @param string $mode Speculation rules mode.
* @return bool True if valid, false otherwise.
*/
public static function is_valid_mode( string $mode ): bool {
return isset( self::$mode_allowlist[ $mode ] );
}
/**
* Checks whether the given speculation rules eagerness is valid.
*
* @since 6.8.0
*
* @param string $eagerness Speculation rules eagerness.
* @return bool True if valid, false otherwise.
*/
public static function is_valid_eagerness( string $eagerness ): bool {
return isset( self::$eagerness_allowlist[ $eagerness ] );
}
/**
* Checks whether the given speculation rules source is valid.
*
* @since 6.8.0
*
* @param string $source Speculation rules source.
* @return bool True if valid, false otherwise.
*/
public static function is_valid_source( string $source ): bool {
return isset( self::$source_allowlist[ $source ] );
}
}
Changelog
| Version | Description |
|---|---|
| 6.8.0 | Introduced. |