Polylang - Version 2.0.3

Version Description

(2016-08-16) =

  • Pro: Fix PHP notice when hiding the language code in url and the language is set from subdomains
  • Pro: Fix one more media being created when the duplicate media in all languages is activated (introduced in 2.0)
  • Pro: Fix shared term slugs not working on PHP 7
  • Pro: Fix Polylang storing integers in some ACF Pro fields where ACF Pro stores strings
  • Pro: Fix ACF Pro custom fields synchronized even when the custom fields synchronization option is deactivated (#40)
  • Fix PHP notice: Undefined variable: original_value in /modules/wpml/wpml-api.php on line 168
  • Fix translations loaded too soon by plugins not correctly reloaded since WP 4.6 (#39)
  • Fix: Remove the delete link for translations of the default category on PHP 7
  • Fix unescaped i18n strings in Lingotek presentation
Download this release

Release Info

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

Code changes from version 2.0.2 to 2.0.3

admin/admin-filters-term.php CHANGED
@@ -632,20 +632,21 @@ class PLL_Admin_Filters_Term {
632
  */
633
  public function option_default_category( $value ) {
634
  $traces = debug_backtrace();
 
635
 
636
- if ( isset( $traces[4] ) ) {
637
  // FIXME 'column_name' for backward compatibility with WP < 4.3
638
- if ( in_array( $traces[4]['function'], array( 'column_cb', 'column_name', 'handle_row_actions' ) ) && in_array( $traces[4]['args'][0]->term_id, $this->model->term->get_translations( $value ) ) ) {
639
- return $traces[4]['args'][0]->term_id;
640
  }
641
 
642
- if ( 'wp_delete_term' == $traces[4]['function'] ) {
643
- return $this->model->term->get( $value, $this->model->term->get_language( $traces[4]['args'][0] ) );
644
  }
645
  }
646
 
647
  // Filters the default category in note below the category list table and in settings->writing dropdown
648
- elseif ( isset( $traces[3]['file'] ) && ( false !== stripos( $traces[3]['file'], 'edit-tags.php' ) || false !== stripos( $traces[3]['file'], 'options-writing.php' ) ) ) {
649
  return $this->model->term->get( $value, $this->pref_lang );
650
  }
651
 
632
  */
633
  public function option_default_category( $value ) {
634
  $traces = debug_backtrace();
635
+ $n = version_compare( PHP_VERSION, '7', '>=' ) ? 3 : 4; // PHP 7 does not include call_user_func_array
636
 
637
+ if ( isset( $traces[ $n ] ) ) {
638
  // FIXME 'column_name' for backward compatibility with WP < 4.3
639
+ if ( in_array( $traces[ $n ]['function'], array( 'column_cb', 'column_name', 'handle_row_actions' ) ) && in_array( $traces[ $n ]['args'][0]->term_id, $this->model->term->get_translations( $value ) ) ) {
640
+ return $traces[ $n ]['args'][0]->term_id;
641
  }
642
 
643
+ if ( 'wp_delete_term' == $traces[ $n ]['function'] ) {
644
+ return $this->model->term->get( $value, $this->model->term->get_language( $traces[ $n ]['args'][0] ) );
645
  }
646
  }
647
 
648
  // Filters the default category in note below the category list table and in settings->writing dropdown
649
+ elseif ( isset( $traces[ $n - 1 ]['file'] ) && ( false !== stripos( $traces[ $n - 1 ]['file'], 'edit-tags.php' ) || false !== stripos( $traces[ $n - 1 ]['file'], 'options-writing.php' ) ) ) {
650
  return $this->model->term->get( $value, $this->pref_lang );
651
  }
652
 
frontend/frontend-filters-links.php CHANGED
@@ -282,7 +282,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
282
  }
283
 
284
  $traces = version_compare( PHP_VERSION, '5.2.5', '>=' ) ? debug_backtrace( false ) : debug_backtrace();
285
- unset( $traces[0], $traces[1], $traces[2] ); // we don't need the last 3 calls (this function + apply_filters)
286
 
287
  foreach ( $traces as $trace ) {
288
  // black list first
282
  }
283
 
284
  $traces = version_compare( PHP_VERSION, '5.2.5', '>=' ) ? debug_backtrace( false ) : debug_backtrace();
285
+ unset( $traces[0], $traces[1] ); // We don't need the last 2 calls: this function + call_user_func_array (or apply_filters on PHP7+)
286
 
287
  foreach ( $traces as $trace ) {
288
  // black list first
include/api.php CHANGED
@@ -124,7 +124,7 @@ function pll_register_string( $name, $string, $context = 'polylang', $multiline
124
  function pll__( $string ) {
125
  static $cache; // Cache object to avoid translating the same string several times
126
 
127
- if ( ! did_action( 'pll_language_defined' ) ) { // No need for translation
128
  return $string;
129
  }
130
 
@@ -165,6 +165,10 @@ function pll_translate_string( $string, $lang ) {
165
  return pll__( $string );
166
  }
167
 
 
 
 
 
168
  static $cache; // Cache object to avoid loading the same translations object several times
169
 
170
  if ( empty( $cache ) ) {
124
  function pll__( $string ) {
125
  static $cache; // Cache object to avoid translating the same string several times
126
 
127
+ if ( ! did_action( 'pll_language_defined' ) || ! is_scalar( $string ) ) { // No need for translation
128
  return $string;
129
  }
130
 
165
  return pll__( $string );
166
  }
167
 
168
+ if ( ! is_scalar( $string ) ) {
169
+ return $string;
170
+ }
171
+
172
  static $cache; // Cache object to avoid loading the same translations object several times
173
 
174
  if ( empty( $cache ) ) {
include/olt-manager.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * it is best practice that plugins do nothing before plugins_loaded is fired
5
  * so it is what Polylang intends to do
6
  * but some plugins load their text domain as soon as loaded, thus before plugins_loaded is fired
7
  * this class differs text domain loading until the language is defined
@@ -10,36 +10,36 @@
10
  * @since 1.2
11
  */
12
  class PLL_OLT_Manager {
13
- static protected $instance; // for singleton
14
  protected $default_locale;
15
- protected $list_textdomains = array(); // all text domains
16
- public $labels = array(); // post types and taxonomies labels to translate
17
 
18
  /**
19
- * constructor: setups relevant filters
20
  *
21
  * @since 1.2
22
  */
23
  public function __construct() {
24
- // saves the default locale before we start any language manipulation
25
  $this->default_locale = get_locale();
26
 
27
- // filters for text domain management
28
  add_filter( 'override_load_textdomain', array( $this, 'mofile' ), 10, 3 );
29
  add_filter( 'gettext', array( $this, 'gettext' ), 10, 3 );
30
  add_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 );
31
 
32
- // loads text domains
33
- add_action( 'pll_language_defined', array( $this, 'load_textdomains' ), 2 ); // after PLL_Frontend::pll_language_defined
34
  add_action( 'pll_no_language_defined', array( $this, 'load_textdomains' ) );
35
 
36
- // allows Polylang to be the first plugin loaded ;- )
37
  add_filter( 'pre_update_option_active_plugins', array( $this, 'make_polylang_first' ) );
38
  add_filter( 'pre_update_option_active_sitewide_plugins', array( $this, 'make_polylang_first' ) );
39
  }
40
 
41
  /**
42
- * access to the single instance of the class
43
  *
44
  * @since 1.7
45
  *
@@ -54,43 +54,44 @@ class PLL_OLT_Manager {
54
  }
55
 
56
  /**
57
- * loads text domains
58
  *
59
  * @since 0.1
60
  */
61
  public function load_textdomains() {
62
- // our override_load_textdomain filter has done its job. let's remove it before calling load_textdomain
63
  remove_filter( 'override_load_textdomain', array( $this, 'mofile' ), 10, 3 );
64
  remove_filter( 'gettext', array( $this, 'gettext' ), 10, 3 );
65
  remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 );
66
  $new_locale = get_locale();
67
 
68
- // don't try to save time for en_US as some users have theme written in another language
69
- // now we can load all overriden text domains with the right language
70
  if ( ! empty( $this->list_textdomains ) ) {
71
  foreach ( $this->list_textdomains as $textdomain ) {
 
72
  if ( ! load_textdomain( $textdomain['domain'], str_replace( "{$this->default_locale}.mo", "$new_locale.mo", $textdomain['mo'] ) ) ) {
73
- // since WP 3.5 themes may store languages files in /wp-content/languages/themes
74
  if ( ! load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/themes/{$textdomain['domain']}-$new_locale.mo" ) ) {
75
- // since WP 3.7 plugins may store languages files in /wp-content/languages/plugins
76
  load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/plugins/{$textdomain['domain']}-$new_locale.mo" );
77
  }
78
  }
79
  }
80
  }
81
 
82
- // first remove taxonomies and post_types labels that we don't need to translate
83
  $taxonomies = array( 'language', 'term_language', 'term_translations', 'post_translations' );
84
  $post_types = array( 'polylang_mo' );
85
 
86
- // we don't need to translate core taxonomies and post types labels when setting the language from the url
87
- // as they will be translated when registered the second time
88
  if ( ! did_action( 'setup_theme' ) ) {
89
  $taxonomies = array_merge( array( 'category', 'post_tag', 'nav_menu', 'link_category', 'post_format' ), $taxonomies );
90
  $post_types = array_merge( array( 'post', 'page', 'attachment', 'revision', 'nav_menu_item' ), $post_types );
91
  }
92
 
93
- // translate labels of post types and taxonomies
94
  foreach ( array_diff_key( $GLOBALS['wp_taxonomies'], array_flip( $taxonomies ) ) as $tax ) {
95
  $this->translate_labels( $tax );
96
  }
@@ -98,9 +99,9 @@ class PLL_OLT_Manager {
98
  $this->translate_labels( $pt );
99
  }
100
 
101
- // act only if the language has not been set early ( before default textdomain loading and $wp_locale creation )
102
  if ( did_action( 'after_setup_theme' ) ) {
103
- // reinitializes wp_locale for weekdays and months
104
  unset( $GLOBALS['wp_locale'] );
105
  $GLOBALS['wp_locale'] = new WP_Locale();
106
  }
@@ -115,27 +116,30 @@ class PLL_OLT_Manager {
115
  */
116
  do_action_ref_array( 'pll_translate_labels', array( &$this->labels ) );
117
 
118
- // free memory
119
  unset( $this->default_locale, $this->list_textdomains, $this->labels );
120
  }
121
 
122
  /**
123
- * saves all text domains in a table for later usage
124
  *
125
  * @since 0.1
126
  *
127
  * @param bool $bool not used
128
  * @param string $domain text domain name
129
  * @param string $mofile translation file name
130
- * @return bool always true
131
  */
132
  public function mofile( $bool, $domain, $mofile ) {
133
- $this->list_textdomains[] = array( 'mo' => $mofile, 'domain' => $domain );
134
- return true; // prevents WP loading text domains as we will load them all later
 
 
 
135
  }
136
 
137
  /**
138
- * saves post types and taxonomies labels for a later usage
139
  *
140
  * @since 0.9
141
  *
@@ -145,14 +149,14 @@ class PLL_OLT_Manager {
145
  * @return string unmodified $translation
146
  */
147
  public function gettext( $translation, $text, $domain ) {
148
- if ( is_string( $text ) ) { // avoid a warning with some buggy plugins which pass an array
149
  $this->labels[ $text ] = array( 'domain' => $domain );
150
  }
151
  return $translation;
152
  }
153
 
154
  /**
155
- * saves post types and taxonomies labels for a later usage
156
  *
157
  * @since 0.9
158
  *
@@ -168,14 +172,14 @@ class PLL_OLT_Manager {
168
  }
169
 
170
  /**
171
- * translates post types and taxonomies labels once the language is known
172
  *
173
  * @since 0.9
174
  *
175
  * @param object $type either a post type or a taxonomy
176
  */
177
  public function translate_labels( $type ) {
178
- // use static array to avoid translating several times the same ( default ) labels
179
  static $translated = array();
180
 
181
  foreach ( $type->labels as $key => $label ) {
@@ -193,7 +197,7 @@ class PLL_OLT_Manager {
193
  }
194
 
195
  /**
196
- * allows Polylang to be the first plugin loaded ;- )
197
  *
198
  * @since 1.2
199
  *
1
  <?php
2
 
3
  /**
4
+ * It is best practice that plugins do nothing before plugins_loaded is fired
5
  * so it is what Polylang intends to do
6
  * but some plugins load their text domain as soon as loaded, thus before plugins_loaded is fired
7
  * this class differs text domain loading until the language is defined
10
  * @since 1.2
11
  */
12
  class PLL_OLT_Manager {
13
+ static protected $instance; // For singleton
14
  protected $default_locale;
15
+ protected $list_textdomains = array(); // All text domains
16
+ public $labels = array(); // Post types and taxonomies labels to translate
17
 
18
  /**
19
+ * Constructor: setups relevant filters
20
  *
21
  * @since 1.2
22
  */
23
  public function __construct() {
24
+ // Saves the default locale before we start any language manipulation
25
  $this->default_locale = get_locale();
26
 
27
+ // Filters for text domain management
28
  add_filter( 'override_load_textdomain', array( $this, 'mofile' ), 10, 3 );
29
  add_filter( 'gettext', array( $this, 'gettext' ), 10, 3 );
30
  add_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 );
31
 
32
+ // Loads text domains
33
+ add_action( 'pll_language_defined', array( $this, 'load_textdomains' ), 2 ); // After PLL_Frontend::pll_language_defined
34
  add_action( 'pll_no_language_defined', array( $this, 'load_textdomains' ) );
35
 
36
+ // Allows Polylang to be the first plugin loaded ;-)
37
  add_filter( 'pre_update_option_active_plugins', array( $this, 'make_polylang_first' ) );
38
  add_filter( 'pre_update_option_active_sitewide_plugins', array( $this, 'make_polylang_first' ) );
39
  }
40
 
41
  /**
42
+ * Access to the single instance of the class
43
  *
44
  * @since 1.7
45
  *
54
  }
55
 
56
  /**
57
+ * Loads text domains
58
  *
59
  * @since 0.1
60
  */
61
  public function load_textdomains() {
62
+ // Our override_load_textdomain filter has done its job. let's remove it before calling load_textdomain
63
  remove_filter( 'override_load_textdomain', array( $this, 'mofile' ), 10, 3 );
64
  remove_filter( 'gettext', array( $this, 'gettext' ), 10, 3 );
65
  remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ), 10, 4 );
66
  $new_locale = get_locale();
67
 
68
+ // Don't try to save time for en_US as some users have theme written in another language
69
+ // Now we can load all overriden text domains with the right language
70
  if ( ! empty( $this->list_textdomains ) ) {
71
  foreach ( $this->list_textdomains as $textdomain ) {
72
+ // FIXME: Since WP 4.6, plugins translations are first loaded from wp-content/languages
73
  if ( ! load_textdomain( $textdomain['domain'], str_replace( "{$this->default_locale}.mo", "$new_locale.mo", $textdomain['mo'] ) ) ) {
74
+ // Since WP 3.5 themes may store languages files in /wp-content/languages/themes
75
  if ( ! load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/themes/{$textdomain['domain']}-$new_locale.mo" ) ) {
76
+ // Since WP 3.7 plugins may store languages files in /wp-content/languages/plugins
77
  load_textdomain( $textdomain['domain'], WP_LANG_DIR . "/plugins/{$textdomain['domain']}-$new_locale.mo" );
78
  }
79
  }
80
  }
81
  }
82
 
83
+ // First remove taxonomies and post_types labels that we don't need to translate
84
  $taxonomies = array( 'language', 'term_language', 'term_translations', 'post_translations' );
85
  $post_types = array( 'polylang_mo' );
86
 
87
+ // We don't need to translate core taxonomies and post types labels when setting the language from the url
88
+ // As they will be translated when registered the second time
89
  if ( ! did_action( 'setup_theme' ) ) {
90
  $taxonomies = array_merge( array( 'category', 'post_tag', 'nav_menu', 'link_category', 'post_format' ), $taxonomies );
91
  $post_types = array_merge( array( 'post', 'page', 'attachment', 'revision', 'nav_menu_item' ), $post_types );
92
  }
93
 
94
+ // Translate labels of post types and taxonomies
95
  foreach ( array_diff_key( $GLOBALS['wp_taxonomies'], array_flip( $taxonomies ) ) as $tax ) {
96
  $this->translate_labels( $tax );
97
  }
99
  $this->translate_labels( $pt );
100
  }
101
 
102
+ // Act only if the language has not been set early ( before default textdomain loading and $wp_locale creation )
103
  if ( did_action( 'after_setup_theme' ) ) {
104
+ // Reinitializes wp_locale for weekdays and months
105
  unset( $GLOBALS['wp_locale'] );
106
  $GLOBALS['wp_locale'] = new WP_Locale();
107
  }
116
  */
117
  do_action_ref_array( 'pll_translate_labels', array( &$this->labels ) );
118
 
119
+ // Free memory
120
  unset( $this->default_locale, $this->list_textdomains, $this->labels );
121
  }
122
 
123
  /**
124
+ * Saves all text domains in a table for later usage
125
  *
126
  * @since 0.1
127
  *
128
  * @param bool $bool not used
129
  * @param string $domain text domain name
130
  * @param string $mofile translation file name
131
+ * @return bool
132
  */
133
  public function mofile( $bool, $domain, $mofile ) {
134
+ $this->list_textdomains[ $domain ] = array( 'mo' => $mofile, 'domain' => $domain );
135
+ // Prevents WP loading text domains as we will load them all later
136
+ // FIXME backward compatibility with WP < 4.6. See #34213
137
+ // true for WP < 4.6, false for WP 4.6+ as we need to keep memory of the location of the language file inside the plugin directory
138
+ return version_compare( $GLOBALS['wp_version'], '4.6-alpha', '<' );
139
  }
140
 
141
  /**
142
+ * Saves post types and taxonomies labels for a later usage
143
  *
144
  * @since 0.9
145
  *
149
  * @return string unmodified $translation
150
  */
151
  public function gettext( $translation, $text, $domain ) {
152
+ if ( is_string( $text ) ) { // Avoid a warning with some buggy plugins which pass an array
153
  $this->labels[ $text ] = array( 'domain' => $domain );
154
  }
155
  return $translation;
156
  }
157
 
158
  /**
159
+ * Saves post types and taxonomies labels for a later usage
160
  *
161
  * @since 0.9
162
  *
172
  }
173
 
174
  /**
175
+ * Translates post types and taxonomies labels once the language is known
176
  *
177
  * @since 0.9
178
  *
179
  * @param object $type either a post type or a taxonomy
180
  */
181
  public function translate_labels( $type ) {
182
+ // Use static array to avoid translating several times the same ( default ) labels
183
  static $translated = array();
184
 
185
  foreach ( $type->labels as $key => $label ) {
197
  }
198
 
199
  /**
200
+ * Allows Polylang to be the first plugin loaded ;- )
201
  *
202
  * @since 1.2
203
  *
include/pointer.php CHANGED
@@ -80,7 +80,7 @@ class PLL_Pointer {
80
  } );
81
  } ).appendTo( buttons );",
82
  empty( $button['link'] ) ? 'button' : 'button button-primary',
83
- $button['label'],
84
  $this->args['pointer'],
85
  empty( $button['link'] ) ? "pointer.pointer( 'close' )" : sprintf( "location.href = '%s'", $button['link'] )
86
  );
@@ -100,7 +100,7 @@ class PLL_Pointer {
100
  } );
101
  // ]]>",
102
  $this->args['id'],
103
- sprintf( '<h3>%s</h3><p>%s</p>', $this->args['title'], $this->args['content'] ),
104
  empty( $this->args['position'] ) ? '' : sprintf( 'position: {edge: "%s", align: "%s",},', $this->args['position']['edge'], $this->args['position']['align'] ),
105
  empty( $this->args['width'] ) ? '' : sprintf( 'pointerWidth: %d,', $this->args['width'] ),
106
  empty( $b ) ? '' : $b
80
  } );
81
  } ).appendTo( buttons );",
82
  empty( $button['link'] ) ? 'button' : 'button button-primary',
83
+ esc_html( $button['label'] ),
84
  $this->args['pointer'],
85
  empty( $button['link'] ) ? "pointer.pointer( 'close' )" : sprintf( "location.href = '%s'", $button['link'] )
86
  );
100
  } );
101
  // ]]>",
102
  $this->args['id'],
103
+ sprintf( '<h3>%s</h3><p>%s</p>', esc_html( $this->args['title'] ), esc_html( $this->args['content'] ) ),
104
  empty( $this->args['position'] ) ? '' : sprintf( 'position: {edge: "%s", align: "%s",},', $this->args['position']['edge'], $this->args['position']['align'] ),
105
  empty( $this->args['width'] ) ? '' : sprintf( 'pointerWidth: %d,', $this->args['width'] ),
106
  empty( $b ) ? '' : $b
lingotek/lingotek.php CHANGED
@@ -57,7 +57,7 @@ class PLL_Lingotek {
57
  'edge' => 'top',
58
  'align' => 'left',
59
  ),
60
- 'width' => 380,
61
  'title' => __( 'Congratulations!', 'polylang' ),
62
  'content' => $content,
63
  'buttons' => $buttons,
@@ -107,7 +107,7 @@ class PLL_Lingotek {
107
  )
108
  );
109
 
110
- printf( '<p>%s</p>', __( 'Polylang is now fully integrated with Lingotek, a professional translation management system!', 'polylang' ) );
111
 
112
  $this->box(
113
  __( 'Automatically Translate My Site', 'polylang' ),
@@ -259,7 +259,7 @@ class PLL_Lingotek {
259
  printf( '<li>%s</li>', esc_html( $item ) );
260
  } ?>
261
  </ul>
262
- <a href="http://www.lingotek.com/wordpress" target = "_blank"><?php _e( 'Learn more...', 'polylang' ) ?></a>
263
  </div>
264
 
265
  </div><?php
57
  'edge' => 'top',
58
  'align' => 'left',
59
  ),
60
+ 'width' => 400,
61
  'title' => __( 'Congratulations!', 'polylang' ),
62
  'content' => $content,
63
  'buttons' => $buttons,
107
  )
108
  );
109
 
110
+ printf( '<p>%s</p>', esc_html__( 'Polylang is now fully integrated with Lingotek, a professional translation management system!', 'polylang' ) );
111
 
112
  $this->box(
113
  __( 'Automatically Translate My Site', 'polylang' ),
259
  printf( '<li>%s</li>', esc_html( $item ) );
260
  } ?>
261
  </ul>
262
+ <a href="http://www.lingotek.com/wordpress" target = "_blank"><?php esc_html_e( 'Learn more...', 'polylang' ) ?></a>
263
  </div>
264
 
265
  </div><?php
modules/wpml/wpml-api.php CHANGED
@@ -149,7 +149,7 @@ class PLL_WPML_API {
149
  if ( 'term' === $pll_type && $term = wpcom_vip_get_term_by( 'term_taxonomy_id', $id ) ) {
150
  $id = $term->term_id;
151
  }
152
- return $pll_type ? call_user_func( "pll_get_$pll_type_language", $id ) : $language_code;
153
  }
154
 
155
  /**
@@ -164,8 +164,8 @@ class PLL_WPML_API {
164
  * @return string the translated string
165
  */
166
  public function wpml_translate_single_string( $string, $context, $name, $lang = null ) {
167
- $has_translation = null; // passed by reference
168
- return icl_translate( $context, $name, $original_value, false, $has_translation, $lang );
169
  }
170
 
171
  /**
@@ -180,6 +180,6 @@ class PLL_WPML_API {
180
  */
181
  public function wpml_element_has_translations( $null, $id, $type ) {
182
  $pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
183
- return ( $pll_type && $translations = call_user_func( "pll_get_$pll_type_translations", $id ) ) ? count( $translations ) > 1 : false;
184
  }
185
  }
149
  if ( 'term' === $pll_type && $term = wpcom_vip_get_term_by( 'term_taxonomy_id', $id ) ) {
150
  $id = $term->term_id;
151
  }
152
+ return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code;
153
  }
154
 
155
  /**
164
  * @return string the translated string
165
  */
166
  public function wpml_translate_single_string( $string, $context, $name, $lang = null ) {
167
+ $has_translation = null; // Passed by reference
168
+ return icl_translate( $context, $name, $string, false, $has_translation, $lang );
169
  }
170
 
171
  /**
180
  */
181
  public function wpml_element_has_translations( $null, $id, $type ) {
182
  $pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
183
+ return ( $pll_type && $translations = call_user_func( "pll_get_{$pll_type}_translations", $id ) ) ? count( $translations ) > 1 : false;
184
  }
185
  }
polylang.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
- Version: 2.0.2
7
  Author: Frédéric Demarle
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
@@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) {
35
  exit; // don't access directly
36
  };
37
 
38
- define( 'POLYLANG_VERSION', '2.0.2' );
39
  define( 'PLL_MIN_WP_VERSION', '4.0' );
40
 
41
  define( 'POLYLANG_FILE', __FILE__ ); // this file
3
  /*
4
  Plugin Name: Polylang
5
  Plugin URI: https://polylang.pro
6
+ Version: 2.0.3
7
  Author: Frédéric Demarle
8
  Author uri: https://polylang.pro
9
  Description: Adds multilingual capability to WordPress
35
  exit; // don't access directly
36
  };
37
 
38
+ define( 'POLYLANG_VERSION', '2.0.3' );
39
  define( 'PLL_MIN_WP_VERSION', '4.0' );
40
 
41
  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.0
6
  Tested up to: 4.6
7
- Stable tag: 2.0.2
8
  License: GPLv2 or later
9
 
10
  Making WordPress multilingual
@@ -77,6 +77,18 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
77
 
78
  == Changelog ==
79
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  = 2.0.2 (2016-08-03) =
81
 
82
  * Avoid fatal error when a 3rd party theme or plugin has a malformed wpml-config.xml file: the malformed wpml-config.xml file is simply ignored
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
5
  Requires at least: 4.0
6
  Tested up to: 4.6
7
+ Stable tag: 2.0.3
8
  License: GPLv2 or later
9
 
10
  Making WordPress multilingual
77
 
78
  == Changelog ==
79
 
80
+ = 2.0.3 (2016-08-16) =
81
+
82
+ * Pro: Fix PHP notice when hiding the language code in url and the language is set from subdomains
83
+ * Pro: Fix one more media being created when the duplicate media in all languages is activated (introduced in 2.0)
84
+ * Pro: Fix shared term slugs not working on PHP 7
85
+ * Pro: Fix Polylang storing integers in some ACF Pro fields where ACF Pro stores strings
86
+ * Pro: Fix ACF Pro custom fields synchronized even when the custom fields synchronization option is deactivated (#40)
87
+ * Fix PHP notice: Undefined variable: original_value in /modules/wpml/wpml-api.php on line 168
88
+ * Fix translations loaded too soon by plugins not correctly reloaded since WP 4.6 (#39)
89
+ * Fix: Remove the delete link for translations of the default category on PHP 7
90
+ * Fix unescaped i18n strings in Lingotek presentation
91
+
92
  = 2.0.2 (2016-08-03) =
93
 
94
  * Avoid fatal error when a 3rd party theme or plugin has a malformed wpml-config.xml file: the malformed wpml-config.xml file is simply ignored