PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
← All changes | src/helpers/image-helper.php +52 -17 18.428.5 View file →
@@ -4,8 +4,9 @@
4 4
5 5 use WPSEO_Image_Utils;
6 6 use Yoast\WP\SEO\Models\SEO_Links;
7 7 use Yoast\WP\SEO\Repositories\Indexable_Repository;
8 +use Yoast\WP\SEO\Repositories\SEO_Links_Repository;
8 9
9 10 /**
10 11 * A helper object for images.
11 12 */
@@ -15,9 +16,9 @@
15 16 * Image types that are supported by Open Graph.
16 17 *
17 18 * @var array
18 19 */
19 - 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' ];
20 21
21 22 /**
22 23 * Image extensions that are supported by Open Graph.
23 24 *
@@ -22,9 +23,9 @@
22 23 * Image extensions that are supported by Open Graph.
23 24 *
24 25 * @var array
25 26 */
26 - protected static $valid_image_extensions = [ 'jpeg', 'jpg', 'gif', 'png' ];
27 + protected static $valid_image_extensions = [ 'jpeg', 'jpg', 'gif', 'png', 'webp' ];
27 28
28 29 /**
29 30 * Represents the indexables repository.
30 31 *
@@ -32,8 +33,15 @@
32 33 */
33 34 protected $indexable_repository;
34 35
35 36 /**
37 + * Represents the SEO Links repository.
38 + *
39 + * @var SEO_Links_Repository
40 + */
41 + protected $seo_links_repository;
42 +
43 + /**
36 44 * The options helper.
37 45 *
38 46 * @var Options_Helper
39 47 */
@@ -49,17 +57,20 @@
49 57 /**
50 58 * Image_Helper constructor.
51 59 *
52 60 * @param Indexable_Repository $indexable_repository The indexable repository.
61 + * @param SEO_Links_Repository $seo_links_repository The SEO Links repository.
53 62 * @param Options_Helper $options The options helper.
54 63 * @param Url_Helper $url_helper The URL helper.
55 64 */
56 65 public function __construct(
57 66 Indexable_Repository $indexable_repository,
67 + SEO_Links_Repository $seo_links_repository,
58 68 Options_Helper $options,
59 69 Url_Helper $url_helper
60 70 ) {
61 71 $this->indexable_repository = $indexable_repository;
72 + $this->seo_links_repository = $seo_links_repository;
62 73 $this->options_helper = $options;
63 74 $this->url_helper = $url_helper;
64 75 }
65 76
@@ -285,35 +296,58 @@
285 296
286 297 /**
287 298 * Find an attachment ID for a given URL.
288 299 *
289 - * @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.
290 302 *
291 303 * @return int The found attachment ID, or 0 if none was found.
292 304 */
293 - public function get_attachment_by_url( $url ) {
294 - // Strip out the size part of an image URL.
295 - $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url );
296 -
305 + public function get_attachment_by_url( $url, $use_link_table = true ) {
297 306 // Don't try to do this for external URLs.
298 - if ( $this->url_helper->get_link_type( $url ) === SEO_Links::TYPE_EXTERNAL ) {
307 + $parsed_url = \wp_parse_url( $url );
308 + if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) {
299 309 return 0;
300 310 }
301 311
302 - $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 );
303 316
304 - if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) {
305 - 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;
306 331 }
307 332
308 - $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 );
309 337
310 - if ( $post_id !== 0 ) {
311 - // Find the indexable, this triggers creating it so it can be found next time.
312 - $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 );
313 344 }
345 + if ( ! \is_a( $link, SEO_Links::class ) ) {
346 + return WPSEO_Image_Utils::get_attachment_by_url( $url );
347 + }
314 348
315 - return $post_id;
349 + return $link->target_post_id;
316 350 }
317 351
318 352 /**
319 353 * Retrieves an attachment ID for an image uploaded in the settings.
@@ -331,9 +365,10 @@
331 365 return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting );
332 366 }
333 367
334 368 /**
335 - * 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.
336 371 *
337 372 * @param string $setting The setting name. Should be company or person.
338 373 *
339 374 * @return array|bool Array with image details when the image is found, boolean when it's not found.