PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
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/indexable-to-postmeta-helper.php +134 -20 18.1 → trunk View file →
@@ -5,9 +5,8 @@
5 5 use Yoast\WP\SEO\Models\Indexable;
6 6
7 7 /**
8 8 * A helper object to map indexable data to postmeta.
9 - * @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
10 9 */
11 10 class Indexable_To_Postmeta_Helper {
12 11
13 12 /**
@@ -54,8 +53,24 @@
54 53 'primary_focus_keyword' => [
55 54 'post_meta_key' => 'focuskw',
56 55 'map_method' => 'simple_map',
57 56 ],
57 + 'open_graph_image' => [
58 + 'post_meta_key' => 'opengraph-image',
59 + 'map_method' => 'social_image_map',
60 + ],
61 + 'open_graph_image_id' => [
62 + 'post_meta_key' => 'opengraph-image-id',
63 + 'map_method' => 'social_image_map',
64 + ],
65 + 'twitter_image' => [
66 + 'post_meta_key' => 'twitter-image',
67 + 'map_method' => 'social_image_map',
68 + ],
69 + 'twitter_image_id' => [
70 + 'post_meta_key' => 'twitter-image-id',
71 + 'map_method' => 'social_image_map',
72 + ],
58 73 'is_robots_noindex' => [
59 74 'post_meta_key' => 'meta-robots-noindex',
60 75 'map_method' => 'noindex_map',
61 76 ],
@@ -66,8 +81,20 @@
66 81 'meta_robots_adv' => [
67 82 'post_meta_key' => 'meta-robots-adv',
68 83 'map_method' => 'robots_adv_map',
69 84 ],
85 + 'is_cornerstone' => [
86 + 'post_meta_key' => 'is_cornerstone',
87 + 'map_method' => 'cornerstone_map',
88 + ],
89 + 'schema_page_type' => [
90 + 'post_meta_key' => 'schema_page_type',
91 + 'map_method' => 'simple_map',
92 + ],
93 + 'schema_article_type' => [
94 + 'post_meta_key' => 'schema_article_type',
95 + 'map_method' => 'simple_map',
96 + ],
70 97 ];
71 98
72 99 /**
73 100 * Indexable_To_Postmeta_Helper constructor.
@@ -80,45 +107,132 @@
80 107
81 108 /**
82 109 * Creates postmeta from a Yoast indexable.
83 110 *
84 - * @param Indexable $indexable The Yoast indexable.
111 + * @param Indexable $indexable The Yoast indexable.
112 + * @param bool $delete_empty Whether an empty indexable value should delete the post meta
113 + * instead of being left untouched. Defaults to false so importers,
114 + * which only fill in missing data, keep their set-only behaviour.
85 115 *
86 - * @return void.
116 + * @return void
87 117 */
88 - public function map_to_postmeta( $indexable ) {
89 - foreach ( $this->yoast_to_postmeta as $indexable_column => $map_info ) {
90 - \call_user_func( [ $this, $map_info['map_method'] ], $indexable, $map_info['post_meta_key'], $indexable_column );
118 + public function map_to_postmeta( $indexable, $delete_empty = false ) {
119 + foreach ( \array_keys( $this->yoast_to_postmeta ) as $indexable_column ) {
120 + $this->map_column_to_postmeta( $indexable, $indexable_column, $delete_empty );
91 121 }
92 122 }
93 123
94 124 /**
125 + * Creates postmeta from a single indexable column.
126 + *
127 + * @param Indexable $indexable The Yoast indexable.
128 + * @param string $indexable_column The indexable column to map.
129 + * @param bool $delete_empty Whether an empty value should delete the post meta key.
130 + *
131 + * @return void
132 + */
133 + public function map_column_to_postmeta( $indexable, $indexable_column, $delete_empty = false ) {
134 + // The advanced-robots flags are persisted together under one meta key, so they cascade through it.
135 + if ( \in_array( $indexable_column, [ 'is_robots_noimageindex', 'is_robots_noarchive', 'is_robots_nosnippet' ], true ) ) {
136 + $indexable_column = 'meta_robots_adv';
137 + }
138 +
139 + if ( ! isset( $this->yoast_to_postmeta[ $indexable_column ] ) ) {
140 + return;
141 + }
142 +
143 + $map_info = $this->yoast_to_postmeta[ $indexable_column ];
144 + \call_user_func( [ $this, $map_info['map_method'] ], $indexable, $map_info['post_meta_key'], $indexable_column, $delete_empty );
145 + }
146 +
147 + /**
95 148 * Uses a simple set_value for non-empty data.
96 149 *
97 150 * @param Indexable $indexable The Yoast indexable.
98 151 * @param string $post_meta_key The post_meta key that will be populated.
99 152 * @param string $indexable_column The indexable data that will be mapped to post_meta.
153 + * @param bool $delete_empty Whether an empty value should delete the post meta key.
100 154 *
101 - * @return void.
155 + * @return void
102 156 */
103 - public function simple_map( $indexable, $post_meta_key, $indexable_column ) {
157 + public function simple_map( $indexable, $post_meta_key, $indexable_column, $delete_empty = false ) {
158 + $value = $indexable->{$indexable_column};
159 +
160 + // Strict emptiness check because empty() would treat the literal string '0' as empty and drop it.
161 + if ( $value === null || $value === '' ) {
162 + if ( $delete_empty ) {
163 + $this->meta->delete( $post_meta_key, $indexable->object_id );
164 + }
165 + return;
166 + }
167 +
168 + $this->meta->set_value( $post_meta_key, $value, $indexable->object_id );
169 + }
170 +
171 + /**
172 + * Maps the cornerstone flag, which is stored as '1' when on and absent when off.
173 + *
174 + * @param Indexable $indexable The Yoast indexable.
175 + * @param string $post_meta_key The post_meta key that will be populated.
176 + * @param string $indexable_column The indexable data that will be mapped to post_meta.
177 + * @param bool $delete_empty Whether a disabled flag should delete the post meta key.
178 + *
179 + * @return void
180 + */
181 + public function cornerstone_map( $indexable, $post_meta_key, $indexable_column, $delete_empty = false ) {
182 + if ( $indexable->is_cornerstone === true ) {
183 + $this->meta->set_value( $post_meta_key, '1', $indexable->object_id );
184 + return;
185 + }
186 +
187 + if ( $delete_empty ) {
188 + $this->meta->delete( $post_meta_key, $indexable->object_id );
189 + }
190 + }
191 +
192 + /**
193 + * Map social image data only if social image is explicitly set.
194 + *
195 + * @param Indexable $indexable The Yoast indexable.
196 + * @param string $post_meta_key The post_meta key that will be populated.
197 + * @param string $indexable_column The indexable data that will be mapped to post_meta.
198 + *
199 + * @return void
200 + */
201 + public function social_image_map( $indexable, $post_meta_key, $indexable_column ) {
104 202 if ( empty( $indexable->{$indexable_column} ) ) {
105 203 return;
106 204 }
107 205
108 - $this->meta->set_value( $post_meta_key, $indexable->{$indexable_column}, $indexable->object_id );
206 + switch ( $indexable_column ) {
207 + case 'open_graph_image':
208 + case 'open_graph_image_id':
209 + $source = $indexable->open_graph_image_source;
210 + break;
211 + case 'twitter_image':
212 + case 'twitter_image_id':
213 + $source = $indexable->twitter_image_source;
214 + break;
215 + }
216 +
217 + // Map the social image data only when the social image is explicitly set.
218 + if ( $source === 'set-by-user' || $source === 'imported' ) {
219 + $value = (string) $indexable->{$indexable_column};
220 +
221 + $this->meta->set_value( $post_meta_key, $value, $indexable->object_id );
222 + }
109 223 }
110 224
111 225 /**
112 226 * Deletes the noindex post_meta key if no noindex in the indexable. Populates the post_meta key appropriately if there is noindex in the indexable.
113 227 *
114 - * @param Indexable $indexable The Yoast indexable.
115 - * @param string $post_meta_key The post_meta key that will be populated.
228 + * @param Indexable $indexable The Yoast indexable.
229 + * @param string $post_meta_key The post_meta key that will be populated.
116 230 *
117 - * @return void.
231 + * @return void
118 232 */
119 233 public function noindex_map( $indexable, $post_meta_key ) {
120 - if ( \is_null( $indexable->is_robots_noindex ) ) {
234 + if ( $indexable->is_robots_noindex === null ) {
121 235 $this->meta->delete( $post_meta_key, $indexable->object_id );
122 236 return;
123 237 }
124 238
@@ -133,15 +247,15 @@
133 247
134 248 /**
135 249 * Deletes the nofollow post_meta key if no nofollow in the indexable or if nofollow is false. Populates the post_meta key appropriately if there is a true nofollow in the indexable.
136 250 *
137 - * @param Indexable $indexable The Yoast indexable.
138 - * @param string $post_meta_key The post_meta key that will be populated.
251 + * @param Indexable $indexable The Yoast indexable.
252 + * @param string $post_meta_key The post_meta key that will be populated.
139 253 *
140 - * @return void.
254 + * @return void
141 255 */
142 256 public function nofollow_map( $indexable, $post_meta_key ) {
143 - if ( \is_null( $indexable->is_robots_nofollow ) || $indexable->is_robots_nofollow === false ) {
257 + if ( $indexable->is_robots_nofollow === null || $indexable->is_robots_nofollow === false ) {
144 258 $this->meta->delete( $post_meta_key, $indexable->object_id );
145 259 }
146 260
147 261 if ( $indexable->is_robots_nofollow === true ) {
@@ -151,12 +265,12 @@
151 265
152 266 /**
153 267 * Deletes the nofollow post_meta key if no nofollow in the indexable or if nofollow is false. Populates the post_meta key appropriately if there is a true nofollow in the indexable.
154 268 *
155 - * @param Indexable $indexable The Yoast indexable.
156 - * @param string $post_meta_key The post_meta key that will be populated.
269 + * @param Indexable $indexable The Yoast indexable.
270 + * @param string $post_meta_key The post_meta key that will be populated.
157 271 *
158 - * @return void.
272 + * @return void
159 273 */
160 274 public function robots_adv_map( $indexable, $post_meta_key ) {
161 275 $adv_settings_to_be_imported = [];
162 276 $no_adv_settings = true;