| @@ -2,9 +2,11 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace Yoast\WP\SEO\Helpers; |
| 4 | 4 | |
| 5 | 5 | use WPSEO_Image_Utils; |
| 6 | +use Yoast\WP\SEO\Models\SEO_Links; | |
| 6 | 7 | use Yoast\WP\SEO\Repositories\Indexable_Repository; |
| 8 | +use Yoast\WP\SEO\Repositories\SEO_Links_Repository; | |
| 7 | 9 | |
| 8 | 10 | /** |
| 9 | 11 | * A helper object for images. |
| 10 | 12 | */ |
| @@ -14,9 +16,9 @@ | ||
| 14 | 16 | * Image types that are supported by Open Graph. |
| 15 | 17 | * |
| 16 | 18 | * @var array |
| 17 | 19 | */ |
| 18 | - protected static $valid_image_types = [ 'image/jpeg', 'image/gif', 'image/png' ]; | |
| 20 | + protected static $valid_image_types = [ 'image/jpeg', 'image/gif', 'image/png', 'image/webp' ]; | |
| 19 | 21 | |
| 20 | 22 | /** |
| 21 | 23 | * Image extensions that are supported by Open Graph. |
| 22 | 24 | * |
| @@ -21,9 +23,9 @@ | ||
| 21 | 23 | * Image extensions that are supported by Open Graph. |
| 22 | 24 | * |
| 23 | 25 | * @var array |
| 24 | 26 | */ |
| 25 | - protected static $valid_image_extensions = [ 'jpeg', 'jpg', 'gif', 'png' ]; | |
| 27 | + protected static $valid_image_extensions = [ 'jpeg', 'jpg', 'gif', 'png', 'webp' ]; | |
| 26 | 28 | |
| 27 | 29 | /** |
| 28 | 30 | * Represents the indexables repository. |
| 29 | 31 | * |
| @@ -31,23 +33,46 @@ | ||
| 31 | 33 | */ |
| 32 | 34 | protected $indexable_repository; |
| 33 | 35 | |
| 34 | 36 | /** |
| 37 | + * Represents the SEO Links repository. | |
| 38 | + * | |
| 39 | + * @var SEO_Links_Repository | |
| 40 | + */ | |
| 41 | + protected $seo_links_repository; | |
| 42 | + | |
| 43 | + /** | |
| 35 | 44 | * The options helper. |
| 36 | 45 | * |
| 37 | 46 | * @var Options_Helper |
| 38 | 47 | */ |
| 39 | - private $options; | |
| 48 | + private $options_helper; | |
| 40 | 49 | |
| 41 | 50 | /** |
| 51 | + * The URL helper. | |
| 52 | + * | |
| 53 | + * @var Url_Helper | |
| 54 | + */ | |
| 55 | + private $url_helper; | |
| 56 | + | |
| 57 | + /** | |
| 42 | 58 | * Image_Helper constructor. |
| 43 | 59 | * |
| 44 | 60 | * @param Indexable_Repository $indexable_repository The indexable repository. |
| 61 | + * @param SEO_Links_Repository $seo_links_repository The SEO Links repository. | |
| 45 | 62 | * @param Options_Helper $options The options helper. |
| 63 | + * @param Url_Helper $url_helper The URL helper. | |
| 46 | 64 | */ |
| 47 | - public function __construct( Indexable_Repository $indexable_repository, Options_Helper $options ) { | |
| 65 | + public function __construct( | |
| 66 | + Indexable_Repository $indexable_repository, | |
| 67 | + SEO_Links_Repository $seo_links_repository, | |
| 68 | + Options_Helper $options, | |
| 69 | + Url_Helper $url_helper | |
| 70 | + ) { | |
| 48 | 71 | $this->indexable_repository = $indexable_repository; |
| 49 | - $this->options = $options; | |
| 72 | + $this->seo_links_repository = $seo_links_repository; | |
| 73 | + $this->options_helper = $options; | |
| 74 | + $this->url_helper = $url_helper; | |
| 50 | 75 | } |
| 51 | 76 | |
| 52 | 77 | /** |
| 53 | 78 | * Determines whether or not the wanted attachment is considered valid. |
| @@ -271,35 +296,58 @@ | ||
| 271 | 296 | |
| 272 | 297 | /** |
| 273 | 298 | * Find an attachment ID for a given URL. |
| 274 | 299 | * |
| 275 | - * @param string $url The URL to find the attachment for. | |
| 300 | + * @param string $url The URL to find the attachment for. | |
| 301 | + * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. | |
| 276 | 302 | * |
| 277 | 303 | * @return int The found attachment ID, or 0 if none was found. |
| 278 | 304 | */ |
| 279 | - public function get_attachment_by_url( $url ) { | |
| 280 | - // Strip out the size part of an image URL. | |
| 281 | - $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); | |
| 282 | - | |
| 305 | + public function get_attachment_by_url( $url, $use_link_table = true ) { | |
| 283 | 306 | // Don't try to do this for external URLs. |
| 284 | - if ( \strpos( $url, \get_site_url() ) !== 0 ) { | |
| 307 | + $parsed_url = \wp_parse_url( $url ); | |
| 308 | + if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { | |
| 285 | 309 | return 0; |
| 286 | 310 | } |
| 287 | 311 | |
| 288 | - $indexable = $this->indexable_repository->find_by_permalink( $url ); | |
| 312 | + /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ | |
| 313 | + if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { | |
| 314 | + // Strip out the size part of an image URL. | |
| 315 | + $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); | |
| 289 | 316 | |
| 290 | - if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { | |
| 291 | - return $indexable->object_id; | |
| 317 | + $indexable = $this->indexable_repository->find_by_permalink( $url ); | |
| 318 | + | |
| 319 | + if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { | |
| 320 | + return $indexable->object_id; | |
| 321 | + } | |
| 322 | + | |
| 323 | + $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); | |
| 324 | + | |
| 325 | + if ( $post_id !== 0 ) { | |
| 326 | + // Find the indexable, this triggers creating it so it can be found next time. | |
| 327 | + $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); | |
| 328 | + } | |
| 329 | + | |
| 330 | + return $post_id; | |
| 292 | 331 | } |
| 293 | 332 | |
| 294 | - $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); | |
| 333 | + if ( ! $use_link_table ) { | |
| 334 | + return WPSEO_Image_Utils::get_attachment_by_url( $url ); | |
| 335 | + } | |
| 336 | + $cache_key = 'attachment_seo_link_object_' . \md5( $url ); | |
| 295 | 337 | |
| 296 | - if ( $post_id !== 0 ) { | |
| 297 | - // Find the indexable, this triggers creating it so it can be found next time. | |
| 298 | - $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); | |
| 338 | + $found = false; | |
| 339 | + $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); | |
| 340 | + | |
| 341 | + if ( $found === false ) { | |
| 342 | + $link = $this->seo_links_repository->find_one_by_url( $url ); | |
| 343 | + \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); | |
| 299 | 344 | } |
| 345 | + if ( ! \is_a( $link, SEO_Links::class ) ) { | |
| 346 | + return WPSEO_Image_Utils::get_attachment_by_url( $url ); | |
| 347 | + } | |
| 300 | 348 | |
| 301 | - return $post_id; | |
| 349 | + return $link->target_post_id; | |
| 302 | 350 | } |
| 303 | 351 | |
| 304 | 352 | /** |
| 305 | 353 | * Retrieves an attachment ID for an image uploaded in the settings. |
| @@ -317,9 +365,10 @@ | ||
| 317 | 365 | return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); |
| 318 | 366 | } |
| 319 | 367 | |
| 320 | 368 | /** |
| 321 | - * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it to an option. | |
| 369 | + * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it | |
| 370 | + * to an option. | |
| 322 | 371 | * |
| 323 | 372 | * @param string $setting The setting name. Should be company or person. |
| 324 | 373 | * |
| 325 | 374 | * @return array|bool Array with image details when the image is found, boolean when it's not found. |
| @@ -324,17 +373,17 @@ | ||
| 324 | 373 | * |
| 325 | 374 | * @return array|bool Array with image details when the image is found, boolean when it's not found. |
| 326 | 375 | */ |
| 327 | 376 | public function get_attachment_meta_from_settings( $setting ) { |
| 328 | - $image_meta = $this->options->get( $setting . '_meta', false ); | |
| 377 | + $image_meta = $this->options_helper->get( $setting . '_meta', false ); | |
| 329 | 378 | if ( ! $image_meta ) { |
| 330 | - $image_id = $this->options->get( $setting . '_id', false ); | |
| 379 | + $image_id = $this->options_helper->get( $setting . '_id', false ); | |
| 331 | 380 | if ( $image_id ) { |
| 332 | 381 | // 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. |
| 333 | 382 | // This means an attachment always exists, so doing this is only needed once. |
| 334 | 383 | $image_meta = $this->get_best_attachment_variation( $image_id ); |
| 335 | 384 | if ( $image_meta ) { |
| 336 | - $this->options->set( $setting . '_meta', $image_meta ); | |
| 385 | + $this->options_helper->set( $setting . '_meta', $image_meta ); | |
| 337 | 386 | } |
| 338 | 387 | } |
| 339 | 388 | } |
| 340 | 389 | |