| @@ -4,9 +4,9 @@ | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | /** |
| 7 | 7 | * Manages the compatibility with Yoast SEO |
| 8 | - * Version tested: 11.5 | |
| 8 | + * Version tested: 15.9.2 | |
| 9 | 9 | * |
| 10 | 10 | * @since 2.3 |
| 11 | 11 | */ |
| 12 | 12 | class PLL_WPSEO { |
| @@ -16,8 +16,9 @@ | ||
| 16 | 16 | * @since 1.6.4 |
| 17 | 17 | */ |
| 18 | 18 | public function init() { |
| 19 | 19 | add_action( 'wp_loaded', array( $this, 'wpseo_translate_options' ) ); |
| 20 | + add_filter( 'wpseo_dynamic_permalinks_enabled', '__return_true', 999 ); | |
| 20 | 21 | |
| 21 | 22 | if ( PLL() instanceof PLL_Frontend ) { |
| 22 | 23 | // Filters sitemap queries to remove inactive language or to get |
| 23 | 24 | // one sitemap per language when using multiple domains or subdomains |
| @@ -37,74 +38,77 @@ | ||
| 37 | 38 | add_action( 'pre_get_posts', array( $this, 'before_sitemap' ), 0 ); // Needs to be fired before WPSEO_Sitemaps::redirect() |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | 41 | add_filter( 'pll_home_url_white_list', array( $this, 'wpseo_home_url_white_list' ) ); |
| 41 | - if ( version_compare( WPSEO_VERSION, '14.0', '<' ) ) { | |
| 42 | - add_action( 'wpseo_opengraph', array( $this, 'wpseo_ogp' ), 2 ); | |
| 43 | - } else { | |
| 44 | - add_filter( 'wpseo_frontend_presenters', array( $this, 'wpseo_frontend_presenters' ) ); | |
| 45 | - } | |
| 42 | + add_filter( 'wpseo_frontend_presenters', array( $this, 'wpseo_frontend_presenters' ) ); | |
| 46 | 43 | add_filter( 'wpseo_canonical', array( $this, 'wpseo_canonical' ) ); |
| 47 | 44 | add_filter( 'wpseo_frontend_presentation', array( $this, 'frontend_presentation' ) ); |
| 48 | 45 | add_filter( 'wpseo_breadcrumb_indexables', array( $this, 'breadcrumb_indexables' ) ); |
| 49 | 46 | } else { |
| 50 | - // Primary category | |
| 51 | - add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ) ); | |
| 47 | + add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 4 ); | |
| 52 | 48 | add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 ); |
| 49 | + add_filter( 'pll_post_metas_to_export', array( $this, 'export_post_metas' ) ); | |
| 50 | + | |
| 51 | + // Yoast SEO adds the columns hooks only for the 'inline-save' action. We need them for 'pll_update_post_rows' too. | |
| 52 | + if ( wp_doing_ajax() && isset( $_POST['action'] ) && 'pll_update_post_rows' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 53 | + $GLOBALS['wpseo_meta_columns'] = new WPSEO_Meta_Columns(); | |
| 54 | + } | |
| 53 | 55 | } |
| 54 | 56 | } |
| 55 | 57 | |
| 56 | 58 | /** |
| 57 | - * Registers custom post types and taxonomy titles for translation. | |
| 59 | + * Registers options for translation. | |
| 58 | 60 | * |
| 59 | 61 | * @since 2.9 |
| 60 | 62 | */ |
| 61 | 63 | public function wpseo_translate_options() { |
| 62 | - $keys = array(); | |
| 64 | + if ( method_exists( 'WPSEO_Options', 'clear_cache' ) ) { | |
| 65 | + WPSEO_Options::clear_cache(); | |
| 66 | + } | |
| 63 | 67 | |
| 64 | - foreach ( get_post_types( array( 'public' => true, '_builtin' => false ) ) as $t ) { | |
| 65 | - if ( pll_is_translated_post_type( $t ) ) { | |
| 66 | - $keys[] = 'title-' . $t; | |
| 67 | - $keys[] = 'metadesc-' . $t; | |
| 68 | - } | |
| 69 | - } | |
| 68 | + $keys = array( | |
| 69 | + 'title-*', | |
| 70 | + 'metadesc-*', | |
| 71 | + 'bctitle-*', | |
| 72 | + 'breadcrumbs-sep', | |
| 73 | + 'breadcrumbs-home', | |
| 74 | + 'breadcrumbs-prefix', | |
| 75 | + 'breadcrumbs-archiveprefix', | |
| 76 | + 'breadcrumbs-searchprefix', | |
| 77 | + 'breadcrumbs-404crumb', | |
| 78 | + 'company_name', | |
| 79 | + 'rssbefore', | |
| 80 | + 'rssafter', | |
| 81 | + 'social-title-*', | |
| 82 | + 'social-description-*', | |
| 83 | + ); | |
| 70 | 84 | |
| 71 | - foreach ( get_post_types( array( 'has_archive' => true, '_builtin' => false ) ) as $t ) { | |
| 72 | - if ( pll_is_translated_post_type( $t ) ) { | |
| 73 | - $keys[] = 'title-ptarchive-' . $t; | |
| 74 | - $keys[] = 'metadesc-ptarchive-' . $t; | |
| 75 | - $keys[] = 'bctitle-ptarchive-' . $t; | |
| 76 | - } | |
| 77 | - } | |
| 85 | + new PLL_Translate_Option( 'wpseo_titles', array_fill_keys( $keys, 1 ), array( 'context' => 'wordpress-seo' ) ); | |
| 78 | 86 | |
| 79 | - foreach ( get_taxonomies( array( 'public' => true, '_builtin' => false ) ) as $t ) { | |
| 80 | - if ( pll_is_translated_taxonomy( $t ) ) { | |
| 81 | - $keys[] = 'title-tax-' . $t; | |
| 82 | - $keys[] = 'metadesc-tax-' . $t; | |
| 83 | - } | |
| 84 | - } | |
| 87 | + $keys = array( | |
| 88 | + 'og_frontpage_title', | |
| 89 | + 'og_frontpage_desc', | |
| 90 | + ); | |
| 85 | 91 | |
| 86 | - if ( ! empty( $keys ) ) { | |
| 87 | - new PLL_Translate_Option( 'wpseo_titles', array_fill_keys( $keys, 1 ), array( 'context' => 'wordpress-seo' ) ); | |
| 88 | - } | |
| 92 | + new PLL_Translate_Option( 'wpseo_social', array_fill_keys( $keys, 1 ), array( 'context' => 'wordpress-seo' ) ); | |
| 89 | 93 | } |
| 90 | 94 | |
| 91 | 95 | /** |
| 92 | - * Fixes the home url as well as the stylesheet url | |
| 93 | - * Only when using multiple domains or subdomains | |
| 96 | + * Fixes the home url as well as the stylesheet url, | |
| 97 | + * only when using multiple domains or subdomains. | |
| 94 | 98 | * |
| 95 | 99 | * @since 1.6.4 |
| 96 | 100 | * |
| 97 | - * @param string $url | |
| 98 | - * @param string $path | |
| 101 | + * @param string $url The complete URL including scheme and path. | |
| 102 | + * @param string $path Path relative to the home URL. | |
| 99 | 103 | * @return $url |
| 100 | 104 | */ |
| 101 | 105 | public function wpseo_home_url( $url, $path ) { |
| 102 | 106 | if ( empty( $path ) ) { |
| 103 | - $path = ltrim( wp_parse_url( pll_get_requested_url(), PHP_URL_PATH ), '/' ); | |
| 107 | + $path = ltrim( (string) wp_parse_url( pll_get_requested_url(), PHP_URL_PATH ), '/' ); | |
| 104 | 108 | } |
| 105 | 109 | |
| 106 | - if ( 'sitemap_index.xml' === $path || preg_match( '#([^/]+?)-sitemap([0-9]+)?\.xml|([a-z]+)?-?sitemap\.xsl#', $path ) ) { | |
| 110 | + if ( preg_match( '#sitemap(_index)?\.xml|([^\/]+?)-?sitemap([0-9]+)?\.xml|([a-z]+)?-?sitemap\.xsl#', $path ) ) { | |
| 107 | 111 | $url = PLL()->links_model->switch_language_in_link( $url, PLL()->curlang ); |
| 108 | 112 | } |
| 109 | 113 | |
| 110 | 114 | return $url; |
| @@ -125,42 +129,45 @@ | ||
| 125 | 129 | return array(); |
| 126 | 130 | } |
| 127 | 131 | |
| 128 | 132 | /** |
| 129 | - * Modifies the sql request for posts sitemaps | |
| 130 | - * Only when using multiple domains or subdomains or if some languages are not active | |
| 133 | + * Modifies the sql request for posts sitemaps. | |
| 131 | 134 | * |
| 132 | 135 | * @since 1.6.4 |
| 133 | 136 | * |
| 134 | - * @param string $sql JOIN clause | |
| 135 | - * @param string $post_type | |
| 137 | + * @param string $sql JOIN clause. | |
| 138 | + * @param string $post_type Post type. | |
| 136 | 139 | * @return string |
| 137 | 140 | */ |
| 138 | 141 | public function wpseo_posts_join( $sql, $post_type ) { |
| 139 | - return pll_is_translated_post_type( $post_type ) && ( PLL()->options['force_lang'] > 1 || $this->wpseo_get_active_languages() ) ? $sql . PLL()->model->post->join_clause() : $sql; | |
| 142 | + return pll_is_translated_post_type( $post_type ) ? $sql . PLL()->model->post->join_clause() : $sql; | |
| 140 | 143 | } |
| 141 | 144 | |
| 142 | 145 | /** |
| 143 | - * Modifies the sql request for posts sitemaps | |
| 144 | - * Only when using multiple domains or subdomains or if some languages are not active | |
| 146 | + * Modifies the sql request for posts sitemaps. | |
| 145 | 147 | * |
| 146 | 148 | * @since 1.6.4 |
| 147 | 149 | * |
| 148 | - * @param string $sql WHERE clause | |
| 149 | - * @param string $post_type | |
| 150 | + * @param string $sql WHERE clause. | |
| 151 | + * @param string $post_type Post type. | |
| 150 | 152 | * @return string |
| 151 | 153 | */ |
| 152 | 154 | public function wpseo_posts_where( $sql, $post_type ) { |
| 153 | - if ( pll_is_translated_post_type( $post_type ) ) { | |
| 154 | - if ( PLL()->options['force_lang'] > 1 ) { | |
| 155 | - return $sql . PLL()->model->post->where_clause( PLL()->curlang ); | |
| 156 | - } | |
| 155 | + if ( ! pll_is_translated_post_type( $post_type ) ) { | |
| 156 | + return $sql; | |
| 157 | + } | |
| 157 | 158 | |
| 158 | - if ( $languages = $this->wpseo_get_active_languages() ) { | |
| 159 | - return $sql . PLL()->model->post->where_clause( $languages ); | |
| 160 | - } | |
| 159 | + if ( PLL()->options['force_lang'] > 1 && PLL()->curlang instanceof PLL_Language ) { | |
| 160 | + return $sql . PLL()->model->post->where_clause( PLL()->curlang ); | |
| 161 | 161 | } |
| 162 | - return $sql; | |
| 162 | + | |
| 163 | + $languages = $this->wpseo_get_active_languages(); | |
| 164 | + | |
| 165 | + if ( empty( $languages ) ) { // Empty when all languages are active. | |
| 166 | + $languages = pll_languages_list(); | |
| 167 | + } | |
| 168 | + | |
| 169 | + return $sql . PLL()->model->post->where_clause( $languages ); | |
| 163 | 170 | } |
| 164 | 171 | |
| 165 | 172 | /** |
| 166 | 173 | * Removes the language filter (and remove inactive languages) for the taxonomy sitemaps |
| @@ -194,13 +201,13 @@ | ||
| 194 | 201 | } |
| 195 | 202 | } |
| 196 | 203 | |
| 197 | 204 | /** |
| 198 | - * Add filters before the sitemap is evaluated and outputed | |
| 205 | + * Add filters before the sitemap is evaluated and outputted. | |
| 199 | 206 | * |
| 200 | 207 | * @since 2.6 |
| 201 | 208 | * |
| 202 | - * @param object $query Instance of WP_Query being filtered. | |
| 209 | + * @param WP_Query $query Instance of WP_Query being filtered. | |
| 203 | 210 | */ |
| 204 | 211 | public function before_sitemap( $query ) { |
| 205 | 212 | $type = $query->get( 'sitemap' ); |
| 206 | 213 | |
| @@ -274,13 +281,13 @@ | ||
| 274 | 281 | return $str; |
| 275 | 282 | } |
| 276 | 283 | |
| 277 | 284 | /** |
| 278 | - * Filters home url | |
| 285 | + * Filters the home url. | |
| 279 | 286 | * |
| 280 | 287 | * @since 1.1.2 |
| 281 | 288 | * |
| 282 | - * @param array $arr | |
| 289 | + * @param array $arr The list of files or functions for which `home_url()` must be filtered. | |
| 283 | 290 | * @return array |
| 284 | 291 | */ |
| 285 | 292 | public function wpseo_home_url_white_list( $arr ) { |
| 286 | 293 | return array_merge( $arr, array( array( 'file' => 'wordpress-seo' ) ) ); |
| @@ -286,19 +293,19 @@ | ||
| 286 | 293 | return array_merge( $arr, array( array( 'file' => 'wordpress-seo' ) ) ); |
| 287 | 294 | } |
| 288 | 295 | |
| 289 | 296 | /** |
| 290 | - * Get alternate language codes for Opengraph | |
| 297 | + * Get alternate language codes for Opengraph. | |
| 291 | 298 | * |
| 292 | 299 | * @since 2.7.3 |
| 293 | 300 | * |
| 294 | - * @return array | |
| 301 | + * @return string[] | |
| 295 | 302 | */ |
| 296 | 303 | protected function get_ogp_alternate_languages() { |
| 297 | 304 | $alternates = array(); |
| 298 | 305 | |
| 299 | 306 | foreach ( PLL()->model->get_languages_list() as $language ) { |
| 300 | - if ( PLL()->curlang->slug !== $language->slug && PLL()->links->get_translation_url( $language ) && isset( $language->facebook ) ) { | |
| 307 | + if ( isset( PLL()->curlang ) && PLL()->curlang->slug !== $language->slug && PLL()->links->get_translation_url( $language ) && isset( $language->facebook ) ) { | |
| 301 | 308 | $alternates[] = $language->facebook; |
| 302 | 309 | } |
| 303 | 310 | } |
| 304 | 311 | |
| @@ -308,24 +315,8 @@ | ||
| 308 | 315 | |
| 309 | 316 | /** |
| 310 | 317 | * Adds opengraph support for translations |
| 311 | 318 | * |
| 312 | - * @since 1.6 | |
| 313 | - */ | |
| 314 | - public function wpseo_ogp() { | |
| 315 | - global $wpseo_og; | |
| 316 | - | |
| 317 | - // WPSEO already deals with the locale | |
| 318 | - if ( did_action( 'pll_init' ) && method_exists( $wpseo_og, 'og_tag' ) ) { | |
| 319 | - foreach ( $this->get_ogp_alternate_languages() as $lang ) { | |
| 320 | - $wpseo_og->og_tag( 'og:locale:alternate', $lang ); | |
| 321 | - } | |
| 322 | - } | |
| 323 | - } | |
| 324 | - | |
| 325 | - /** | |
| 326 | - * Adds opengraph support for translations | |
| 327 | - * | |
| 328 | 319 | * @since 2.7.3 |
| 329 | 320 | * |
| 330 | 321 | * @param array $presenters An array of objects implementing Abstract_Indexable_Presenter |
| 331 | 322 | * @return array |
| @@ -344,13 +335,13 @@ | ||
| 344 | 335 | return $_presenters; |
| 345 | 336 | } |
| 346 | 337 | |
| 347 | 338 | /** |
| 348 | - * Fixes the canonical front page url as unlike WP, WPSEO does not add a trailing slash to the canonical front page url | |
| 339 | + * Fixes the canonical front page url as unlike WP, WPSEO does not add a trailing slash to the canonical front page url. | |
| 349 | 340 | * |
| 350 | 341 | * @since 1.7.10 |
| 351 | 342 | * |
| 352 | - * @param string $url | |
| 343 | + * @param string $url The canonical URL evaluated by Yoast SEO. | |
| 353 | 344 | * @return $url |
| 354 | 345 | */ |
| 355 | 346 | public function wpseo_canonical( $url ) { |
| 356 | 347 | return is_front_page( $url ) && get_option( 'permalink_structure' ) ? trailingslashit( $url ) : $url; |
| @@ -366,28 +357,29 @@ | ||
| 366 | 357 | */ |
| 367 | 358 | public function frontend_presentation( $presentation ) { |
| 368 | 359 | switch ( $presentation->model->object_type ) { |
| 369 | 360 | case 'home-page': |
| 370 | - $presentation->model->permalink = pll_home_url(); | |
| 371 | 361 | $presentation->model->title = WPSEO_Options::get( 'title-home-wpseo' ); |
| 372 | 362 | $presentation->model->description = WPSEO_Options::get( 'metadesc-home-wpseo' ); |
| 363 | + $presentation->model->open_graph_title = WPSEO_Options::get( 'og_frontpage_title' ); | |
| 364 | + $presentation->model->open_graph_description = WPSEO_Options::get( 'og_frontpage_desc' ); | |
| 373 | 365 | break; |
| 374 | 366 | |
| 375 | 367 | case 'post-type-archive': |
| 376 | 368 | if ( pll_is_translated_post_type( $presentation->model->object_sub_type ) ) { |
| 377 | - $presentation->model->permalink = get_post_type_archive_link( $presentation->model->object_sub_type ); | |
| 378 | 369 | $presentation->model->title = WPSEO_Options::get( 'title-ptarchive-' . $presentation->model->object_sub_type ); |
| 379 | 370 | $presentation->model->description = WPSEO_Options::get( 'metadesc-ptarchive-' . $presentation->model->object_sub_type ); |
| 380 | 371 | } |
| 381 | 372 | break; |
| 382 | 373 | |
| 383 | - case 'user': | |
| 384 | - $presentation->model->permalink = get_author_posts_url( $presentation->model->object_id ); | |
| 385 | - break; | |
| 386 | - | |
| 387 | 374 | case 'system-page': |
| 388 | - if ( '404' === $presentation->model->object_sub_type ) { | |
| 389 | - $presentation->model->title = WPSEO_Options::get( 'title-404-wpseo' ); | |
| 375 | + switch ( $presentation->model->object_sub_type ) { | |
| 376 | + case '404': | |
| 377 | + $presentation->model->title = WPSEO_Options::get( 'title-404-wpseo' ); | |
| 378 | + break; | |
| 379 | + case 'search-result': | |
| 380 | + $presentation->model->title = WPSEO_Options::get( 'title-search-wpseo' ); | |
| 381 | + break; | |
| 390 | 382 | } |
| 391 | 383 | break; |
| 392 | 384 | } |
| 393 | 385 | |
| @@ -394,29 +386,32 @@ | ||
| 394 | 386 | return $presentation; |
| 395 | 387 | } |
| 396 | 388 | |
| 397 | 389 | /** |
| 398 | - * Fixes the breadcrumb links and strings stored in the indexable table since Yoast SEO 14.0 | |
| 390 | + * Fixes the breadcrumb links and strings stored in the indexable table since Yoast SEO 14.0. | |
| 399 | 391 | * |
| 392 | + * In version 17.0, the breadcrumb links do not honor the filter `wpseo_dynamic_permalinks_enabled`. | |
| 393 | + * | |
| 400 | 394 | * @since 2.8.3 |
| 401 | 395 | * |
| 402 | 396 | * @param array $indexables An array of Indexable objects. |
| 403 | - * @return object | |
| 397 | + * @return array | |
| 404 | 398 | */ |
| 405 | 399 | public function breadcrumb_indexables( $indexables ) { |
| 406 | 400 | foreach ( $indexables as &$indexable ) { |
| 407 | - switch ( $indexable->object_type ) { | |
| 408 | - case 'home-page': | |
| 409 | - $indexable->permalink = pll_home_url(); | |
| 410 | - $indexable->breadcrumb_title = pll__( WPSEO_Options::get( 'breadcrumbs-home' ) ); | |
| 411 | - break; | |
| 412 | - | |
| 413 | - case 'post-type-archive': | |
| 414 | - if ( pll_is_translated_post_type( $indexable->object_sub_type ) ) { | |
| 415 | - $indexable->permalink = get_post_type_archive_link( $indexable->object_sub_type ); | |
| 416 | - $indexable->breadcrumb_title = pll__( WPSEO_Options::get( 'bctitle-ptarchive-' . $indexable->object_sub_type ) ); | |
| 417 | - } | |
| 418 | - break; | |
| 401 | + if ( 'home-page' === $indexable->object_type || ( 'post' === $indexable->object_type && 'page' === $indexable->object_sub_type && get_option( 'page_on_front' ) === $indexable->object_id ) ) { | |
| 402 | + // Handles both when the front page displays the list of posts or a static page. | |
| 403 | + $indexable->permalink = pll_home_url(); | |
| 404 | + $indexable->breadcrumb_title = pll__( WPSEO_Options::get( 'breadcrumbs-home' ) ); | |
| 405 | + } elseif ( 'post' === $indexable->object_type && 'page' === $indexable->object_sub_type && get_option( 'page_for_posts' ) === $indexable->object_id ) { | |
| 406 | + $indexable->permalink = get_permalink( $indexable->object_id ); | |
| 407 | + } elseif ( 'post-type-archive' === $indexable->object_type && pll_is_translated_post_type( $indexable->object_sub_type ) ) { | |
| 408 | + $indexable->permalink = get_post_type_archive_link( $indexable->object_sub_type ); | |
| 409 | + $breadcrumb_title = WPSEO_Options::get( 'bctitle-ptarchive-' . $indexable->object_sub_type ); | |
| 410 | + $breadcrumb_title = $breadcrumb_title ?: $indexable->breadcrumb_title; // The option may be empty. | |
| 411 | + $indexable->breadcrumb_title = pll__( $breadcrumb_title ); | |
| 412 | + } elseif ( 'term' === $indexable->object_type && pll_is_translated_taxonomy( $indexable->object_sub_type ) ) { | |
| 413 | + $indexable->permalink = get_term_link( $indexable->object_id ); | |
| 419 | 414 | } |
| 420 | 415 | } |
| 421 | 416 | |
| 422 | 417 | return $indexables; |
| @@ -422,16 +417,32 @@ | ||
| 422 | 417 | return $indexables; |
| 423 | 418 | } |
| 424 | 419 | |
| 425 | 420 | /** |
| 426 | - * Synchronize the primary term | |
| 421 | + * Copies or synchronizes the metas. | |
| 427 | 422 | * |
| 428 | 423 | * @since 2.3.3 |
| 429 | 424 | * |
| 430 | - * @param array $keys List of custom fields names. | |
| 425 | + * @param string[] $keys List of custom fields names. | |
| 426 | + * @param bool $sync True if it is synchronization, false if it is a copy. | |
| 427 | + * @param int $from Id of the post from which we copy information. | |
| 428 | + * @param int $to Id of the post to which we paste information. | |
| 431 | 429 | * @return array |
| 432 | 430 | */ |
| 433 | - public function copy_post_metas( $keys ) { | |
| 431 | + public function copy_post_metas( $keys, $sync, $from, $to ) { | |
| 432 | + if ( ! $sync ) { | |
| 433 | + // Text requiring translation. | |
| 434 | + $keys = array_merge( $keys, $this->get_translatable_meta_keys() ); | |
| 435 | + | |
| 436 | + // Copy the image urls. | |
| 437 | + $keys[] = '_yoast_wpseo_opengraph-image'; | |
| 438 | + $keys[] = '_yoast_wpseo_twitter-image'; | |
| 439 | + | |
| 440 | + $keys[] = '_yoast_wpseo_meta-robots-noindex'; | |
| 441 | + $keys[] = '_yoast_wpseo_meta-robots-nofollow'; | |
| 442 | + $keys[] = '_yoast_wpseo_meta-robots-adv'; | |
| 443 | + } | |
| 444 | + | |
| 434 | 445 | $taxonomies = get_taxonomies( |
| 435 | 446 | array( |
| 436 | 447 | 'hierarchical' => true, |
| 437 | 448 | 'public' => true, |
| @@ -437,8 +448,12 @@ | ||
| 437 | 448 | 'public' => true, |
| 438 | 449 | ) |
| 439 | 450 | ); |
| 440 | 451 | |
| 452 | + $sync_taxonomies = PLL()->sync->taxonomies->get_taxonomies_to_copy( $sync, $from, $to ); | |
| 453 | + | |
| 454 | + $taxonomies = array_intersect( $taxonomies, $sync_taxonomies ); | |
| 455 | + | |
| 441 | 456 | foreach ( $taxonomies as $taxonomy ) { |
| 442 | 457 | $keys[] = '_yoast_wpseo_primary_' . $taxonomy; |
| 443 | 458 | } |
| 444 | 459 | |
| @@ -455,10 +470,48 @@ | ||
| 455 | 470 | * @param string $lang Language of target. |
| 456 | 471 | * @return int |
| 457 | 472 | */ |
| 458 | 473 | public function translate_post_meta( $value, $key, $lang ) { |
| 459 | - if ( false !== strpos( $key, '_yoast_wpseo_primary_' ) ) { | |
| 460 | - $value = pll_get_term( $value, $lang ); | |
| 474 | + if ( 0 !== strpos( $key, '_yoast_wpseo_primary_' ) ) { | |
| 475 | + return $value; | |
| 461 | 476 | } |
| 462 | - return $value; | |
| 477 | + | |
| 478 | + $taxonomy = str_replace( '_yoast_wpseo_primary_', '', $key ); | |
| 479 | + if ( ! PLL()->model->is_translated_taxonomy( $taxonomy ) ) { | |
| 480 | + return $value; | |
| 481 | + } | |
| 482 | + | |
| 483 | + return pll_get_term( $value, $lang ); | |
| 484 | + } | |
| 485 | + | |
| 486 | + /** | |
| 487 | + * Adds the yoast translatable metas to export. | |
| 488 | + * | |
| 489 | + * @param array $metas An array of post metas (keyed with meta keys) to export. | |
| 490 | + * @return array The modified array of post metas to export. | |
| 491 | + */ | |
| 492 | + public function export_post_metas( $metas ) { | |
| 493 | + $metas_to_export = array_fill_keys( $this->get_translatable_meta_keys(), 1 ); | |
| 494 | + | |
| 495 | + return array_merge( $metas, $metas_to_export ); | |
| 496 | + } | |
| 497 | + | |
| 498 | + /** | |
| 499 | + * Returns the meta keys with translatable text. | |
| 500 | + * | |
| 501 | + * @since 3.3 | |
| 502 | + * | |
| 503 | + * @return string[] | |
| 504 | + */ | |
| 505 | + protected function get_translatable_meta_keys() { | |
| 506 | + return array( | |
| 507 | + '_yoast_wpseo_title', | |
| 508 | + '_yoast_wpseo_metadesc', | |
| 509 | + '_yoast_wpseo_bctitle', | |
| 510 | + '_yoast_wpseo_focuskw', | |
| 511 | + '_yoast_wpseo_opengraph-title', | |
| 512 | + '_yoast_wpseo_opengraph-description', | |
| 513 | + '_yoast_wpseo_twitter-title', | |
| 514 | + '_yoast_wpseo_twitter-description', | |
| 515 | + ); | |
| 463 | 516 | } |
| 464 | 517 | } |