|
18 | 18 | * @param string $optimization_detective_version Current version of the optimization detective plugin.
|
19 | 19 | */
|
20 | 20 | function image_prioritizer_init( string $optimization_detective_version ): void {
|
21 |
| - $required_od_version = '0.7.0'; |
| 21 | + $required_od_version = '0.9.0'; |
22 | 22 | if ( ! version_compare( (string) strtok( $optimization_detective_version, '-' ), $required_od_version, '>=' ) ) {
|
23 | 23 | add_action(
|
24 | 24 | 'admin_notices',
|
@@ -121,7 +121,6 @@ function image_prioritizer_filter_extension_module_urls( $extension_module_urls
|
121 | 121 | * @return array<string, array{type: string}> Additional properties.
|
122 | 122 | */
|
123 | 123 | function image_prioritizer_add_element_item_schema_properties( array $additional_properties ): array {
|
124 |
| - // TODO: Validation of the URL. |
125 | 124 | $additional_properties['lcpElementExternalBackgroundImage'] = array(
|
126 | 125 | 'type' => 'object',
|
127 | 126 | 'properties' => array(
|
@@ -151,3 +150,63 @@ function image_prioritizer_add_element_item_schema_properties( array $additional
|
151 | 150 | );
|
152 | 151 | return $additional_properties;
|
153 | 152 | }
|
| 153 | + |
| 154 | +/** |
| 155 | + * Validates that the provided background image URL is valid. |
| 156 | + * |
| 157 | + * @since n.e.x.t |
| 158 | + * |
| 159 | + * @param bool|WP_Error|mixed $validity Validity. Valid if true or a WP_Error without any errors, or invalid otherwise. |
| 160 | + * @param OD_Strict_URL_Metric $url_metric URL Metric, already validated against the JSON Schema. |
| 161 | + * @return bool|WP_Error Validity. Valid if true or a WP_Error without any errors, or invalid otherwise. |
| 162 | + */ |
| 163 | +function image_prioritizer_filter_store_url_metric_validity( $validity, OD_Strict_URL_Metric $url_metric ) { |
| 164 | + if ( ! is_bool( $validity ) && ! ( $validity instanceof WP_Error ) ) { |
| 165 | + $validity = (bool) $validity; |
| 166 | + } |
| 167 | + |
| 168 | + $data = $url_metric->get( 'lcpElementExternalBackgroundImage' ); |
| 169 | + if ( ! is_array( $data ) ) { |
| 170 | + return $validity; |
| 171 | + } |
| 172 | + |
| 173 | + $r = wp_safe_remote_head( |
| 174 | + $data['url'], |
| 175 | + array( |
| 176 | + 'redirection' => 3, // Allow up to 3 redirects. |
| 177 | + ) |
| 178 | + ); |
| 179 | + if ( $r instanceof WP_Error ) { |
| 180 | + return new WP_Error( |
| 181 | + WP_DEBUG ? $r->get_error_code() : 'head_request_failure', |
| 182 | + __( 'HEAD request for background image URL failed.', 'image-prioritizer' ) . ( WP_DEBUG ? ' ' . $r->get_error_message() : '' ), |
| 183 | + array( |
| 184 | + 'code' => 500, |
| 185 | + ) |
| 186 | + ); |
| 187 | + } |
| 188 | + $response_code = wp_remote_retrieve_response_code( $r ); |
| 189 | + if ( $response_code < 200 || $response_code >= 400 ) { |
| 190 | + return new WP_Error( |
| 191 | + 'background_image_response_not_ok', |
| 192 | + __( 'HEAD request for background image URL did not return with a success status code.', 'image-prioritizer' ), |
| 193 | + array( |
| 194 | + 'code' => WP_DEBUG ? $response_code : 400, |
| 195 | + ) |
| 196 | + ); |
| 197 | + } |
| 198 | + |
| 199 | + $content_type = wp_remote_retrieve_header( $r, 'Content-Type' ); |
| 200 | + if ( ! is_string( $content_type ) || ! str_starts_with( $content_type, 'image/' ) ) { |
| 201 | + return new WP_Error( |
| 202 | + 'background_image_response_not_image', |
| 203 | + __( 'HEAD request for background image URL did not return an image Content-Type.', 'image-prioritizer' ), |
| 204 | + array( |
| 205 | + 'code' => 400, |
| 206 | + ) |
| 207 | + ); |
| 208 | + } |
| 209 | + |
| 210 | + // TODO: Check for the Content-Length and return invalid if it is gigantic? |
| 211 | + return $validity; |
| 212 | +} |
0 commit comments