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/builders/indexable-post-builder.php +62 -49 18.228.5 View file →
@@ -1,12 +1,13 @@
1 1 <?php
2 2
3 3 namespace Yoast\WP\SEO\Builders;
4 4
5 -use WP_Error;
6 5 use WP_Post;
7 -use WPSEO_Meta;
6 +use Yoast\WP\SEO\Exceptions\Indexable\Post_Not_Built_Exception;
8 7 use Yoast\WP\SEO\Exceptions\Indexable\Post_Not_Found_Exception;
8 +use Yoast\WP\SEO\Helpers\Meta_Helper;
9 +use Yoast\WP\SEO\Helpers\Permalink_Helper;
9 10 use Yoast\WP\SEO\Helpers\Post_Helper;
10 11 use Yoast\WP\SEO\Helpers\Post_Type_Helper;
11 12 use Yoast\WP\SEO\Models\Indexable;
12 13 use Yoast\WP\SEO\Repositories\Indexable_Repository;
@@ -42,8 +43,15 @@
42 43 */
43 44 protected $post_type_helper;
44 45
45 46 /**
47 + * The permalink helper.
48 + *
49 + * @var Permalink_Helper
50 + */
51 + protected $permalink_helper;
52 +
53 + /**
46 54 * Knows the latest version of the Indexable post builder type.
47 55 *
48 56 * @var int
49 57 */
@@ -49,22 +57,35 @@
49 57 */
50 58 protected $version;
51 59
52 60 /**
61 + * The meta helper.
62 + *
63 + * @var Meta_Helper
64 + */
65 + protected $meta;
66 +
67 + /**
53 68 * Indexable_Post_Builder constructor.
54 69 *
55 70 * @param Post_Helper $post_helper The post helper.
56 71 * @param Post_Type_Helper $post_type_helper The post type helper.
57 72 * @param Indexable_Builder_Versions $versions The indexable builder versions.
73 + * @param Meta_Helper $meta The meta helper.
74 + * @param Permalink_Helper $permalink_helper The permalink helper.
58 75 */
59 76 public function __construct(
60 77 Post_Helper $post_helper,
61 78 Post_Type_Helper $post_type_helper,
62 - Indexable_Builder_Versions $versions
79 + Indexable_Builder_Versions $versions,
80 + Meta_Helper $meta,
81 + Permalink_Helper $permalink_helper
63 82 ) {
64 83 $this->post_helper = $post_helper;
65 84 $this->post_type_helper = $post_type_helper;
66 85 $this->version = $versions->get_latest_version_for_type( 'post' );
86 + $this->meta = $meta;
87 + $this->permalink_helper = $permalink_helper;
67 88 }
68 89
69 90 /**
70 91 * Sets the indexable repository. Done to avoid circular dependencies.
@@ -71,8 +92,10 @@
71 92 *
72 93 * @required
73 94 *
74 95 * @param Indexable_Repository $indexable_repository The indexable repository.
96 + *
97 + * @return void
75 98 */
76 99 public function set_indexable_repository( Indexable_Repository $indexable_repository ) {
77 100 $this->indexable_repository = $indexable_repository;
78 101 }
@@ -85,12 +108,13 @@
85 108 *
86 109 * @return bool|Indexable The extended indexable. False when unable to build.
87 110 *
88 111 * @throws Post_Not_Found_Exception When the post could not be found.
112 + * @throws Post_Not_Built_Exception When the post should not be indexed.
89 113 */
90 114 public function build( $post_id, $indexable ) {
91 115 if ( ! $this->post_helper->is_post_indexable( $post_id ) ) {
92 - return false;
116 + throw Post_Not_Built_Exception::because_not_indexable( $post_id );
93 117 }
94 118
95 119 $post = $this->post_helper->get_post( $post_id );
96 120
@@ -98,32 +122,39 @@
98 122 throw new Post_Not_Found_Exception();
99 123 }
100 124
101 125 if ( $this->should_exclude_post( $post ) ) {
102 - return false;
126 + throw Post_Not_Built_Exception::because_post_type_excluded( $post_id );
103 127 }
104 128
105 129 $indexable->object_id = $post_id;
106 130 $indexable->object_type = 'post';
107 131 $indexable->object_sub_type = $post->post_type;
108 - $indexable->permalink = $this->get_permalink( $post->post_type, $post_id );
132 + $indexable->permalink = $this->permalink_helper->get_permalink_for_post( $post->post_type, $post_id );
109 133
110 134 $indexable->primary_focus_keyword_score = $this->get_keyword_score(
111 - $this->get_meta_value( $post_id, 'focuskw' ),
112 - (int) $this->get_meta_value( $post_id, 'linkdex' )
135 + $this->meta->get_value( 'focuskw', $post_id ),
136 + (int) $this->meta->get_value( 'linkdex', $post_id ),
113 137 );
114 138
115 - $indexable->readability_score = (int) $this->get_meta_value( $post_id, 'content_score' );
139 + $indexable->readability_score = (int) $this->meta->get_value( 'content_score', $post_id );
116 140
117 - $indexable->is_cornerstone = ( $this->get_meta_value( $post_id, 'is_cornerstone' ) === '1' );
141 + $indexable->inclusive_language_score = (int) $this->meta->get_value( 'inclusive_language_score', $post_id );
142 +
143 + $indexable->seo_title_score = (int) $this->meta->get_value( 'seo_title_score', $post_id );
144 +
145 + $indexable->meta_description_score = (int) $this->meta->get_value( 'meta_description_score', $post_id );
146 +
147 + $indexable->is_cornerstone = ( $this->meta->get_value( 'is_cornerstone', $post_id ) === '1' );
118 148 $indexable->is_robots_noindex = $this->get_robots_noindex(
119 - $this->get_meta_value( $post_id, 'meta-robots-noindex' )
149 + (int) $this->meta->get_value( 'meta-robots-noindex', $post_id ),
120 150 );
121 151
122 152 // Set additional meta-robots values.
123 - $indexable->is_robots_nofollow = ( $this->get_meta_value( $post_id, 'meta-robots-nofollow' ) === '1' );
124 - $noindex_advanced = $this->get_meta_value( $post_id, 'meta-robots-adv' );
153 + $indexable->is_robots_nofollow = ( $this->meta->get_value( 'meta-robots-nofollow', $post_id ) === '1' );
154 + $noindex_advanced = $this->meta->get_value( 'meta-robots-adv', $post_id );
125 155 $meta_robots = \explode( ',', $noindex_advanced );
156 +
126 157 foreach ( $this->get_robots_options() as $meta_robots_option ) {
127 158 $indexable->{'is_robots_' . $meta_robots_option} = \in_array( $meta_robots_option, $meta_robots, true ) ? 1 : null;
128 159 }
129 160
@@ -129,9 +160,9 @@
129 160
130 161 $this->reset_social_images( $indexable );
131 162
132 163 foreach ( $this->get_indexable_lookup() as $meta_key => $indexable_key ) {
133 - $indexable->{$indexable_key} = $this->get_meta_value( $post_id, $meta_key );
164 + $indexable->{$indexable_key} = $this->empty_string_to_null( $this->meta->get_value( $meta_key, $post_id ) );
134 165 }
135 166
136 167 if ( empty( $indexable->breadcrumb_title ) ) {
137 168 $indexable->breadcrumb_title = \wp_strip_all_tags( \get_the_title( $post_id ), true );
@@ -148,10 +179,10 @@
148 179 $indexable->is_public = $this->is_public( $indexable );
149 180 $indexable->has_public_posts = $this->has_public_posts( $indexable );
150 181 $indexable->blog_id = \get_current_blog_id();
151 182
152 - $indexable->schema_page_type = $this->get_meta_value( $post_id, 'schema_page_type' );
153 - $indexable->schema_article_type = $this->get_meta_value( $post_id, 'schema_article_type' );
183 + $indexable->schema_page_type = $this->empty_string_to_null( $this->meta->get_value( 'schema_page_type', $post_id ) );
184 + $indexable->schema_article_type = $this->empty_string_to_null( $this->meta->get_value( 'schema_article_type', $post_id ) );
154 185
155 186 $indexable->object_last_modified = $post->post_modified_gmt;
156 187 $indexable->object_published_at = $post->post_date_gmt;
157 188
@@ -160,24 +191,8 @@
160 191 return $indexable;
161 192 }
162 193
163 194 /**
164 - * Retrieves the permalink for a post with the given post type and ID.
165 - *
166 - * @param string $post_type The post type.
167 - * @param int $post_id The post ID.
168 - *
169 - * @return false|string|WP_Error The permalink.
170 - */
171 - protected function get_permalink( $post_type, $post_id ) {
172 - if ( $post_type !== 'attachment' ) {
173 - return \get_permalink( $post_id );
174 - }
175 -
176 - return \wp_get_attachment_url( $post_id );
177 - }
178 -
179 - /**
180 195 * Determines the value of is_public.
181 196 *
182 197 * @param Indexable $indexable The indexable.
183 198 *
@@ -326,25 +341,8 @@
326 341 ];
327 342 }
328 343
329 344 /**
330 - * Retrieves the current value for the meta field.
331 - *
332 - * @param int $post_id The post ID to use.
333 - * @param string $meta_key Meta key to fetch.
334 - *
335 - * @return mixed The value of the indexable entry to use.
336 - */
337 - protected function get_meta_value( $post_id, $meta_key ) {
338 - $value = WPSEO_Meta::get_value( $meta_key, $post_id );
339 - if ( \is_string( $value ) && $value === '' ) {
340 - return null;
341 - }
342 -
343 - return $value;
344 - }
345 -
346 - /**
347 345 * Finds an alternative image for the social image.
348 346 *
349 347 * @param Indexable $indexable The indexable.
350 348 *
@@ -413,6 +411,21 @@
413 411 * @return bool `true` if the post should be excluded from building, `false` if not.
414 412 */
415 413 protected function should_exclude_post( $post ) {
416 414 return $this->post_type_helper->is_excluded( $post->post_type );
415 + }
416 +
417 + /**
418 + * Transforms an empty string into null. Leaves non-empty strings intact.
419 + *
420 + * @param string $text The string.
421 + *
422 + * @return string|null The input string or null.
423 + */
424 + protected function empty_string_to_null( $text ) {
425 + if ( ! \is_string( $text ) || $text === '' ) {
426 + return null;
427 + }
428 +
429 + return $text;
417 430 }
418 431 }