Polylang - Version 3.1.3

Version Description

(2021-12-14) =

  • Fix user description escaping #934
  • Fix dismissable notice when creating a term in WP 5.9 #936
  • Fix empty search not handled correctly. Props Dominik Schilling #937
  • Fix warning occurring when a 3rd party plugin attempts to register anything else than a string using the WPML API #942
  • Fix Yoast SEO columns not corectly drawn when quick editing a post #943
Download this release

Release Info

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

Code changes from version 3.1.2 to 3.1.3

admin/admin-filters.php CHANGED
@@ -66,15 +66,13 @@ class PLL_Admin_Filters extends PLL_Filters {
66
  public function personal_options( $profileuser ) {
67
  foreach ( $this->model->get_languages_list() as $lang ) {
68
  $meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug;
69
-
70
- /** This filter is documented in wp-includes/user.php */
71
- $description = apply_filters( 'user_description', get_user_meta( $profileuser->ID, $meta, true ) ); // Applies WP default filter wp_kses_data
72
 
73
  printf(
74
  '<input type="hidden" class="biography" name="%s___%s" value="%s" />',
75
  esc_attr( $lang->slug ),
76
  esc_attr( $lang->name ),
77
- esc_attr( $description )
78
  );
79
  }
80
  }
66
  public function personal_options( $profileuser ) {
67
  foreach ( $this->model->get_languages_list() as $lang ) {
68
  $meta = $lang->slug == $this->options['default_lang'] ? 'description' : 'description_' . $lang->slug;
69
+ $description = get_user_meta( $profileuser->ID, $meta, true );
 
 
70
 
71
  printf(
72
  '<input type="hidden" class="biography" name="%s___%s" value="%s" />',
73
  esc_attr( $lang->slug ),
74
  esc_attr( $lang->name ),
75
+ sanitize_user_field( 'description', $description, $profileuser->ID, 'edit' )
76
  );
77
  }
78
  }
frontend/choose-lang.php CHANGED
@@ -305,16 +305,13 @@ abstract class PLL_Choose_Lang {
305
  if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) {
306
  $this->set_language( $lang );
307
  $this->set_curlang_in_query( $query );
308
- }
309
-
310
- // sets is_home on translated home page when it displays posts
311
- // is_home must be true on page 2, 3... too
312
- // as well as when searching an empty string: http://wordpress.org/support/topic/plugin-polylang-polylang-breaks-search-in-spun-theme
313
- elseif ( ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) || ( isset( $query->query['s'] ) && ! $query->query['s'] ) ) && $lang = get_query_var( 'lang' ) ) {
314
  $lang = $this->model->get_language( $lang );
315
- $this->set_language( $lang ); // sets the language now otherwise it will be too late to filter sticky posts !
316
  $query->is_home = true;
317
- $query->is_archive = $query->is_tax = false;
 
318
  }
319
  }
320
 
305
  if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) {
306
  $this->set_language( $lang );
307
  $this->set_curlang_in_query( $query );
308
+ } elseif ( ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) ) && $lang = get_query_var( 'lang' ) ) {
309
+ // Set is_home on translated home page when it displays posts. It must be true on page 2, 3... too.
 
 
 
 
310
  $lang = $this->model->get_language( $lang );
311
+ $this->set_language( $lang ); // Set the language now otherwise it will be too late to filter sticky posts!
312
  $query->is_home = true;
313
+ $query->is_tax = false;
314
+ $query->is_archive = false;
315
  }
316
  }
317
 
include/model.php CHANGED
@@ -91,7 +91,6 @@ class PLL_Model {
91
  array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
92
 
93
  if ( ! empty( $languages ) && ! empty( $term_languages ) ) {
94
- // Don't use array_map + create_function() to instantiate an autoloaded class as it breaks badly in old versions of PHP.
95
  foreach ( $languages as $k => $v ) {
96
  $languages[ $k ] = new PLL_Language( $v, $term_languages[ 'pll_' . $v->slug ] );
97
  }
91
  array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
92
 
93
  if ( ! empty( $languages ) && ! empty( $term_languages ) ) {
 
94
  foreach ( $languages as $k => $v ) {
95
  $languages[ $k ] = new PLL_Language( $v, $term_languages[ 'pll_' . $v->slug ] );
96
  }
integrations/wpseo/wpseo.php CHANGED
@@ -50,6 +50,11 @@ class PLL_WPSEO {
50
  } else {
51
  add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 2 );
52
  add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 );
 
 
 
 
 
53
  }
54
  }
55
 
50
  } else {
51
  add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 2 );
52
  add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 );
53
+
54
+ // Yoast SEO adds the columns hooks only for the 'inline-save' action. We need them for 'pll_update_post_rows' too.
55
+ if ( wp_doing_ajax() && isset( $_POST['action'] ) && 'pll_update_post_rows' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
56
+ $GLOBALS['wpseo_meta_columns'] = new WPSEO_Meta_Columns();
57
+ }
58
  }
59
  }
60
 
js/build/post.js CHANGED
@@ -133,7 +133,9 @@ jQuery(
133
  data,
134
  function( response ) {
135
  if ( response ) {
136
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
 
 
137
  $.each(
138
  res.responses,
139
  function() {
133
  data,
134
  function( response ) {
135
  if ( response ) {
136
+ // Since WP changeset #52710 parseAjaxReponse() return content to notice the user in a HTML tag with ajax-response id.
137
+ // Not to disturb this behaviour by executing another ajax request in the ajaxSuccess event, we need to target another unexisting id.
138
+ var res = wpAjax.parseAjaxResponse( response, 'pll-ajax-response' );
139
  $.each(
140
  res.responses,
141
  function() {
js/build/post.min.js CHANGED
@@ -1 +1 @@
1
- var __webpack_exports__={};jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)}))})),jQuery((function(a){a(document).on("DOMNodeInserted",(function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),p(o),i.on("change",(function(){l(a(this).val()),p(a(this).val())}))}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,(function(t,e){a.each(e,(function(e,i){a.each(i,(function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()}))}))}))}function p(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,(function(t,e){a.each(e,(function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()}))}))}}))})),jQuery((function(a){a(document).ajaxSuccess((function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each((function(){t.push(a(this).parent().parent().attr("id").substring(5))}));var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,(function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(t.responses,(function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)}))}));
1
+ var __webpack_exports__={};jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)}))})),jQuery((function(a){a(document).on("DOMNodeInserted",(function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),p(o),i.on("change",(function(){l(a(this).val()),p(a(this).val())}))}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,(function(t,e){a.each(e,(function(e,i){a.each(i,(function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()}))}))}))}function p(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,(function(t,e){a.each(e,(function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()}))}))}}))})),jQuery((function(a){a(document).ajaxSuccess((function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each((function(){t.push(a(this).parent().parent().attr("id").substring(5))}));var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,(function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"pll-ajax-response");a.each(t.responses,(function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)}))}));
js/build/term.js CHANGED
@@ -68,7 +68,9 @@ jQuery(
68
  data,
69
  function( response ) {
70
  if ( response ) {
71
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
 
 
72
  $.each(
73
  res.responses,
74
  function() {
68
  data,
69
  function( response ) {
70
  if ( response ) {
71
+ // Since WP changeset #52710 parseAjaxReponse() return content to notice the user in a HTML tag with ajax-response id.
72
+ // Not to disturb this behaviour by executing another ajax request in the ajaxSuccess event, we need to target another unexisting id.
73
+ var res = wpAjax.parseAjaxResponse( response, 'pll-ajax-response' );
74
  $.each(
75
  res.responses,
76
  function() {
js/build/term.min.js CHANGED
@@ -1 +1 @@
1
- var __webpack_exports__={};jQuery((function(a){a(document).on("DOMNodeInserted",(function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i),e==a("#default_cat_"+e).html()&&l.prop("disabled",!0)}}}))})),jQuery((function(a){a(document).ajaxSuccess((function(t,n,e){function l(t){var n=new Array;a(".translation_"+t).each((function(){n.push(a(this).parent().parent().attr("id").substring(4))}));var e={action:"pll_update_term_rows",term_id:t,translations:n.join(","),taxonomy:a("input[name='taxonomy']").val(),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,e,(function(t){if(t){var n=wpAjax.parseAjaxResponse(t,"ajax-response");a.each(n.responses,(function(){"row"==this.what&&a("#tag-"+this.supplemental.term_id).replaceWith(this.data)}))}}))}var i=wpAjax.unserialize(e.data);if(void 0!==i.action)switch(i.action){case"add-tag":res=wpAjax.parseAjaxResponse(n.responseXML,"ajax-response"),a.each(res.responses,(function(){"term"==this.what&&l(this.supplemental.term_id)})),a(".htr_lang").val(0);break;case"delete-tag":l(i.tag_ID);break;case"inline-save-tax":l(i.tax_ID)}}))})),jQuery((function(a){function t(){a(".tr_lang").each((function(){var t=a(this).attr("id").substring(8),n=a(this).parent().parent().siblings(".pll-edit-column");a(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_terms_not_translated&term_language="+a("#term_lang_choice").val()+"&term_id="+a("input[name='tag_ID']").val()+"&taxonomy="+a("input[name='taxonomy']").val()+"&translation_language="+t+"&post_type="+typenow+"&_pll_nonce="+a("#_pll_nonce").val(),select:function(e,l){a("#htr_lang_"+t).val(l.item.id),n.html(l.item.link)}}),a(this).on("blur",(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))}))}))}t(),a("#term_lang_choice").on("change",(function(){var n=a(this).val(),e=a(this).children('option[value="'+n+'"]').attr("lang"),l=a('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),i={action:"term_lang_choice",lang:n,from_tag:a("input[name='from_tag']").val(),term_id:a("input[name='tag_ID']").val(),taxonomy:a("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,i,(function(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(e.responses,(function(){switch(this.what){case"translations":a("#term-translations").html(this.data),t();break;case"parent":a("#parent").replaceWith(this.data);break;case"tag_cloud":a(".tagcloud").replaceWith(this.data);break;case"flag":a(".pll-select-flag").html(this.data)}})),a("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)}))}))}));
1
+ var __webpack_exports__={};jQuery((function(a){a(document).on("DOMNodeInserted",(function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i),e==a("#default_cat_"+e).html()&&l.prop("disabled",!0)}}}))})),jQuery((function(a){a(document).ajaxSuccess((function(t,n,e){function l(t){var n=new Array;a(".translation_"+t).each((function(){n.push(a(this).parent().parent().attr("id").substring(4))}));var e={action:"pll_update_term_rows",term_id:t,translations:n.join(","),taxonomy:a("input[name='taxonomy']").val(),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,e,(function(t){if(t){var n=wpAjax.parseAjaxResponse(t,"pll-ajax-response");a.each(n.responses,(function(){"row"==this.what&&a("#tag-"+this.supplemental.term_id).replaceWith(this.data)}))}}))}var i=wpAjax.unserialize(e.data);if(void 0!==i.action)switch(i.action){case"add-tag":res=wpAjax.parseAjaxResponse(n.responseXML,"ajax-response"),a.each(res.responses,(function(){"term"==this.what&&l(this.supplemental.term_id)})),a(".htr_lang").val(0);break;case"delete-tag":l(i.tag_ID);break;case"inline-save-tax":l(i.tax_ID)}}))})),jQuery((function(a){function t(){a(".tr_lang").each((function(){var t=a(this).attr("id").substring(8),n=a(this).parent().parent().siblings(".pll-edit-column");a(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_terms_not_translated&term_language="+a("#term_lang_choice").val()+"&term_id="+a("input[name='tag_ID']").val()+"&taxonomy="+a("input[name='taxonomy']").val()+"&translation_language="+t+"&post_type="+typenow+"&_pll_nonce="+a("#_pll_nonce").val(),select:function(e,l){a("#htr_lang_"+t).val(l.item.id),n.html(l.item.link)}}),a(this).on("blur",(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))}))}))}t(),a("#term_lang_choice").on("change",(function(){var n=a(this).val(),e=a(this).children('option[value="'+n+'"]').attr("lang"),l=a('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),i={action:"term_lang_choice",lang:n,from_tag:a("input[name='from_tag']").val(),term_id:a("input[name='tag_ID']").val(),taxonomy:a("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,i,(function(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(e.responses,(function(){switch(this.what){case"translations":a("#term-translations").html(this.data),t();break;case"parent":a("#parent").replaceWith(this.data);break;case"tag_cloud":a(".tagcloud").replaceWith(this.data);break;case"flag":a(".pll-select-flag").html(this.data)}})),a("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)}))}))}));
modules/wpml/wpml-compat.php CHANGED
@@ -103,6 +103,10 @@ class PLL_WPML_Compat {
103
  * @return void
104
  */
105
  public function register_string( $context, $name, $string ) {
 
 
 
 
106
  // If a string has already been registered with the same name and context, let's replace it.
107
  $exist_string = $this->get_string_by_context_and_name( $context, $name );
108
  if ( $exist_string && $exist_string !== $string ) {
@@ -122,7 +126,7 @@ class PLL_WPML_Compat {
122
 
123
  // Registers the string if it does not exist yet (multiline as in WPML).
124
  $to_register = array( 'context' => $context, 'name' => $name, 'string' => $string, 'multiline' => true, 'icl' => true );
125
- if ( ! in_array( $to_register, self::$strings ) && $to_register['string'] ) {
126
  $key = md5( "$context | $name" );
127
  self::$strings[ $key ] = $to_register;
128
  update_option( 'polylang_wpml_strings', self::$strings );
103
  * @return void
104
  */
105
  public function register_string( $context, $name, $string ) {
106
+ if ( ! $string || ! is_scalar( $string ) ) {
107
+ return;
108
+ }
109
+
110
  // If a string has already been registered with the same name and context, let's replace it.
111
  $exist_string = $this->get_string_by_context_and_name( $context, $name );
112
  if ( $exist_string && $exist_string !== $string ) {
126
 
127
  // Registers the string if it does not exist yet (multiline as in WPML).
128
  $to_register = array( 'context' => $context, 'name' => $name, 'string' => $string, 'multiline' => true, 'icl' => true );
129
+ if ( ! in_array( $to_register, self::$strings ) ) {
130
  $key = md5( "$context | $name" );
131
  self::$strings[ $key ] = $to_register;
132
  update_option( 'polylang_wpml_strings', self::$strings );
polylang.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: Polylang
11
  * Plugin URI: https://polylang.pro
12
  * Description: Adds multilingual capability to WordPress
13
- * Version: 3.1.2
14
  * Requires at least: 5.4
15
  * Requires PHP: 5.6
16
  * Author: WP SYNTEX
@@ -53,7 +53,7 @@ if ( defined( 'POLYLANG_VERSION' ) ) {
53
  }
54
  } else {
55
  // Go on loading the plugin
56
- define( 'POLYLANG_VERSION', '3.1.2' );
57
  define( 'PLL_MIN_WP_VERSION', '5.4' );
58
  define( 'PLL_MIN_PHP_VERSION', '5.6' );
59
 
10
  * Plugin Name: Polylang
11
  * Plugin URI: https://polylang.pro
12
  * Description: Adds multilingual capability to WordPress
13
+ * Version: 3.1.3
14
  * Requires at least: 5.4
15
  * Requires PHP: 5.6
16
  * Author: WP SYNTEX
53
  }
54
  } else {
55
  // Go on loading the plugin
56
+ define( 'POLYLANG_VERSION', '3.1.3' );
57
  define( 'PLL_MIN_WP_VERSION', '5.4' );
58
  define( 'PLL_MIN_PHP_VERSION', '5.6' );
59
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: multilingual, bilingual, translate, translation, language, multilanguage,
5
  Requires at least: 5.4
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
- Stable tag: 3.1.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -78,6 +78,14 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
78
 
79
  == Changelog ==
80
 
 
 
 
 
 
 
 
 
81
  = 3.1.2 (2021-10-11) =
82
 
83
  * Pro: Fix parent page not filtered by language in the block editor since WP 5.6
5
  Requires at least: 5.4
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
+ Stable tag: 3.1.3
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
78
 
79
  == Changelog ==
80
 
81
+ = 3.1.3 (2021-12-14) =
82
+
83
+ * Fix user description escaping #934
84
+ * Fix dismissable notice when creating a term in WP 5.9 #936
85
+ * Fix empty search not handled correctly. Props Dominik Schilling #937
86
+ * Fix warning occurring when a 3rd party plugin attempts to register anything else than a string using the WPML API #942
87
+ * Fix Yoast SEO columns not corectly drawn when quick editing a post #943
88
+
89
  = 3.1.2 (2021-10-11) =
90
 
91
  * Pro: Fix parent page not filtered by language in the block editor since WP 5.6