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
wordpress-seo / src / helpers / indexable-to-postmeta-helper.php

indexable-to-postmeta-helper.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at src/helpers/indexable-to-postmeta-helper.php

299 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Helpers;
4
5 use Yoast\WP\SEO\Models\Indexable;
6
7 /**
8 * A helper object to map indexable data to postmeta.
9 */
10 class Indexable_To_Postmeta_Helper {
11
12 /**
13 * The Meta helper.
14 *
15 * @var Meta_Helper
16 */
17 public $meta;
18
19 /**
20 * The map of yoast to post meta.
21 *
22 * @var array
23 */
24 protected $yoast_to_postmeta = [
25 'title' => [
26 'post_meta_key' => 'title',
27 'map_method' => 'simple_map',
28 ],
29 'description' => [
30 'post_meta_key' => 'metadesc',
31 'map_method' => 'simple_map',
32 ],
33 'open_graph_title' => [
34 'post_meta_key' => 'opengraph-title',
35 'map_method' => 'simple_map',
36 ],
37 'open_graph_description' => [
38 'post_meta_key' => 'opengraph-description',
39 'map_method' => 'simple_map',
40 ],
41 'twitter_title' => [
42 'post_meta_key' => 'twitter-title',
43 'map_method' => 'simple_map',
44 ],
45 'twitter_description' => [
46 'post_meta_key' => 'twitter-description',
47 'map_method' => 'simple_map',
48 ],
49 'canonical' => [
50 'post_meta_key' => 'canonical',
51 'map_method' => 'simple_map',
52 ],
53 'primary_focus_keyword' => [
54 'post_meta_key' => 'focuskw',
55 'map_method' => 'simple_map',
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 ],
73 'is_robots_noindex' => [
74 'post_meta_key' => 'meta-robots-noindex',
75 'map_method' => 'noindex_map',
76 ],
77 'is_robots_nofollow' => [
78 'post_meta_key' => 'meta-robots-nofollow',
79 'map_method' => 'nofollow_map',
80 ],
81 'meta_robots_adv' => [
82 'post_meta_key' => 'meta-robots-adv',
83 'map_method' => 'robots_adv_map',
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 ],
97 ];
98
99 /**
100 * Indexable_To_Postmeta_Helper constructor.
101 *
102 * @param Meta_Helper $meta The Meta helper.
103 */
104 public function __construct( Meta_Helper $meta ) {
105 $this->meta = $meta;
106 }
107
108 /**
109 * Creates postmeta from a Yoast indexable.
110 *
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.
115 *
116 * @return void
117 */
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 );
121 }
122 }
123
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 /**
148 * Uses a simple set_value for non-empty data.
149 *
150 * @param Indexable $indexable The Yoast indexable.
151 * @param string $post_meta_key The post_meta key that will be populated.
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.
154 *
155 * @return void
156 */
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 ) {
202 if ( empty( $indexable->{$indexable_column} ) ) {
203 return;
204 }
205
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 }
223 }
224
225 /**
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.
227 *
228 * @param Indexable $indexable The Yoast indexable.
229 * @param string $post_meta_key The post_meta key that will be populated.
230 *
231 * @return void
232 */
233 public function noindex_map( $indexable, $post_meta_key ) {
234 if ( $indexable->is_robots_noindex === null ) {
235 $this->meta->delete( $post_meta_key, $indexable->object_id );
236 return;
237 }
238
239 if ( $indexable->is_robots_noindex === false ) {
240 $this->meta->set_value( $post_meta_key, 2, $indexable->object_id );
241 }
242
243 if ( $indexable->is_robots_noindex === true ) {
244 $this->meta->set_value( $post_meta_key, 1, $indexable->object_id );
245 }
246 }
247
248 /**
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.
250 *
251 * @param Indexable $indexable The Yoast indexable.
252 * @param string $post_meta_key The post_meta key that will be populated.
253 *
254 * @return void
255 */
256 public function nofollow_map( $indexable, $post_meta_key ) {
257 if ( $indexable->is_robots_nofollow === null || $indexable->is_robots_nofollow === false ) {
258 $this->meta->delete( $post_meta_key, $indexable->object_id );
259 }
260
261 if ( $indexable->is_robots_nofollow === true ) {
262 $this->meta->set_value( $post_meta_key, 1, $indexable->object_id );
263 }
264 }
265
266 /**
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.
268 *
269 * @param Indexable $indexable The Yoast indexable.
270 * @param string $post_meta_key The post_meta key that will be populated.
271 *
272 * @return void
273 */
274 public function robots_adv_map( $indexable, $post_meta_key ) {
275 $adv_settings_to_be_imported = [];
276 $no_adv_settings = true;
277
278 if ( $indexable->is_robots_noimageindex === true ) {
279 $adv_settings_to_be_imported[] = 'noimageindex';
280 $no_adv_settings = false;
281 }
282 if ( $indexable->is_robots_noarchive === true ) {
283 $adv_settings_to_be_imported[] = 'noarchive';
284 $no_adv_settings = false;
285 }
286 if ( $indexable->is_robots_nosnippet === true ) {
287 $adv_settings_to_be_imported[] = 'nosnippet';
288 $no_adv_settings = false;
289 }
290
291 if ( $no_adv_settings === true ) {
292 $this->meta->delete( $post_meta_key, $indexable->object_id );
293 return;
294 }
295
296 $this->meta->set_value( $post_meta_key, \implode( ',', $adv_settings_to_be_imported ), $indexable->object_id );
297 }
298 }
299