ntf( /* 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> 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 ] ); } }