PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.8
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.8
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 / actions / importing / aioseo / aioseo-posts-importing-action.php

aioseo-posts-importing-action.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 27.8, at src/actions/importing/aioseo/aioseo-posts-importing-action.php

626 lines 22.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
4 namespace Yoast\WP\SEO\Actions\Importing\Aioseo;
5
6 use wpdb;
7 use Yoast\WP\SEO\Actions\Importing\Abstract_Aioseo_Importing_Action;
8 use Yoast\WP\SEO\Helpers\Image_Helper;
9 use Yoast\WP\SEO\Helpers\Import_Cursor_Helper;
10 use Yoast\WP\SEO\Helpers\Indexable_Helper;
11 use Yoast\WP\SEO\Helpers\Indexable_To_Postmeta_Helper;
12 use Yoast\WP\SEO\Helpers\Options_Helper;
13 use Yoast\WP\SEO\Helpers\Sanitization_Helper;
14 use Yoast\WP\SEO\Models\Indexable;
15 use Yoast\WP\SEO\Repositories\Indexable_Repository;
16 use Yoast\WP\SEO\Services\Importing\Aioseo\Aioseo_Replacevar_Service;
17 use Yoast\WP\SEO\Services\Importing\Aioseo\Aioseo_Robots_Provider_Service;
18 use Yoast\WP\SEO\Services\Importing\Aioseo\Aioseo_Robots_Transformer_Service;
19 use Yoast\WP\SEO\Services\Importing\Aioseo\Aioseo_Social_Images_Provider_Service;
20
21 /**
22 * Importing action for AIOSEO post data.
23 */
24 class Aioseo_Posts_Importing_Action extends Abstract_Aioseo_Importing_Action {
25
26 /**
27 * The plugin of the action.
28 */
29 public const PLUGIN = 'aioseo';
30
31 /**
32 * The type of the action.
33 */
34 public const TYPE = 'posts';
35
36 /**
37 * The map of aioseo to yoast meta.
38 *
39 * @var array<string, array<string, string|bool|array<string, string|bool>>>
40 */
41 protected $aioseo_to_yoast_map = [
42 'title' => [
43 'yoast_name' => 'title',
44 'transform_method' => 'simple_import_post',
45 ],
46 'description' => [
47 'yoast_name' => 'description',
48 'transform_method' => 'simple_import_post',
49 ],
50 'og_title' => [
51 'yoast_name' => 'open_graph_title',
52 'transform_method' => 'simple_import_post',
53 ],
54 'og_description' => [
55 'yoast_name' => 'open_graph_description',
56 'transform_method' => 'simple_import_post',
57 ],
58 'twitter_title' => [
59 'yoast_name' => 'twitter_title',
60 'transform_method' => 'simple_import_post',
61 'twitter_import' => true,
62 ],
63 'twitter_description' => [
64 'yoast_name' => 'twitter_description',
65 'transform_method' => 'simple_import_post',
66 'twitter_import' => true,
67 ],
68 'canonical_url' => [
69 'yoast_name' => 'canonical',
70 'transform_method' => 'url_import_post',
71 ],
72 'keyphrases' => [
73 'yoast_name' => 'primary_focus_keyword',
74 'transform_method' => 'keyphrase_import',
75 ],
76 'og_image_url' => [
77 'yoast_name' => 'open_graph_image',
78 'social_image_import' => true,
79 'social_setting_prefix_aioseo' => 'og_',
80 'social_setting_prefix_yoast' => 'open_graph_',
81 'transform_method' => 'social_image_url_import',
82 ],
83 'twitter_image_url' => [
84 'yoast_name' => 'twitter_image',
85 'social_image_import' => true,
86 'social_setting_prefix_aioseo' => 'twitter_',
87 'social_setting_prefix_yoast' => 'twitter_',
88 'transform_method' => 'social_image_url_import',
89 ],
90 'robots_noindex' => [
91 'yoast_name' => 'is_robots_noindex',
92 'transform_method' => 'post_robots_noindex_import',
93 'robots_import' => true,
94 ],
95 'robots_nofollow' => [
96 'yoast_name' => 'is_robots_nofollow',
97 'transform_method' => 'post_general_robots_import',
98 'robots_import' => true,
99 'robot_type' => 'nofollow',
100 ],
101 'robots_noarchive' => [
102 'yoast_name' => 'is_robots_noarchive',
103 'transform_method' => 'post_general_robots_import',
104 'robots_import' => true,
105 'robot_type' => 'noarchive',
106 ],
107 'robots_nosnippet' => [
108 'yoast_name' => 'is_robots_nosnippet',
109 'transform_method' => 'post_general_robots_import',
110 'robots_import' => true,
111 'robot_type' => 'nosnippet',
112 ],
113 'robots_noimageindex' => [
114 'yoast_name' => 'is_robots_noimageindex',
115 'transform_method' => 'post_general_robots_import',
116 'robots_import' => true,
117 'robot_type' => 'noimageindex',
118 ],
119 ];
120
121 /**
122 * Represents the indexables repository.
123 *
124 * @var Indexable_Repository
125 */
126 protected $indexable_repository;
127
128 /**
129 * The WordPress database instance.
130 *
131 * @var wpdb
132 */
133 protected $wpdb;
134
135 /**
136 * The image helper.
137 *
138 * @var Image_Helper
139 */
140 protected $image;
141
142 /**
143 * The indexable_to_postmeta helper.
144 *
145 * @var Indexable_To_Postmeta_Helper
146 */
147 protected $indexable_to_postmeta;
148
149 /**
150 * The indexable helper.
151 *
152 * @var Indexable_Helper
153 */
154 protected $indexable_helper;
155
156 /**
157 * The social images provider service.
158 *
159 * @var Aioseo_Social_Images_Provider_Service
160 */
161 protected $social_images_provider;
162
163 /**
164 * Class constructor.
165 *
166 * @param Indexable_Repository $indexable_repository The indexables repository.
167 * @param wpdb $wpdb The WordPress database instance.
168 * @param Import_Cursor_Helper $import_cursor The import cursor helper.
169 * @param Indexable_Helper $indexable_helper The indexable helper.
170 * @param Indexable_To_Postmeta_Helper $indexable_to_postmeta The indexable_to_postmeta helper.
171 * @param Options_Helper $options The options helper.
172 * @param Image_Helper $image The image helper.
173 * @param Sanitization_Helper $sanitization The sanitization helper.
174 * @param Aioseo_Replacevar_Service $replacevar_handler The replacevar handler.
175 * @param Aioseo_Robots_Provider_Service $robots_provider The robots provider service.
176 * @param Aioseo_Robots_Transformer_Service $robots_transformer The robots transfomer service.
177 * @param Aioseo_Social_Images_Provider_Service $social_images_provider The social images provider service.
178 */
179 public function __construct(
180 Indexable_Repository $indexable_repository,
181 wpdb $wpdb,
182 Import_Cursor_Helper $import_cursor,
183 Indexable_Helper $indexable_helper,
184 Indexable_To_Postmeta_Helper $indexable_to_postmeta,
185 Options_Helper $options,
186 Image_Helper $image,
187 Sanitization_Helper $sanitization,
188 Aioseo_Replacevar_Service $replacevar_handler,
189 Aioseo_Robots_Provider_Service $robots_provider,
190 Aioseo_Robots_Transformer_Service $robots_transformer,
191 Aioseo_Social_Images_Provider_Service $social_images_provider
192 ) {
193 parent::__construct( $import_cursor, $options, $sanitization, $replacevar_handler, $robots_provider, $robots_transformer );
194
195 $this->indexable_repository = $indexable_repository;
196 $this->wpdb = $wpdb;
197 $this->image = $image;
198 $this->indexable_helper = $indexable_helper;
199 $this->indexable_to_postmeta = $indexable_to_postmeta;
200 $this->social_images_provider = $social_images_provider;
201 }
202
203 // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: They are already prepared.
204
205 /**
206 * Returns the total number of unimported objects.
207 *
208 * @return int The total number of unimported objects.
209 */
210 public function get_total_unindexed() {
211 if ( ! $this->aioseo_helper->aioseo_exists() ) {
212 return 0;
213 }
214
215 $limit = false;
216 $just_detect = true;
217 $indexables_to_create = $this->wpdb->get_col( $this->query( $limit, $just_detect ) );
218
219 $number_of_indexables_to_create = \count( $indexables_to_create );
220 $completed = $number_of_indexables_to_create === 0;
221 $this->set_completed( $completed );
222
223 return $number_of_indexables_to_create;
224 }
225
226 /**
227 * Returns the limited number of unimported objects.
228 *
229 * @param int $limit The maximum number of unimported objects to be returned.
230 *
231 * @return int|false The limited number of unindexed posts. False if the query fails.
232 */
233 public function get_limited_unindexed_count( $limit ) {
234 if ( ! $this->aioseo_helper->aioseo_exists() ) {
235 return 0;
236 }
237
238 $just_detect = true;
239 $indexables_to_create = $this->wpdb->get_col( $this->query( $limit, $just_detect ) );
240
241 $number_of_indexables_to_create = \count( $indexables_to_create );
242 $completed = $number_of_indexables_to_create === 0;
243 $this->set_completed( $completed );
244
245 return $number_of_indexables_to_create;
246 }
247
248 /**
249 * Imports AIOSEO meta data and creates the respective Yoast indexables and postmeta.
250 *
251 * @return Indexable[]|false An array of created indexables or false if aioseo data was not found.
252 */
253 public function index() {
254 if ( ! $this->aioseo_helper->aioseo_exists() ) {
255 return false;
256 }
257
258 $limit = $this->get_limit();
259 $aioseo_indexables = $this->wpdb->get_results( $this->query( $limit ), \ARRAY_A );
260 $created_indexables = [];
261
262 $completed = \count( $aioseo_indexables ) === 0;
263 $this->set_completed( $completed );
264
265 // Let's build the list of fields to check their defaults, to identify whether we're gonna import AIOSEO data in the indexable or not.
266 $check_defaults_fields = [];
267 foreach ( $this->aioseo_to_yoast_map as $yoast_mapping ) {
268 // We don't want to check all the imported fields.
269 if ( ! \in_array( $yoast_mapping['yoast_name'], [ 'open_graph_image', 'twitter_image' ], true ) ) {
270 $check_defaults_fields[] = $yoast_mapping['yoast_name'];
271 }
272 }
273
274 $last_indexed_aioseo_id = 0;
275 foreach ( $aioseo_indexables as $aioseo_indexable ) {
276 $last_indexed_aioseo_id = $aioseo_indexable['id'];
277
278 $indexable = $this->indexable_repository->find_by_id_and_type( $aioseo_indexable['post_id'], 'post' );
279
280 // Let's ensure that the current post id represents something that we want to index (eg. *not* shop_order).
281 if ( ! \is_a( $indexable, 'Yoast\WP\SEO\Models\Indexable' ) ) {
282 continue;
283 }
284
285 if ( $this->indexable_helper->check_if_default_indexable( $indexable, $check_defaults_fields ) ) {
286 $indexable = $this->map( $indexable, $aioseo_indexable );
287 $this->indexable_helper->save_indexable( $indexable );
288
289 // To ensure that indexables can be rebuild after a reset, we have to store the data in the postmeta table too.
290 $this->indexable_to_postmeta->map_to_postmeta( $indexable );
291 }
292
293 $last_indexed_aioseo_id = $aioseo_indexable['id'];
294
295 $created_indexables[] = $indexable;
296 }
297
298 $cursor_id = $this->get_cursor_id();
299 $this->import_cursor->set_cursor( $cursor_id, $last_indexed_aioseo_id );
300
301 return $created_indexables;
302 }
303
304 // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
305
306 /**
307 * Maps AIOSEO meta data to Yoast meta data.
308 *
309 * @param Indexable $indexable The Yoast indexable.
310 * @param array $aioseo_indexable The AIOSEO indexable.
311 *
312 * @return Indexable The created indexables.
313 */
314 public function map( $indexable, $aioseo_indexable ) {
315 foreach ( $this->aioseo_to_yoast_map as $aioseo_key => $yoast_mapping ) {
316 // For robots import.
317 if ( isset( $yoast_mapping['robots_import'] ) && $yoast_mapping['robots_import'] ) {
318 $yoast_mapping['subtype'] = $indexable->object_sub_type;
319 $indexable->{$yoast_mapping['yoast_name']} = $this->transform_import_data( $yoast_mapping['transform_method'], $aioseo_indexable, $aioseo_key, $yoast_mapping, $indexable );
320
321 continue;
322 }
323
324 // For social images, like open graph and twitter image.
325 if ( isset( $yoast_mapping['social_image_import'] ) && $yoast_mapping['social_image_import'] ) {
326 $image_url = $this->transform_import_data( $yoast_mapping['transform_method'], $aioseo_indexable, $aioseo_key, $yoast_mapping, $indexable );
327
328 // Update the indexable's social image only where there's actually a url to import, so as not to lose the social images that we came up with when we originally built the indexable.
329 if ( ! empty( $image_url ) ) {
330 $indexable->{$yoast_mapping['yoast_name']} = $image_url;
331
332 $image_source_key = $yoast_mapping['social_setting_prefix_yoast'] . 'image_source';
333 $indexable->$image_source_key = 'imported';
334
335 $image_id_key = $yoast_mapping['social_setting_prefix_yoast'] . 'image_id';
336 $indexable->$image_id_key = $this->image->get_attachment_by_url( $image_url );
337
338 if ( $yoast_mapping['yoast_name'] === 'open_graph_image' ) {
339 $indexable->open_graph_image_meta = null;
340 }
341 }
342 continue;
343 }
344
345 // For twitter import, take the respective open graph data if the appropriate setting is enabled.
346 if ( isset( $yoast_mapping['twitter_import'] ) && $yoast_mapping['twitter_import'] && $aioseo_indexable['twitter_use_og'] ) {
347 $aioseo_indexable['twitter_title'] = $aioseo_indexable['og_title'];
348 $aioseo_indexable['twitter_description'] = $aioseo_indexable['og_description'];
349 }
350
351 if ( ! empty( $aioseo_indexable[ $aioseo_key ] ) ) {
352 $indexable->{$yoast_mapping['yoast_name']} = $this->transform_import_data( $yoast_mapping['transform_method'], $aioseo_indexable, $aioseo_key, $yoast_mapping, $indexable );
353 }
354 }
355
356 return $indexable;
357 }
358
359 /**
360 * Transforms the data to be imported.
361 *
362 * @param string $transform_method The method that is going to be used for transforming the data.
363 * @param array $aioseo_indexable The data of the AIOSEO indexable data that is being imported.
364 * @param string $aioseo_key The name of the specific set of data that is going to be transformed.
365 * @param array $yoast_mapping Extra details for the import of the specific data that is going to be transformed.
366 * @param Indexable $indexable The Yoast indexable that we are going to import the transformed data into.
367 *
368 * @return string|bool|null The transformed data to be imported.
369 */
370 protected function transform_import_data( $transform_method, $aioseo_indexable, $aioseo_key, $yoast_mapping, $indexable ) {
371 return \call_user_func( [ $this, $transform_method ], $aioseo_indexable, $aioseo_key, $yoast_mapping, $indexable );
372 }
373
374 /**
375 * Returns the number of objects that will be imported in a single importing pass.
376 *
377 * @return int The limit.
378 */
379 public function get_limit() {
380 /**
381 * Filter 'wpseo_aioseo_post_indexation_limit' - Allow filtering the number of posts indexed during each indexing pass.
382 *
383 * @param int $max_posts The maximum number of posts indexed.
384 */
385 $limit = \apply_filters( 'wpseo_aioseo_post_indexation_limit', 25 );
386
387 if ( ! \is_int( $limit ) || $limit < 1 ) {
388 $limit = 25;
389 }
390
391 return $limit;
392 }
393
394 /**
395 * Populates the needed data array based on which columns we use from the AIOSEO indexable table.
396 *
397 * @return array The needed data array that contains all the needed columns.
398 */
399 public function get_needed_data() {
400 $needed_data = \array_keys( $this->aioseo_to_yoast_map );
401 \array_push( $needed_data, 'id', 'post_id', 'robots_default', 'og_image_custom_url', 'og_image_type', 'twitter_image_custom_url', 'twitter_image_type', 'twitter_use_og' );
402
403 return $needed_data;
404 }
405
406 /**
407 * Populates the needed robot data array to be used in validating against its structure.
408 *
409 * @return array The needed data array that contains all the needed columns.
410 */
411 public function get_needed_robot_data() {
412 $needed_robot_data = [];
413
414 foreach ( $this->aioseo_to_yoast_map as $yoast_mapping ) {
415 if ( isset( $yoast_mapping['robot_type'] ) ) {
416 $needed_robot_data[] = $yoast_mapping['robot_type'];
417 }
418 }
419
420 return $needed_robot_data;
421 }
422
423 /**
424 * Creates a query for gathering AiOSEO data from the database.
425 *
426 * @param int|false $limit The maximum number of unimported objects to be returned.
427 * False for "no limit".
428 * @param bool $just_detect Whether we want to just detect if there are unimported objects. If false, we want to actually import them too.
429 *
430 * @return string The query to use for importing or counting the number of items to import.
431 */
432 public function query( $limit = false, $just_detect = false ) {
433 $table = $this->aioseo_helper->get_table();
434
435 $select_statement = 'id';
436 if ( ! $just_detect ) {
437 // If we want to import too, we need the actual needed data from AIOSEO indexables.
438 $needed_data = $this->get_needed_data();
439
440 $select_statement = \implode( ', ', $needed_data );
441 }
442
443 $cursor_id = $this->get_cursor_id();
444 $cursor = $this->import_cursor->get_cursor( $cursor_id );
445
446 /**
447 * Filter 'wpseo_aioseo_post_cursor' - Allow filtering the value of the aioseo post import cursor.
448 *
449 * @param int $import_cursor The value of the aioseo post import cursor.
450 */
451 $cursor = \apply_filters( 'wpseo_aioseo_post_import_cursor', $cursor );
452
453 $replacements = [ $cursor ];
454
455 $limit_statement = '';
456 if ( ! empty( $limit ) ) {
457 $replacements[] = $limit;
458 $limit_statement = ' LIMIT %d';
459 }
460
461 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
462 return $this->wpdb->prepare(
463 "SELECT {$select_statement} FROM {$table} WHERE id > %d ORDER BY id{$limit_statement}",
464 $replacements,
465 );
466 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
467 }
468
469 /**
470 * Minimally transforms data to be imported.
471 *
472 * @param array $aioseo_data All of the AIOSEO data to be imported.
473 * @param string $aioseo_key The AIOSEO key that contains the setting we're working with.
474 *
475 * @return string The transformed meta data.
476 */
477 public function simple_import_post( $aioseo_data, $aioseo_key ) {
478 return $this->simple_import( $aioseo_data[ $aioseo_key ] );
479 }
480
481 /**
482 * Transforms URL to be imported.
483 *
484 * @param array $aioseo_data All of the AIOSEO data to be imported.
485 * @param string $aioseo_key The AIOSEO key that contains the setting we're working with.
486 *
487 * @return string The transformed URL.
488 */
489 public function url_import_post( $aioseo_data, $aioseo_key ) {
490 return $this->url_import( $aioseo_data[ $aioseo_key ] );
491 }
492
493 /**
494 * Plucks the keyphrase to be imported from the AIOSEO array of keyphrase meta data.
495 *
496 * @param array $aioseo_data All of the AIOSEO data to be imported.
497 * @param string $aioseo_key The AIOSEO key that contains the setting we're working with, aka keyphrases.
498 *
499 * @return string|null The plucked keyphrase.
500 */
501 public function keyphrase_import( $aioseo_data, $aioseo_key ) {
502 $meta_data = \json_decode( $aioseo_data[ $aioseo_key ], true );
503 if ( ! isset( $meta_data['focus']['keyphrase'] ) ) {
504 return null;
505 }
506
507 return $this->sanitization->sanitize_text_field( $meta_data['focus']['keyphrase'] );
508 }
509
510 /**
511 * Imports the post's noindex setting.
512 *
513 * @param bool $aioseo_robots_settings AIOSEO's set of robot settings for the post.
514 *
515 * @return bool|null The value of Yoast's noindex setting for the post.
516 */
517 public function post_robots_noindex_import( $aioseo_robots_settings ) {
518 // If robot settings defer to default settings, we have null in the is_robots_noindex field.
519 if ( $aioseo_robots_settings['robots_default'] ) {
520 return null;
521 }
522
523 return $aioseo_robots_settings['robots_noindex'];
524 }
525
526 /**
527 * Imports the post's robots setting.
528 *
529 * @param bool $aioseo_robots_settings AIOSEO's set of robot settings for the post.
530 * @param string $aioseo_key The AIOSEO key that contains the robot setting we're working with.
531 * @param array $mapping The mapping of the setting we're working with.
532 *
533 * @return bool|null The value of Yoast's noindex setting for the post.
534 */
535 public function post_general_robots_import( $aioseo_robots_settings, $aioseo_key, $mapping ) {
536 $mapping = $this->enhance_mapping( $mapping );
537
538 if ( $aioseo_robots_settings['robots_default'] ) {
539 // Let's first get the subtype's setting value and then transform it taking into consideration whether it defers to global defaults.
540 $subtype_setting = $this->robots_provider->get_subtype_robot_setting( $mapping );
541 return $this->robots_transformer->transform_robot_setting( $mapping['robot_type'], $subtype_setting, $mapping );
542 }
543
544 return $aioseo_robots_settings[ $aioseo_key ];
545 }
546
547 /**
548 * Enhances the mapping of the setting we're working with, with type and the option name, so that we can retrieve the settings for the object we're working with.
549 *
550 * @param array $mapping The mapping of the setting we're working with.
551 *
552 * @return array The enhanced mapping.
553 */
554 public function enhance_mapping( $mapping = [] ) {
555 $mapping['type'] = 'postTypes';
556 $mapping['option_name'] = 'aioseo_options_dynamic';
557
558 return $mapping;
559 }
560
561 /**
562 * Imports the og and twitter image url.
563 *
564 * @param bool $aioseo_social_image_settings AIOSEO's set of social image settings for the post.
565 * @param string $aioseo_key The AIOSEO key that contains the robot setting we're working with.
566 * @param array $mapping The mapping of the setting we're working with.
567 * @param Indexable $indexable The Yoast indexable we're importing into.
568 *
569 * @return bool|null The url of the social image we're importing, null if there's none.
570 */
571 public function social_image_url_import( $aioseo_social_image_settings, $aioseo_key, $mapping, $indexable ) {
572 if ( $mapping['social_setting_prefix_aioseo'] === 'twitter_' && $aioseo_social_image_settings['twitter_use_og'] ) {
573 $mapping['social_setting_prefix_aioseo'] = 'og_';
574 }
575
576 $social_setting = \rtrim( $mapping['social_setting_prefix_aioseo'], '_' );
577
578 $image_type = $aioseo_social_image_settings[ $mapping['social_setting_prefix_aioseo'] . 'image_type' ];
579
580 if ( $image_type === 'default' ) {
581 $image_type = $this->social_images_provider->get_default_social_image_source( $social_setting );
582 }
583
584 switch ( $image_type ) {
585 case 'attach':
586 $image_url = $this->social_images_provider->get_first_attached_image( $indexable->object_id );
587 break;
588 case 'auto':
589 if ( $this->social_images_provider->get_featured_image( $indexable->object_id ) ) {
590 // If there's a featured image, lets not import it, as our indexable calculation has already set that as active social image. That way we achieve dynamicality.
591 return null;
592 }
593 $image_url = $this->social_images_provider->get_auto_image( $indexable->object_id );
594 break;
595 case 'content':
596 $image_url = $this->social_images_provider->get_first_image_in_content( $indexable->object_id );
597 break;
598 case 'custom_image':
599 $image_url = $aioseo_social_image_settings[ $mapping['social_setting_prefix_aioseo'] . 'image_custom_url' ];
600 break;
601 case 'featured':
602 return null; // Our auto-calculation when the indexable was built/updated has taken care of it, so it's not needed to transfer any data now.
603 case 'author':
604 return null;
605 case 'custom':
606 return null;
607 case 'default':
608 $image_url = $this->social_images_provider->get_default_custom_social_image( $social_setting );
609 break;
610 default:
611 $image_url = $aioseo_social_image_settings[ $mapping['social_setting_prefix_aioseo'] . 'image_url' ];
612 break;
613 }
614
615 if ( empty( $image_url ) ) {
616 $image_url = $this->social_images_provider->get_default_custom_social_image( $social_setting );
617 }
618
619 if ( empty( $image_url ) ) {
620 return null;
621 }
622
623 return $this->sanitization->sanitize_url( $image_url, null );
624 }
625 }
626