Polylang - Version 2.3.3

Version Description

(2018-03-15) =

  • Pro: Fix tax query using a term sharing slugs (fix a conflict with Fusion Builder)
  • Restore Polylang (free) on REST requests, while disabling the language filter as in v2.3
  • Rework auto translated query with taxonomy in different language #223
  • Synchronize Yoast SEO primary category (needs Yoast SEO 7.0+)
  • Fix PHP warning introduced by Yoast SEO 7.0 #229
  • Fix tax query when using the relation 'OR'
  • Fix a conflict with the combination of Barrel + WP Bakery Page Builder
  • Fix broken redirect with MU domain mapping #226
  • Fix site title not translated in password change email
Download this release

Release Info

Developer Chouby
Plugin Icon 128x128 Polylang
Version 2.3.3
Comparing to
See all releases

Code changes from version 2.3.2 to 2.3.3

frontend/frontend-auto-translate.php CHANGED
@@ -21,9 +21,7 @@ class PLL_Frontend_Auto_Translate {
21
  $this->curlang = &$polylang->curlang;
22
 
23
  add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); // after main Polylang filter
24
- add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
25
- add_action( 'parse_query', array( $this, 'remove_terms_filter' ) );
26
- add_action( 'posts_selection', array( $this, 'add_terms_filter' ) );
27
  }
28
 
29
  /**
@@ -104,7 +102,7 @@ class PLL_Frontend_Auto_Translate {
104
  if ( ! empty( $qv['tag'] ) ) {
105
  $sep = strpos( $qv['tag'], ',' ) !== false ? ',' : '+'; // Two possible separators for tag slugs
106
  foreach ( explode( $sep, $qv['tag'] ) as $slug ) {
107
- $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug;
108
  }
109
 
110
  $qv['tag'] = implode( $sep, $arr );
@@ -120,7 +118,7 @@ class PLL_Frontend_Auto_Translate {
120
  $arr = array();
121
  if ( ! empty( $qv[ $key ] ) ) {
122
  foreach ( $qv[ $key ] as $slug ) {
123
- $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, 'post_tag' ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_tag( $tr_id ) ) ) ? $tr->slug : $slug;
124
  }
125
 
126
  $qv[ $key ] = $arr;
@@ -135,7 +133,7 @@ class PLL_Frontend_Auto_Translate {
135
  if ( ! empty( $qv[ $tax->query_var ] ) ) {
136
  $sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // Two possible separators
137
  foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) {
138
- $arr[] = ( ( $tag = wpcom_vip_get_term_by( 'slug', $slug, $taxonomy ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) ? $tr->slug : $slug;
139
  }
140
 
141
  $qv[ $tax->query_var ] = implode( $sep, $arr );
@@ -225,26 +223,6 @@ class PLL_Frontend_Auto_Translate {
225
  return $args;
226
  }
227
 
228
- /**
229
- * Remove terms filter when doing a WP_Query
230
- * Needed since WP 4.9
231
- *
232
- * @since 2.3.2
233
- */
234
- public function remove_terms_filter() {
235
- remove_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
236
- }
237
-
238
- /**
239
- * Add terms filter back after a WP_Query
240
- * Needed since WP 4.9
241
- *
242
- * @since 2.3.2
243
- */
244
- public function add_terms_filter() {
245
- add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
246
- }
247
-
248
  /**
249
  * Translates tax queries
250
  * Compatible with nested tax queries introduced in WP 4.1
@@ -260,7 +238,7 @@ class PLL_Frontend_Auto_Translate {
260
  $arr = array();
261
  $field = isset( $q['field'] ) && in_array( $q['field'], array( 'slug', 'name' ) ) ? $q['field'] : 'term_id';
262
  foreach ( (array) $q['terms'] as $t ) {
263
- $arr[] = ( ( $tag = wpcom_vip_get_term_by( $field, $t, $q['taxonomy'] ) ) && ( $tr_id = $this->get_term( $tag->term_id ) ) && ! is_wp_error( $tr = get_term( $tr_id, $q['taxonomy'] ) ) ) ? $tr->$field : $t;
264
  }
265
 
266
  $tax_queries[ $key ]['terms'] = $arr;
@@ -274,4 +252,34 @@ class PLL_Frontend_Auto_Translate {
274
 
275
  return $tax_queries;
276
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  }
21
  $this->curlang = &$polylang->curlang;
22
 
23
  add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); // after main Polylang filter
24
+ add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 20, 2 );
 
 
25
  }
26
 
27
  /**
102
  if ( ! empty( $qv['tag'] ) ) {
103
  $sep = strpos( $qv['tag'], ',' ) !== false ? ',' : '+'; // Two possible separators for tag slugs
104
  foreach ( explode( $sep, $qv['tag'] ) as $slug ) {
105
+ $arr[] = $this->get_translated_term_by( 'slug', $slug, 'post_tag' );
106
  }
107
 
108
  $qv['tag'] = implode( $sep, $arr );
118
  $arr = array();
119
  if ( ! empty( $qv[ $key ] ) ) {
120
  foreach ( $qv[ $key ] as $slug ) {
121
+ $arr[] = $this->get_translated_term_by( 'slug', $slug, 'post_tag' );
122
  }
123
 
124
  $qv[ $key ] = $arr;
133
  if ( ! empty( $qv[ $tax->query_var ] ) ) {
134
  $sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // Two possible separators
135
  foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) {
136
+ $arr[] = $this->get_translated_term_by( 'slug', $slug, $taxonomy );
137
  }
138
 
139
  $qv[ $tax->query_var ] = implode( $sep, $arr );
223
  return $args;
224
  }
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  /**
227
  * Translates tax queries
228
  * Compatible with nested tax queries introduced in WP 4.1
238
  $arr = array();
239
  $field = isset( $q['field'] ) && in_array( $q['field'], array( 'slug', 'name' ) ) ? $q['field'] : 'term_id';
240
  foreach ( (array) $q['terms'] as $t ) {
241
+ $arr[] = $this->get_translated_term_by( $field, $t, $q['taxonomy'] );
242
  }
243
 
244
  $tax_queries[ $key ]['terms'] = $arr;
252
 
253
  return $tax_queries;
254
  }
255
+
256
+ /**
257
+ * Translates a term given one field.
258
+ *
259
+ * @since 2.3.3
260
+ *
261
+ * @param string $field Either 'slug', 'name', 'term_id', or 'term_taxonomy_id'
262
+ * @param string|int $term Search for this term value
263
+ * @param string $taxonomy Taxonomy name.
264
+ * @return string|int Translated term slug, name, term_id or term_taxonomy_id
265
+ */
266
+ protected function get_translated_term_by( $field, $term, $taxonomy ) {
267
+ if ( 'term_id' === $field ) {
268
+ if ( $tr_id = $this->get_term( $term ) ) {
269
+ return $tr_id;
270
+ }
271
+ } else {
272
+ $terms = get_terms( $taxonomy, array( $field => $term, 'lang' => '' ) );
273
+
274
+ if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
275
+ $t = reset( $terms );
276
+ $tr_id = $this->get_term( $t->term_id );
277
+
278
+ if ( ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) {
279
+ return $tr->$field;
280
+ }
281
+ }
282
+ }
283
+ return $term;
284
+ }
285
  }
frontend/frontend-filters.php CHANGED
@@ -132,10 +132,14 @@ class PLL_Frontend_Filters extends PLL_Filters {
132
  * @return array
133
  */
134
  public function get_terms_args( $args ) {
135
- if ( isset( $this->tax_query_lang ) ) {
136
- $args['lang'] = $this->tax_query_lang;
 
 
 
 
137
  }
138
- $lang = isset( $args['lang'] ) ? $args['lang'] : $this->curlang->slug;
139
  $key = '_' . ( is_array( $lang ) ? implode( ',', $lang ) : $lang );
140
  $args['cache_domain'] = empty( $args['cache_domain'] ) ? 'pll' . $key : $args['cache_domain'] . $key;
141
  return $args;
132
  * @return array
133
  */
134
  public function get_terms_args( $args ) {
135
+ if ( isset( $args['lang'] ) ) {
136
+ $lang = $args['lang'];
137
+ } elseif ( isset( $this->tax_query_lang ) ) {
138
+ $lang = $args['lang'] = empty( $this->tax_query_lang ) && ! empty( $args['slug'] ) ? $this->curlang->slug : $this->tax_query_lang;
139
+ } else {
140
+ $lang = $this->curlang->slug;
141
  }
142
+
143
  $key = '_' . ( is_array( $lang ) ? implode( ',', $lang ) : $lang );
144
  $args['cache_domain'] = empty( $args['cache_domain'] ) ? 'pll' . $key : $args['cache_domain'] . $key;
145
  return $args;
frontend/frontend-links.php CHANGED
@@ -162,7 +162,12 @@ class PLL_Frontend_Links extends PLL_Links {
162
  * @param string $language The language code of the translation
163
  */
164
  $translation_url = apply_filters( 'pll_translation_url', ( isset( $url ) && ! is_wp_error( $url ) ? $url : null ), $language->slug );
165
- $this->cache->set( 'translation_url:' . $language->slug, $translation_url );
 
 
 
 
 
166
  return $translation_url;
167
  }
168
 
162
  * @param string $language The language code of the translation
163
  */
164
  $translation_url = apply_filters( 'pll_translation_url', ( isset( $url ) && ! is_wp_error( $url ) ? $url : null ), $language->slug );
165
+
166
+ // Don't cache before template_redirect to avoid a conflict with Barrel + WP Bakery Page Builder
167
+ if ( did_action( 'template_redirect' ) ) {
168
+ $this->cache->set( 'translation_url:' . $language->slug, $translation_url );
169
+ }
170
+
171
  return $translation_url;
172
  }
173
 
frontend/frontend.php CHANGED
@@ -56,19 +56,25 @@ class PLL_Frontend extends PLL_Base {
56
  public function init() {
57
  $this->links = new PLL_Frontend_Links( $this );
58
 
59
- // Static front page and page for posts
60
- if ( 'page' === get_option( 'show_on_front' ) ) {
61
- $this->static_pages = new PLL_Frontend_Static_Pages( $this );
62
- }
 
 
 
 
 
63
 
64
- // Setup the language chooser
65
- $c = array( 'Content', 'Url', 'Url', 'Domain' );
66
- $class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ];
67
- $this->choose_lang = new $class( $this );
68
- $this->choose_lang->init();
69
 
70
- // Need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content
71
- $this->nav_menu = new PLL_Frontend_Nav_Menu( $this );
 
72
  }
73
 
74
  /**
56
  public function init() {
57
  $this->links = new PLL_Frontend_Links( $this );
58
 
59
+ // Don't set any language for REST requests when Polylang Pro is not active
60
+ if ( ! class_exists( 'PLL_REST_Translated_Object' ) && 0 === strpos( str_replace( 'index.php', '', $_SERVER['REQUEST_URI'] ), '/' . rest_get_url_prefix() . '/' ) ) {
61
+ /** This action is documented in include/class-polylang.php */
62
+ do_action( 'pll_no_language_defined' );
63
+ } else {
64
+ // Static front page and page for posts
65
+ if ( 'page' === get_option( 'show_on_front' ) ) {
66
+ $this->static_pages = new PLL_Frontend_Static_Pages( $this );
67
+ }
68
 
69
+ // Setup the language chooser
70
+ $c = array( 'Content', 'Url', 'Url', 'Domain' );
71
+ $class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ];
72
+ $this->choose_lang = new $class( $this );
73
+ $this->choose_lang->init();
74
 
75
+ // Need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content
76
+ $this->nav_menu = new PLL_Frontend_Nav_Menu( $this );
77
+ }
78
  }
79
 
80
  /**
include/class-polylang.php CHANGED
@@ -141,24 +141,6 @@ class Polylang {
141
  }
142
  }
143
 
144
- /**
145
- * Should we activate Polylang on front
146
- *
147
- * @since 2.3.2
148
- *
149
- * @param object $model
150
- * @return bool
151
- */
152
- protected function is_active_on_front( $model ) {
153
- // Do nothing on frontend if no language is defined
154
- // Or if it is a REST request and the compatibility class is not present
155
- return $model->get_languages_list() &&
156
- empty( $_GET['deactivate-polylang'] ) && (
157
- class_exists( 'PLL_REST_Translated_Object' ) ||
158
- false === strpos( str_replace( 'index.php', '', $_SERVER['REQUEST_URI'] ), '/' . rest_get_url_prefix() . '/' )
159
- );
160
- }
161
-
162
  /**
163
  * Polylang initialization
164
  * setups models and separate admin and frontend
@@ -196,9 +178,12 @@ class Polylang {
196
 
197
  if ( PLL_SETTINGS ) {
198
  $polylang = new PLL_Settings( $links_model );
199
- } elseif ( PLL_ADMIN ) {
 
200
  $polylang = new PLL_Admin( $links_model );
201
- } elseif ( $this->is_active_on_front( $model ) ) {
 
 
202
  $polylang = new PLL_Frontend( $links_model );
203
  }
204
 
141
  }
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Polylang initialization
146
  * setups models and separate admin and frontend
178
 
179
  if ( PLL_SETTINGS ) {
180
  $polylang = new PLL_Settings( $links_model );
181
+ }
182
+ elseif ( PLL_ADMIN ) {
183
  $polylang = new PLL_Admin( $links_model );
184
+ }
185
+ // Do nothing on frontend if no language is defined
186
+ elseif ( $model->get_languages_list() && empty( $_GET['deactivate-polylang'] ) ) {
187
  $polylang = new PLL_Frontend( $links_model );
188
  }
189
 
include/filters.php CHANGED
@@ -264,7 +264,7 @@ class PLL_Filters {
264
  * @return array
265
  */
266
  function translate_user_email( $email ) {
267
- $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
268
  $email['subject'] = sprintf( $email['subject'], $blog_name );
269
  $email['message'] = str_replace( '###SITENAME###', $blog_name, $email['message'] );
270
  return $email;
264
  * @return array
265
  */
266
  function translate_user_email( $email ) {
267
+ $blog_name = wp_specialchars_decode( pll__( get_option( 'blogname' ) ), ENT_QUOTES );
268
  $email['subject'] = sprintf( $email['subject'], $blog_name );
269
  $email['message'] = str_replace( '###SITENAME###', $blog_name, $email['message'] );
270
  return $email;
include/query.php CHANGED
@@ -90,12 +90,24 @@ class PLL_Query {
90
  */
91
  public function set_language( $lang ) {
92
  // Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
93
- $this->query->query_vars['tax_query'][] = array(
94
  'taxonomy' => 'language',
95
  'field' => 'term_taxonomy_id', // Since WP 3.5
96
  'terms' => $lang->term_taxonomy_id,
97
  'operator' => 'IN',
98
  );
 
 
 
 
 
 
 
 
 
 
 
 
99
  }
100
 
101
  /**
90
  */
91
  public function set_language( $lang ) {
92
  // Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
93
+ $lang_query = array(
94
  'taxonomy' => 'language',
95
  'field' => 'term_taxonomy_id', // Since WP 3.5
96
  'terms' => $lang->term_taxonomy_id,
97
  'operator' => 'IN',
98
  );
99
+
100
+ $tax_query = &$this->query->query_vars['tax_query'];
101
+
102
+ if ( isset( $tax_query['relation'] ) && 'OR' === $tax_query['relation'] ) {
103
+ $tax_query = array(
104
+ $lang_query,
105
+ array( $tax_query ),
106
+ 'relation' => 'AND',
107
+ );
108
+ } else {
109
+ $tax_query[] = $lang_query;
110
+ }
111
  }
112
 
113
  /**
modules/plugins/plugins-compat.php CHANGED
@@ -340,24 +340,26 @@ class PLL_Plugins_Compat {
340
  * @since 2.2
341
  */
342
  public function dm_redirect_to_mapped_domain() {
343
- // Don't redirect the main site
344
- if ( is_main_site() ) {
345
- return;
346
- }
347
 
348
- // Don't redirect post previews
349
- if ( isset( $_GET['preview'] ) && 'true' === $_GET['preview'] ) {
350
- return;
351
- }
 
 
352
 
353
- // Don't redirect theme customizer
354
- if ( isset( $_POST['customize'] ) && isset( $_POST['theme'] ) && 'on' === $_POST['customize'] ) {
355
- return;
356
- }
357
 
358
- // If we can't associate the requested domain to a language, redirect to the default domain
359
- $options = get_option( 'polylang' );
360
- if ( $options['force_lang'] > 1 ) {
 
 
 
361
  $hosts = PLL()->links_model->get_hosts();
362
  $lang = array_search( $_SERVER['HTTP_HOST'], $hosts );
363
 
@@ -368,5 +370,8 @@ class PLL_Plugins_Compat {
368
  exit;
369
  }
370
  }
 
 
 
371
  }
372
  }
340
  * @since 2.2
341
  */
342
  public function dm_redirect_to_mapped_domain() {
343
+ $options = get_option( 'polylang' );
 
 
 
344
 
345
+ // The language is set from the subdomain or domain name
346
+ if ( $options['force_lang'] > 1 ) {
347
+ // Don't redirect the main site
348
+ if ( is_main_site() ) {
349
+ return;
350
+ }
351
 
352
+ // Don't redirect post previews
353
+ if ( isset( $_GET['preview'] ) && 'true' === $_GET['preview'] ) {
354
+ return;
355
+ }
356
 
357
+ // Don't redirect theme customizer
358
+ if ( isset( $_POST['customize'] ) && isset( $_POST['theme'] ) && 'on' === $_POST['customize'] ) {
359
+ return;
360
+ }
361
+
362
+ // If we can't associate the requested domain to a language, redirect to the default domain
363
  $hosts = PLL()->links_model->get_hosts();
364
  $lang = array_search( $_SERVER['HTTP_HOST'], $hosts );
365
 
370
  exit;
371
  }
372
  }
373
+
374
+ // Otherwise rely on MU Domain Mapping
375
+ redirect_to_mapped_domain();
376
  }
377
  }
modules/plugins/wpseo.php CHANGED
@@ -16,65 +16,50 @@ class PLL_WPSEO {
16
  return;
17
  }
18
 
19
- if ( ! PLL() instanceof PLL_Frontend ) {
20
- add_action( 'admin_init', array( $this, 'wpseo_register_strings' ) );
21
- return;
22
- }
23
-
24
- add_filter( 'option_wpseo_titles', array( $this, 'wpseo_translate_titles' ) );
25
 
26
- // Reloads options once the language has been defined to enable translations
27
- // Useful only when the language is set from content
28
- if ( did_action( 'wp_loaded' ) ) {
29
- $wpseo_front = WPSEO_Frontend::get_instance();
30
- $options = WPSEO_Options::get_option_names();
31
- foreach ( $options as $opt ) {
32
- $wpseo_front->options = array_merge( $wpseo_front->options, (array) get_option( $opt ) );
 
33
  }
34
- }
35
 
36
- // Filters sitemap queries to remove inactive language or to get
37
- // one sitemap per language when using multiple domains or subdomains
38
- // because WPSEO does not accept several domains or subdomains in one sitemap
39
- add_filter( 'wpseo_posts_join', array( $this, 'wpseo_posts_join' ), 10, 2 );
40
- add_filter( 'wpseo_posts_where', array( $this, 'wpseo_posts_where' ), 10, 2 );
41
- add_filter( 'wpseo_typecount_join', array( $this, 'wpseo_posts_join' ), 10, 2 );
42
- add_filter( 'wpseo_typecount_where', array( $this, 'wpseo_posts_where' ), 10, 2 );
43
 
44
- if ( PLL()->options['force_lang'] > 1 ) {
45
- add_filter( 'wpseo_enable_xml_sitemap_transient_caching', '__return_false' ); // Disable cache! otherwise WPSEO keeps only one domain (thanks to Junaid Bhura)
46
- add_filter( 'home_url', array( $this, 'wpseo_home_url' ), 10, 2 ); // Fix home_url
47
- } else {
48
- // Get all terms in all languages when the language is set from the content or directory name
49
- add_filter( 'get_terms_args', array( $this, 'wpseo_remove_terms_filter' ) );
50
 
51
- // Add the homepages for all languages to the sitemap when the front page displays posts
52
- if ( ! get_option( 'page_on_front' ) ) {
53
- add_filter( 'wpseo_sitemap_post_content', array( $this, 'add_language_home_urls' ) );
 
54
  }
55
- }
56
 
57
- add_filter( 'pll_home_url_white_list', array( $this, 'wpseo_home_url_white_list' ) );
58
- add_action( 'wpseo_opengraph', array( $this, 'wpseo_ogp' ), 2 );
59
- add_filter( 'wpseo_canonical', array( $this, 'wpseo_canonical' ) );
60
- }
 
61
 
62
- /**
63
- * Helper function to register strings for custom post types and custom taxonomies titles and meta descriptions
64
- *
65
- * @since 2.1.6
66
- *
67
- * @param array $options
68
- * @param array $titles
69
- * @return array
70
- */
71
- protected function _wpseo_register_strings( $options, $titles ) {
72
- foreach ( $titles as $title ) {
73
- if ( ! empty( $options[ $title ] ) ) {
74
- pll_register_string( $title, $options[ $title ], 'wordpress-seo' );
75
- }
76
  }
77
- return $options;
78
  }
79
 
80
  /**
@@ -303,4 +288,52 @@ class PLL_WPSEO {
303
  public function wpseo_canonical( $url ) {
304
  return is_front_page( $url ) && get_option( 'permalink_structure' ) ? trailingslashit( $url ) : $url;
305
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  }
16
  return;
17
  }
18
 
19
+ if ( PLL() instanceof PLL_Frontend ) {
20
+ add_filter( 'option_wpseo_titles', array( $this, 'wpseo_translate_titles' ) );
 
 
 
 
21
 
22
+ // Reloads options once the language has been defined to enable translations
23
+ // Useful only when the language is set from content
24
+ if ( version_compare( WPSEO_VERSION, '7.0', '<' ) && did_action( 'wp_loaded' ) ) {
25
+ $wpseo_front = WPSEO_Frontend::get_instance();
26
+ $options = WPSEO_Options::get_option_names();
27
+ foreach ( $options as $opt ) {
28
+ $wpseo_front->options = array_merge( $wpseo_front->options, (array) get_option( $opt ) );
29
+ }
30
  }
 
31
 
32
+ // Filters sitemap queries to remove inactive language or to get
33
+ // one sitemap per language when using multiple domains or subdomains
34
+ // because WPSEO does not accept several domains or subdomains in one sitemap
35
+ add_filter( 'wpseo_posts_join', array( $this, 'wpseo_posts_join' ), 10, 2 );
36
+ add_filter( 'wpseo_posts_where', array( $this, 'wpseo_posts_where' ), 10, 2 );
37
+ add_filter( 'wpseo_typecount_join', array( $this, 'wpseo_posts_join' ), 10, 2 );
38
+ add_filter( 'wpseo_typecount_where', array( $this, 'wpseo_posts_where' ), 10, 2 );
39
 
40
+ if ( PLL()->options['force_lang'] > 1 ) {
41
+ add_filter( 'wpseo_enable_xml_sitemap_transient_caching', '__return_false' ); // Disable cache! otherwise WPSEO keeps only one domain (thanks to Junaid Bhura)
42
+ add_filter( 'home_url', array( $this, 'wpseo_home_url' ), 10, 2 ); // Fix home_url
43
+ } else {
44
+ // Get all terms in all languages when the language is set from the content or directory name
45
+ add_filter( 'get_terms_args', array( $this, 'wpseo_remove_terms_filter' ) );
46
 
47
+ // Add the homepages for all languages to the sitemap when the front page displays posts
48
+ if ( ! get_option( 'page_on_front' ) ) {
49
+ add_filter( 'wpseo_sitemap_post_content', array( $this, 'add_language_home_urls' ) );
50
+ }
51
  }
 
52
 
53
+ add_filter( 'pll_home_url_white_list', array( $this, 'wpseo_home_url_white_list' ) );
54
+ add_action( 'wpseo_opengraph', array( $this, 'wpseo_ogp' ), 2 );
55
+ add_filter( 'wpseo_canonical', array( $this, 'wpseo_canonical' ) );
56
+ } else {
57
+ add_action( 'admin_init', array( $this, 'wpseo_register_strings' ) );
58
 
59
+ // Primary category
60
+ add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ) );
61
+ add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
62
  }
 
63
  }
64
 
65
  /**
288
  public function wpseo_canonical( $url ) {
289
  return is_front_page( $url ) && get_option( 'permalink_structure' ) ? trailingslashit( $url ) : $url;
290
  }
291
+
292
+ /**
293
+ * Helper function to register strings for custom post types and custom taxonomies titles and meta descriptions
294
+ *
295
+ * @since 2.1.6
296
+ *
297
+ * @param array $options
298
+ * @param array $titles
299
+ * @return array
300
+ */
301
+ protected function _wpseo_register_strings( $options, $titles ) {
302
+ foreach ( $titles as $title ) {
303
+ if ( ! empty( $options[ $title ] ) ) {
304
+ pll_register_string( $title, $options[ $title ], 'wordpress-seo' );
305
+ }
306
+ }
307
+ return $options;
308
+ }
309
+
310
+ /**
311
+ * Synchronize the primary category
312
+ *
313
+ * @since 2.3.3
314
+ *
315
+ * @param array $keys List of custom fields names
316
+ * @return array
317
+ */
318
+ public function copy_post_metas( $keys ) {
319
+ $keys[] = '_yoast_wpseo_primary_category';
320
+ return $keys;
321
+ }
322
+
323
+ /**
324
+ * Translate the primary category during the synchronization process
325
+ *
326
+ * @since 2.3.3
327
+ *
328
+ * @param int $value Meta value
329
+ * @param string $key Meta key
330
+ * @param string $lang Language of target
331
+ * @return int
332
+ */
333
+ public function translate_post_meta( $value, $key, $lang ) {
334
+ if ( '_yoast_wpseo_primary_category' === $key ) {
335
+ $value = pll_get_term( $value, $lang );
336
+ }
337
+ return $value;
338
+ }
339
  }
polylang.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
- Version: 2.3.2
7
  Author: Frédéric Demarle
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
@@ -53,7 +53,7 @@ if ( defined( 'POLYLANG_BASENAME' ) ) {
53
  }
54
  } else {
55
  // Go on loading the plugin
56
- define( 'POLYLANG_VERSION', '2.3.2' );
57
  define( 'PLL_MIN_WP_VERSION', '4.4' );
58
 
59
  define( 'POLYLANG_FILE', __FILE__ ); // this file
3
  /**
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
+ Version: 2.3.3
7
  Author: Frédéric Demarle
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
53
  }
54
  } else {
55
  // Go on loading the plugin
56
+ define( 'POLYLANG_VERSION', '2.3.3' );
57
  define( 'PLL_MIN_WP_VERSION', '4.4' );
58
 
59
  define( 'POLYLANG_FILE', __FILE__ ); // this file
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://polylang.pro
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
5
  Requires at least: 4.4
6
  Tested up to: 4.9
7
- Stable tag: 2.3.2
8
  License: GPLv2 or later
9
 
10
  Making WordPress multilingual
@@ -41,7 +41,7 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
41
 
42
  == Installation ==
43
 
44
- 1. Make sure you are using WordPress 4.0 or later and that your server is running PHP 5.2.4 or later (same requirement as WordPress itself)
45
  1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
46
  1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
47
  1. Go to the languages settings page and create the languages you need
@@ -76,10 +76,23 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
76
 
77
  == Changelog ==
78
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  = 2.3.2 (2018-03-05) =
80
 
81
  * Pro: Fix REST requests not filtered by the requested language (introduced in 2.3).
82
  * Pro: Fix error 404 on single posts if posts are untranslatable
 
83
  * Fix translated terms unassigned from posts when deleting a term
84
  * Fix auto translated query with taxonomy in different language returning empty results since WP 4.9 #223
85
  * Fix conflict with a homepage option of the theme Extra
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
5
  Requires at least: 4.4
6
  Tested up to: 4.9
7
+ Stable tag: 2.3.3
8
  License: GPLv2 or later
9
 
10
  Making WordPress multilingual
41
 
42
  == Installation ==
43
 
44
+ 1. Make sure you are using WordPress 4.4 or later and that your server is running PHP 5.2.4 or later (same requirement as WordPress itself)
45
  1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
46
  1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
47
  1. Go to the languages settings page and create the languages you need
76
 
77
  == Changelog ==
78
 
79
+ = 2.3.3 (2018-03-15) =
80
+
81
+ * Pro: Fix tax query using a term sharing slugs (fix a conflict with Fusion Builder)
82
+ * Restore Polylang (free) on REST requests, while disabling the language filter as in v2.3
83
+ * Rework auto translated query with taxonomy in different language #223
84
+ * Synchronize Yoast SEO primary category (needs Yoast SEO 7.0+)
85
+ * Fix PHP warning introduced by Yoast SEO 7.0 #229
86
+ * Fix tax query when using the relation 'OR'
87
+ * Fix a conflict with the combination of Barrel + WP Bakery Page Builder
88
+ * Fix broken redirect with MU domain mapping #226
89
+ * Fix site title not translated in password change email
90
+
91
  = 2.3.2 (2018-03-05) =
92
 
93
  * Pro: Fix REST requests not filtered by the requested language (introduced in 2.3).
94
  * Pro: Fix error 404 on single posts if posts are untranslatable
95
+ * Deactivate Polylang (free) on REST requests by default.
96
  * Fix translated terms unassigned from posts when deleting a term
97
  * Fix auto translated query with taxonomy in different language returning empty results since WP 4.9 #223
98
  * Fix conflict with a homepage option of the theme Extra