| @@ -25,11 +25,9 @@ | ||
| 25 | 25 | $url = preg_replace( '/(.*)-\d+x\d+\.(jpg|png|gif)$/', '$1.$2', $url ); |
| 26 | 26 | |
| 27 | 27 | static $uploads; |
| 28 | 28 | |
| 29 | - if ( $uploads === null ) { | |
| 30 | - $uploads = wp_get_upload_dir(); | |
| 31 | - } | |
| 29 | + $uploads ??= wp_get_upload_dir(); | |
| 32 | 30 | |
| 33 | 31 | // Don't try to do this for external URLs. |
| 34 | 32 | if ( strpos( $url, $uploads['baseurl'] ) !== 0 ) { |
| 35 | 33 | return 0; |
| @@ -69,8 +67,17 @@ | ||
| 69 | 67 | // Note: We use the WP COM version if we can, see above. |
| 70 | 68 | $id = attachment_url_to_postid( $url ); |
| 71 | 69 | |
| 72 | 70 | if ( empty( $id ) ) { |
| 71 | + /** | |
| 72 | + * If no ID was found, maybe we're dealing with a scaled big image. So, let's try that. | |
| 73 | + * | |
| 74 | + * @see https://core.trac.wordpress.org/ticket/51058 | |
| 75 | + */ | |
| 76 | + $id = self::get_scaled_image_id( $url ); | |
| 77 | + } | |
| 78 | + | |
| 79 | + if ( empty( $id ) ) { | |
| 73 | 80 | wp_cache_set( $cache_key, 'not_found', '', ( 12 * HOUR_IN_SECONDS + wp_rand( 0, ( 4 * HOUR_IN_SECONDS ) ) ) ); |
| 74 | 81 | return 0; |
| 75 | 82 | } |
| 76 | 83 | |
| @@ -79,14 +86,32 @@ | ||
| 79 | 86 | return $id; |
| 80 | 87 | } |
| 81 | 88 | |
| 82 | 89 | /** |
| 90 | + * Tries getting the ID of a potentially scaled image. | |
| 91 | + * | |
| 92 | + * @param string $url The URL of the image. | |
| 93 | + * | |
| 94 | + * @return int|false The ID of the image or false for failure. | |
| 95 | + */ | |
| 96 | + protected static function get_scaled_image_id( $url ) { | |
| 97 | + $path_parts = pathinfo( $url ); | |
| 98 | + if ( isset( $path_parts['dirname'], $path_parts['filename'], $path_parts['extension'] ) ) { | |
| 99 | + $scaled_url = trailingslashit( $path_parts['dirname'] ) . $path_parts['filename'] . '-scaled.' . $path_parts['extension']; | |
| 100 | + | |
| 101 | + return attachment_url_to_postid( $scaled_url ); | |
| 102 | + } | |
| 103 | + | |
| 104 | + return false; | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 83 | 108 | * Retrieves the image data. |
| 84 | 109 | * |
| 85 | 110 | * @param array $image Image array with URL and metadata. |
| 86 | 111 | * @param int $attachment_id Attachment ID. |
| 87 | 112 | * |
| 88 | - * @return false|array { | |
| 113 | + * @return array|false { | |
| 89 | 114 | * Array of image data |
| 90 | 115 | * |
| 91 | 116 | * @type string $alt Image's alt text. |
| 92 | 117 | * @type string $path Path of image. |
| @@ -120,9 +145,9 @@ | ||
| 120 | 145 | * Filter: 'wpseo_image_data' - Filter image data. |
| 121 | 146 | * |
| 122 | 147 | * Elements with keys not listed in the section will be discarded. |
| 123 | 148 | * |
| 124 | - * @api array { | |
| 149 | + * @param array $image_data { | |
| 125 | 150 | * Array of image data |
| 126 | 151 | * |
| 127 | 152 | * @type int id Image's ID as an attachment. |
| 128 | 153 | * @type string alt Image's alt text. |
| @@ -134,9 +159,9 @@ | ||
| 134 | 159 | * @type string size Image's size. |
| 135 | 160 | * @type string url Image's URL. |
| 136 | 161 | * @type int filesize The file size in bytes, if already set. |
| 137 | 162 | * } |
| 138 | - * @api int Attachment ID. | |
| 163 | + * @param int $attachment_id Attachment ID. | |
| 139 | 164 | */ |
| 140 | 165 | $image = apply_filters( 'wpseo_image_data', $image, $attachment_id ); |
| 141 | 166 | |
| 142 | 167 | // Keep only the keys we need, and nothing else. |
| @@ -158,11 +183,11 @@ | ||
| 158 | 183 | /** |
| 159 | 184 | * Filter: 'wpseo_image_image_weight_limit' - Determines what the maximum weight |
| 160 | 185 | * (in bytes) of an image is allowed to be, default is 2 MB. |
| 161 | 186 | * |
| 162 | - * @api int - The maximum weight (in bytes) of an image. | |
| 187 | + * @param int $max_bytes The maximum weight (in bytes) of an image. | |
| 163 | 188 | */ |
| 164 | - $max_size = apply_filters( 'wpseo_image_image_weight_limit', 2097152 ); | |
| 189 | + $max_size = apply_filters( 'wpseo_image_image_weight_limit', 2_097_152 ); | |
| 165 | 190 | |
| 166 | 191 | // We cannot check without a path, so assume it's fine. |
| 167 | 192 | if ( ! isset( $image['path'] ) ) { |
| 168 | 193 | return true; |
| @@ -173,10 +198,10 @@ | ||
| 173 | 198 | |
| 174 | 199 | /** |
| 175 | 200 | * Find the right version of an image based on size. |
| 176 | 201 | * |
| 177 | - * @param int $attachment_id Attachment ID. | |
| 178 | - * @param string $size Size name. | |
| 202 | + * @param int $attachment_id Attachment ID. | |
| 203 | + * @param string|array $size Size name, or array of width and height in pixels (e.g [800,400]). | |
| 179 | 204 | * |
| 180 | 205 | * @return array|false Returns an array with image data on success, false on failure. |
| 181 | 206 | */ |
| 182 | 207 | public static function get_image( $attachment_id, $size ) { |
| @@ -188,13 +213,26 @@ | ||
| 188 | 213 | if ( ! $image ) { |
| 189 | 214 | $image = image_get_intermediate_size( $attachment_id, $size ); |
| 190 | 215 | } |
| 191 | 216 | |
| 217 | + if ( ! is_array( $image ) ) { | |
| 218 | + $image_src = wp_get_attachment_image_src( $attachment_id, $size ); | |
| 219 | + if ( is_array( $image_src ) && isset( $image_src[1] ) && isset( $image_src[2] ) ) { | |
| 220 | + $image = []; | |
| 221 | + $image['url'] = $image_src[0]; | |
| 222 | + $image['width'] = $image_src[1]; | |
| 223 | + $image['height'] = $image_src[2]; | |
| 224 | + $image['size'] = 'full'; | |
| 225 | + } | |
| 226 | + } | |
| 227 | + | |
| 192 | 228 | if ( ! $image ) { |
| 193 | 229 | return false; |
| 194 | 230 | } |
| 195 | 231 | |
| 196 | - $image['size'] = $size; | |
| 232 | + if ( ! isset( $image['size'] ) ) { | |
| 233 | + $image['size'] = $size; | |
| 234 | + } | |
| 197 | 235 | |
| 198 | 236 | return self::get_data( $image, $attachment_id ); |
| 199 | 237 | } |
| 200 | 238 | |
| @@ -227,11 +265,9 @@ | ||
| 227 | 265 | */ |
| 228 | 266 | public static function get_absolute_path( $path ) { |
| 229 | 267 | static $uploads; |
| 230 | 268 | |
| 231 | - if ( $uploads === null ) { | |
| 232 | - $uploads = wp_get_upload_dir(); | |
| 233 | - } | |
| 269 | + $uploads ??= wp_get_upload_dir(); | |
| 234 | 270 | |
| 235 | 271 | // Add the uploads basedir if the path does not start with it. |
| 236 | 272 | if ( empty( $uploads['error'] ) && strpos( $path, $uploads['basedir'] ) !== 0 ) { |
| 237 | 273 | return $uploads['basedir'] . DIRECTORY_SEPARATOR . ltrim( $path, DIRECTORY_SEPARATOR ); |
| @@ -271,12 +307,18 @@ | ||
| 271 | 307 | if ( isset( $image['filesize'] ) ) { |
| 272 | 308 | return $image['filesize']; |
| 273 | 309 | } |
| 274 | 310 | |
| 311 | + if ( ! isset( $image['path'] ) ) { | |
| 312 | + return 0; | |
| 313 | + } | |
| 314 | + | |
| 275 | 315 | // If the file size for the file is over our limit, we're going to go for a smaller version. |
| 276 | - // @todo Save the filesize to the image metadata. | |
| 277 | - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- If file size doesn't properly return, we'll not fail. | |
| 278 | - return @filesize( self::get_absolute_path( $image['path'] ) ); | |
| 316 | + if ( function_exists( 'wp_filesize' ) ) { | |
| 317 | + return wp_filesize( self::get_absolute_path( $image['path'] ) ); | |
| 318 | + } | |
| 319 | + | |
| 320 | + return file_exists( $image['path'] ) ? (int) filesize( $image['path'] ) : 0; | |
| 279 | 321 | } |
| 280 | 322 | |
| 281 | 323 | /** |
| 282 | 324 | * Returns the different image variations for consideration. |
| @@ -357,9 +399,9 @@ | ||
| 357 | 399 | public static function get_sizes() { |
| 358 | 400 | /** |
| 359 | 401 | * Filter: 'wpseo_image_sizes' - Determines which image sizes we'll loop through to get an appropriate image. |
| 360 | 402 | * |
| 361 | - * @api array - The array of image sizes to loop through. | |
| 403 | + * @param array<string> $sizes The array of image sizes to loop through. | |
| 362 | 404 | */ |
| 363 | 405 | return apply_filters( 'wpseo_image_sizes', [ 'full', 'large', 'medium_large' ] ); |
| 364 | 406 | } |
| 365 | 407 | |
| @@ -449,16 +491,22 @@ | ||
| 449 | 491 | * @return int|bool The attachment id, or false or 0 if no ID is available. |
| 450 | 492 | */ |
| 451 | 493 | public static function get_attachment_id_from_settings( $setting ) { |
| 452 | 494 | $image_id = WPSEO_Options::get( $setting . '_id', false ); |
| 453 | - if ( ! $image_id ) { | |
| 454 | - $image = WPSEO_Options::get( $setting, false ); | |
| 455 | - if ( $image ) { | |
| 456 | - // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. | |
| 457 | - // This means an attachment always exists, so doing this is only needed once. | |
| 458 | - $image_id = self::get_attachment_by_url( $image ); | |
| 459 | - WPSEO_Options::set( $setting . '_id', $image_id ); | |
| 460 | - } | |
| 495 | + if ( $image_id ) { | |
| 496 | + return $image_id; | |
| 497 | + } | |
| 498 | + | |
| 499 | + $image = WPSEO_Options::get( $setting, false ); | |
| 500 | + if ( $image ) { | |
| 501 | + // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. | |
| 502 | + // This means an attachment always exists, so doing this is only needed once. | |
| 503 | + $image_id = self::get_attachment_by_url( $image ); | |
| 504 | + } | |
| 505 | + | |
| 506 | + // Only store a new ID if it is not 0, to prevent an update loop. | |
| 507 | + if ( $image_id ) { | |
| 508 | + WPSEO_Options::set( $setting . '_id', $image_id ); | |
| 461 | 509 | } |
| 462 | 510 | |
| 463 | 511 | return $image_id; |
| 464 | 512 | } |