Polylang - Version 0.9.8

Version Description

(2012-12-05) =

  • Bug correction: ajax on frontend does not work when adding the language code to all urls
  • Bug correction: search forms using the get_search_form filter do not work
Download this release

Release Info

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

Code changes from version 0.9.6 to 0.9.8

include/admin-filters.php CHANGED
@@ -67,6 +67,7 @@ class Polylang_Admin_Filters extends Polylang_Admin_Base {
67
  add_action('wp_ajax_media_lang_choice', array(&$this,'media_lang_choice'));
68
 
69
  // adds actions related to languages when creating, saving or deleting media
 
70
  add_filter('attachment_fields_to_save', array(&$this, 'save_media'), 10, 2);
71
  add_action('delete_attachment', array(&$this, 'delete_post'));
72
  add_filter('wp_delete_file', array(&$this, 'wp_delete_file'));
@@ -222,10 +223,11 @@ class Polylang_Admin_Filters extends Polylang_Admin_Base {
222
  isset($_REQUEST['post_id']) && $lang = $this->get_post_language($_REQUEST['post_id']))
223
  $query->set('lang', $lang->slug);
224
 
225
- if (!isset($qvars['lang']) && $lg = get_user_meta(get_current_user_id(), 'pll_filter_content', true))
 
226
  $qvars['lang'] = $lg;
227
 
228
- if (isset($qvars['lang']) && $qvars['lang'] == 'all')
229
  unset ($qvars['lang']);
230
 
231
  return $query;
@@ -546,10 +548,6 @@ class Polylang_Admin_Filters extends Polylang_Admin_Base {
546
  $post_id = $post->ID;
547
  $lang = $this->get_post_language($post_id);
548
 
549
- // fills with the post language when uploading from post, otherwise the default language
550
- if (!$lang)
551
- $lang = $post->post_parent ? $this->get_post_language($post->post_parent) : $this->get_default_language();
552
-
553
  $fields['language'] = array(
554
  'label' => __('Language', 'polylang'),
555
  'input' => 'html',
@@ -619,17 +617,30 @@ class Polylang_Admin_Filters extends Polylang_Admin_Base {
619
  if (!$translations && $lang = $this->get_post_language($post_id))
620
  $translations[$lang->slug] = $post_id;
621
 
622
- $this->set_post_language($tr_id, $_GET['new_lang']);
623
  $translations[$_GET['new_lang']] = $tr_id;
624
  $this->save_translations('post', $tr_id, $translations);
625
 
626
- wp_redirect(admin_url("media.php?attachment_id=$tr_id&action=edit"));
 
627
  exit;
628
  }
629
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
  // called when a media is saved
631
  function save_media($post, $attachment) {
632
- $this->set_post_language($post['ID'], $attachment['language']); // FIXME the language is no more automatically saved by WP since WP 3.5 (just a bug?)
633
 
634
  $this->delete_translation('post', $post['ID']);
635
 
67
  add_action('wp_ajax_media_lang_choice', array(&$this,'media_lang_choice'));
68
 
69
  // adds actions related to languages when creating, saving or deleting media
70
+ add_action('add_attachment', array(&$this, 'add_attachment'));
71
  add_filter('attachment_fields_to_save', array(&$this, 'save_media'), 10, 2);
72
  add_action('delete_attachment', array(&$this, 'delete_post'));
73
  add_filter('wp_delete_file', array(&$this, 'wp_delete_file'));
223
  isset($_REQUEST['post_id']) && $lang = $this->get_post_language($_REQUEST['post_id']))
224
  $query->set('lang', $lang->slug);
225
 
226
+ if (isset($qvars['post_type']) && in_array($qvars['post_type'], $this->post_types) &&
227
+ !isset($qvars['lang']) && $lg = get_user_meta(get_current_user_id(), 'pll_filter_content', true))
228
  $qvars['lang'] = $lg;
229
 
230
+ if ((isset($qvars['post_type']) && !in_array($qvars['post_type'], $this->post_types)) || (isset($qvars['lang']) && $qvars['lang'] == 'all'))
231
  unset ($qvars['lang']);
232
 
233
  return $query;
548
  $post_id = $post->ID;
549
  $lang = $this->get_post_language($post_id);
550
 
 
 
 
 
551
  $fields['language'] = array(
552
  'label' => __('Language', 'polylang'),
553
  'input' => 'html',
617
  if (!$translations && $lang = $this->get_post_language($post_id))
618
  $translations[$lang->slug] = $post_id;
619
 
 
620
  $translations[$_GET['new_lang']] = $tr_id;
621
  $this->save_translations('post', $tr_id, $translations);
622
 
623
+ wp_redirect(admin_url(sprintf(version_compare($GLOBALS['wp_version'], '3.5', '<') ?
624
+ 'media.php?attachment_id=%d&action=edit' : 'post.php?post=%d&action=edit', $tr_id)));
625
  exit;
626
  }
627
 
628
+ // sets the language of a new attachment
629
+ function add_attachment($post_id) {
630
+ if (isset($_GET['new_lang']) && $_GET['new_lang']) // created as a translation from an existing attachment
631
+ $lang = $_GET['new_lang'];
632
+ else {
633
+ $post = get_post($post_id);
634
+ if (isset($post->post_parent) && $post->post_parent) // upload in the "Add media" modal when editing a post
635
+ $lang = $this->get_post_language($post->post_parent);
636
+ }
637
+
638
+ $this->set_post_language($post_id, isset($lang) ? $lang : $this->get_default_language());
639
+ }
640
+
641
  // called when a media is saved
642
  function save_media($post, $attachment) {
643
+ $this->set_post_language($post['ID'], $attachment['language']); // FIXME the language is no more automatically saved by WP since WP 3.5
644
 
645
  $this->delete_translation('post', $post['ID']);
646
 
include/admin.php CHANGED
@@ -417,6 +417,7 @@ class Polylang_Admin extends Polylang_Admin_Base {
417
 
418
  function &get_strings() {
419
  global $wp_registered_widgets;
 
420
 
421
  // WP strings
422
  $this->register_string(__('Site Title'), get_option('blogname'));
@@ -433,13 +434,14 @@ class Polylang_Admin extends Polylang_Admin_Base {
433
  foreach ($widgets as $widget) {
434
  // nothing can be done if the widget is created using pre WP2.8 API :(
435
  // there is no object, so we can't access it to get the widget options
436
- // the second part of the test is probably useless
437
- if (!isset($wp_registered_widgets[$widget]['callback'][0]) || !is_object($wp_registered_widgets[$widget]['callback'][0]))
438
  continue;
439
 
440
  $widget_settings = $wp_registered_widgets[$widget]['callback'][0]->get_settings();
441
  $number = $wp_registered_widgets[$widget]['params'][0]['number'];
442
- if (isset($widget_settings[$number]['title']) && $title = $widget_settings[$number]['title'])
 
443
  $this->register_string(__('Widget title', 'polylang'), $title);
444
  }
445
  }
417
 
418
  function &get_strings() {
419
  global $wp_registered_widgets;
420
+ $languages = get_option('polylang_widgets');
421
 
422
  // WP strings
423
  $this->register_string(__('Site Title'), get_option('blogname'));
434
  foreach ($widgets as $widget) {
435
  // nothing can be done if the widget is created using pre WP2.8 API :(
436
  // there is no object, so we can't access it to get the widget options
437
+ if (!isset($wp_registered_widgets[$widget]['callback'][0]) || !is_object($wp_registered_widgets[$widget]['callback'][0]) ||
438
+ !method_exists($wp_registered_widgets[$widget]['callback'][0], 'get_settings'))
439
  continue;
440
 
441
  $widget_settings = $wp_registered_widgets[$widget]['callback'][0]->get_settings();
442
  $number = $wp_registered_widgets[$widget]['params'][0]['number'];
443
+ // don't enable widget title translation if the widget is visible in only one language or if there is no title
444
+ if (!(isset($languages[$widget]) && $languages[$widget]) && isset($widget_settings[$number]['title']) && $title = $widget_settings[$number]['title'])
445
  $this->register_string(__('Widget title', 'polylang'), $title);
446
  }
447
  }
include/base.php CHANGED
@@ -159,7 +159,7 @@ abstract class Polylang_Base {
159
  $term_id = $value;
160
  elseif (is_string($value) && $taxonomy)
161
  $term_id = get_term_by('slug', $value , $taxonomy)->term_id;
162
- return $term_id ? $this->get_language(get_metadata('term', $term_id, '_language', true)) : false;
163
  }
164
 
165
  // among the term and its translations, returns the id of the term which is in $lang
159
  $term_id = $value;
160
  elseif (is_string($value) && $taxonomy)
161
  $term_id = get_term_by('slug', $value , $taxonomy)->term_id;
162
+ return isset($term_id) && $term_id ? $this->get_language(get_metadata('term', $term_id, '_language', true)) : false;
163
  }
164
 
165
  // among the term and its translations, returns the id of the term which is in $lang
include/core.php CHANGED
@@ -41,7 +41,7 @@ class Polylang_Core extends Polylang_base {
41
 
42
  add_action('init', array(&$this, 'init'));
43
  foreach (array('wp', 'login_init', 'admin_init') as $filter) // admin_init for ajax thanks to g100g
44
- add_action($filter, array(&$this, 'load_textdomains'), 5); // priority 5 for post types and taxonomies with registered with in wp hook with default priority
45
 
46
  // filters the WordPress locale
47
  add_filter('locale', array(&$this, 'get_locale'));
@@ -225,36 +225,43 @@ class Polylang_Core extends Polylang_base {
225
 
226
  // sets the language when it is always included in the url
227
  function setup_theme() {
228
- $root = $this->options['rewrite']? '' : 'language/';
229
-
230
- foreach ($this->get_languages_list() as $language)
231
- $languages[] = $language->slug;
232
-
233
- $languages = $GLOBALS['wp_rewrite']->using_permalinks() ?
234
- '#\/'.$root.'('.implode('|', $languages).')\/#' :
235
- '#lang=('.implode('|', $languages).')#';
236
-
237
- preg_match($languages, trailingslashit($_SERVER['REQUEST_URI']), $matches);
238
-
239
- // home is resquested
240
- // some PHP setups turn requests for / into /index.php in REQUEST_URI
241
- // thanks to Gonçalo Peres for pointing out the issue with queries unknown to WP
242
- // http://wordpress.org/support/topic/plugin-polylang-language-homepage-redirection-problem-and-solution-but-incomplete?replies=4#post-2729566
243
- if (str_replace('www.', '', home_url('/')) == trailingslashit((is_ssl() ? 'https://' : 'http://').str_replace('www.', '', $_SERVER['HTTP_HOST']).str_replace(array('index.php', '?'.$_SERVER['QUERY_STRING']), array('', ''), $_SERVER['REQUEST_URI']))) {
244
- // take care to post preview http://wordpress.org/support/topic/static-frontpage-url-parameter-url-language-information
245
- if (isset($_GET['preview']) && isset($_GET['p']) && $lg = $this->get_post_language($_GET['p']))
246
- $this->curlang = $lg ? $lg : $this->get_language($this->options['default_lang']);
247
- else
248
- $this->home_requested();
249
- }
250
- // $matches[1] is the slug of the requested language
251
- elseif ($matches)
252
- $this->curlang = $this->get_language($matches[1]);
253
- elseif (false === strpos($_SERVER['SCRIPT_NAME'], 'index.php')) // wp-login, wp-signup, wp-activate
254
- $this->curlang = $this->get_preferred_language();
255
  else {
256
- $this->curlang = $this->get_language($this->options['default_lang']);
257
- add_action('wp', array(&$this, 'check_language_code_in_url')); // before Wordpress redirect_canonical
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  }
259
 
260
  $GLOBALS['l10n']['pll_string'] = $this->mo_import($this->curlang);
@@ -559,9 +566,14 @@ class Polylang_Core extends Polylang_base {
559
 
560
  // prevents redirection of the homepage when using page on front
561
  function stop_redirect_canonical($redirect_url, $requested_url) {
562
- $home_url = home_url('/');
563
- $page_link = $this->page_link('', get_option('page_on_front'));
564
- return $requested_url == $home_url || ($page_link != $home_url && strpos($requested_url, $page_link ) !== false) ? false : $redirect_url;
 
 
 
 
 
565
  }
566
 
567
  // redirects incoming links to the proper URL when adding the language code to all urls
@@ -803,10 +815,10 @@ class Polylang_Core extends Polylang_base {
803
  }
804
 
805
  // translates page for posts and page on front
806
- function translate_page($val) {
807
  // returns the current page if there is no translation to avoid ugly notices
808
  // the fonction is often called so let's store the result
809
- return isset($this->curlang) && $val && (isset($this->posts[$val]) || $this->posts[$val] = $this->get_post($val, $this->curlang)) ? $this->posts[$val] : $val;
810
  }
811
 
812
  // filters the home url to get the right language
@@ -815,11 +827,16 @@ class Polylang_Core extends Polylang_base {
815
  return $url;
816
 
817
  $theme = get_theme_root();
818
- foreach (debug_backtrace(/*!DEBUG_BACKTRACE_PROVIDE_OBJECT|DEBUG_BACKTRACE_IGNORE_ARGS*/) as $trace) {
 
819
  // search form
820
  if (isset($trace['file']) && strpos($trace['file'], 'searchform.php'))
821
  return $GLOBALS['wp_rewrite']->using_permalinks() ? $this->get_home_url($this->curlang, true) : $url;
822
 
 
 
 
 
823
  $ok = $trace['function'] == 'wp_nav_menu' ||
824
  // direct call from the theme
825
  (isset($trace['file']) && strpos($trace['file'], $theme) !== false &&
41
 
42
  add_action('init', array(&$this, 'init'));
43
  foreach (array('wp', 'login_init', 'admin_init') as $filter) // admin_init for ajax thanks to g100g
44
+ add_action($filter, array(&$this, 'load_textdomains'), 5); // priority 5 for post types and taxonomies registered in wp hook with default priority
45
 
46
  // filters the WordPress locale
47
  add_filter('locale', array(&$this, 'get_locale'));
225
 
226
  // sets the language when it is always included in the url
227
  function setup_theme() {
228
+ // special case for ajax request
229
+ if (isset($_REQUEST['pll_load_front']))
230
+ $this->curlang = isset($_REQUEST['lang']) && $_REQUEST['lang'] ? $this->get_language($_REQUEST['lang']) : $this->get_preferred_language();
231
+
232
+ // standard case
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  else {
234
+ $root = $this->options['rewrite']? '' : 'language/';
235
+
236
+ foreach ($this->get_languages_list() as $language)
237
+ $languages[] = $language->slug;
238
+
239
+ $languages = $GLOBALS['wp_rewrite']->using_permalinks() ?
240
+ '#\/'.$root.'('.implode('|', $languages).')\/#' :
241
+ '#lang=('.implode('|', $languages).')#';
242
+
243
+ preg_match($languages, trailingslashit($_SERVER['REQUEST_URI']), $matches);
244
+
245
+ // home is resquested
246
+ // some PHP setups turn requests for / into /index.php in REQUEST_URI
247
+ // thanks to Gonçalo Peres for pointing out the issue with queries unknown to WP
248
+ // http://wordpress.org/support/topic/plugin-polylang-language-homepage-redirection-problem-and-solution-but-incomplete?replies=4#post-2729566
249
+ if (str_replace('www.', '', home_url('/')) == trailingslashit((is_ssl() ? 'https://' : 'http://').str_replace('www.', '', $_SERVER['HTTP_HOST']).str_replace(array('index.php', '?'.$_SERVER['QUERY_STRING']), array('', ''), $_SERVER['REQUEST_URI']))) {
250
+ // take care to post preview http://wordpress.org/support/topic/static-frontpage-url-parameter-url-language-information
251
+ if (isset($_GET['preview']) && isset($_GET['p']) && $lg = $this->get_post_language($_GET['p']))
252
+ $this->curlang = $lg ? $lg : $this->get_language($this->options['default_lang']);
253
+ else
254
+ $this->home_requested();
255
+ }
256
+ // $matches[1] is the slug of the requested language
257
+ elseif ($matches)
258
+ $this->curlang = $this->get_language($matches[1]);
259
+ elseif (false === strpos($_SERVER['SCRIPT_NAME'], 'index.php')) // wp-login, wp-signup, wp-activate
260
+ $this->curlang = $this->get_preferred_language();
261
+ else {
262
+ $this->curlang = $this->get_language($this->options['default_lang']);
263
+ add_action('wp', array(&$this, 'check_language_code_in_url')); // before Wordpress redirect_canonical
264
+ }
265
  }
266
 
267
  $GLOBALS['l10n']['pll_string'] = $this->mo_import($this->curlang);
566
 
567
  // prevents redirection of the homepage when using page on front
568
  function stop_redirect_canonical($redirect_url, $requested_url) {
569
+ if (($page_on_front = get_option('page_on_front')) && $page_on_front == get_query_var('page_id')) // default permalinks
570
+ return false;
571
+
572
+ $url = @parse_url($requested_url);
573
+ $url = trailingslashit($url['scheme'] . '://' .$url['host'] . (isset($url['path']) ? $url['path'] : ''));
574
+ $page_on_front = trailingslashit($this->page_link('', $page_on_front));
575
+
576
+ return $url == home_url('/') || $url == $page_on_front ? false : $redirect_url;
577
  }
578
 
579
  // redirects incoming links to the proper URL when adding the language code to all urls
815
  }
816
 
817
  // translates page for posts and page on front
818
+ function translate_page($v) {
819
  // returns the current page if there is no translation to avoid ugly notices
820
  // the fonction is often called so let's store the result
821
+ return isset($this->curlang) && $v && (isset($this->posts[$v]) || $this->posts[$v] = $this->get_post($v, $this->curlang)) ? $this->posts[$v] : $v;
822
  }
823
 
824
  // filters the home url to get the right language
827
  return $url;
828
 
829
  $theme = get_theme_root();
830
+ // FIXME can I decrease the size of the array to improve speed?
831
+ foreach (array_reverse(debug_backtrace(/*!DEBUG_BACKTRACE_PROVIDE_OBJECT|DEBUG_BACKTRACE_IGNORE_ARGS*/)) as $trace) {
832
  // search form
833
  if (isset($trace['file']) && strpos($trace['file'], 'searchform.php'))
834
  return $GLOBALS['wp_rewrite']->using_permalinks() ? $this->get_home_url($this->curlang, true) : $url;
835
 
836
+ // don't interfere with get_search_form filter which I prefer to use when possible
837
+ if ($trace['function'] == 'get_search_form')
838
+ return $url;
839
+
840
  $ok = $trace['function'] == 'wp_nav_menu' ||
841
  // direct call from the theme
842
  (isset($trace['file']) && strpos($trace['file'], $theme) !== false &&
include/media-translations.php CHANGED
@@ -14,7 +14,8 @@
14
  printf('<td class="tr-edit-column"><input type="hidden" name="media_tr_lang[%s]" value="%d" /><a href="%s">%s</a></td>',
15
  esc_attr($language->slug),
16
  esc_attr($translation_id),
17
- esc_url(admin_url(sprintf('media.php?attachment_id=%d&action=edit', $translation_id))),
 
18
  __('Edit','polylang')
19
  );
20
  }
14
  printf('<td class="tr-edit-column"><input type="hidden" name="media_tr_lang[%s]" value="%d" /><a href="%s">%s</a></td>',
15
  esc_attr($language->slug),
16
  esc_attr($translation_id),
17
+ esc_url(admin_url(sprintf(version_compare($GLOBALS['wp_version'], '3.5', '<') ?
18
+ 'media.php?attachment_id=%d&action=edit' : 'post.php?post=%d&action=edit', $translation_id))),
19
  __('Edit','polylang')
20
  );
21
  }
polylang.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Polylang
4
  Plugin URI: http://wordpress.org/extend/plugins/polylang/
5
- Version: 0.9.6
6
  Author: F. Demarle
7
  Description: Adds multilingual capability to Wordpress
8
  Text Domain: polylang
@@ -26,7 +26,7 @@ Domain Path: /languages
26
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
- define('POLYLANG_VERSION', '0.9.6');
30
  define('PLL_MIN_WP_VERSION', '3.1');
31
 
32
  define('POLYLANG_DIR', dirname(__FILE__)); // our directory
2
  /*
3
  Plugin Name: Polylang
4
  Plugin URI: http://wordpress.org/extend/plugins/polylang/
5
+ Version: 0.9.8
6
  Author: F. Demarle
7
  Description: Adds multilingual capability to Wordpress
8
  Text Domain: polylang
26
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
+ define('POLYLANG_VERSION', '0.9.8');
30
  define('PLL_MIN_WP_VERSION', '3.1');
31
 
32
  define('POLYLANG_DIR', dirname(__FILE__)); // our directory
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Chouby
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CCWWYUUQV8F4E
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, i18n, international, l10n, localization
5
  Requires at least: 3.1
6
- Tested up to: 3.4.2
7
- Stable tag: 0.9.6
8
  License: GPLv2 or later
9
 
10
  Polylang adds multilingual content management support to WordPress.
@@ -93,13 +93,26 @@ Every suggestions are welcome.
93
 
94
  == Changelog ==
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  = 0.9.6 (2012-11-26) =
97
 
98
  * It is now possible to query the terms by language using the WordPress function 'get_terms'
99
  * Bug correction: search for empty string in default language displays posts in all languages when hiding the URL language information for default language
100
  * Bug correction: completely reworked the canonical redirection introduced in 0.9.5 which created more problems than it solved
101
  * Bug correction: ajax for media translations does not work
102
- * Started tests with WordPress 3.5 beta RC1
103
 
104
  = 0.9.5 (2012-11-13) =
105
 
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CCWWYUUQV8F4E
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, i18n, international, l10n, localization
5
  Requires at least: 3.1
6
+ Tested up to: 3.5
7
+ Stable tag: 0.9.8
8
  License: GPLv2 or later
9
 
10
  Polylang adds multilingual content management support to WordPress.
93
 
94
  == Changelog ==
95
 
96
+ = 0.9.8 (2012-12-05) =
97
+
98
+ * Bug correction: ajax on frontend does not work when adding the language code to all urls
99
+ * Bug correction: search forms using the get_search_form filter do not work
100
+
101
+ = 0.9.7 (2012-12-04) =
102
+
103
+ * Bug correction: the admin language filter does filter non translatable post types
104
+ * Bug correction: again the canonical redirection
105
+ * Bug correction: fatal error when Polylang is used together with 'Author Avatars List'
106
+ * Bug correction: widget titles uselessly appear in the strings translations table when the widget is set for only one language
107
+ * Tests done with WordPress 3.5 beta RC3 and Twenty Twelve
108
+
109
  = 0.9.6 (2012-11-26) =
110
 
111
  * It is now possible to query the terms by language using the WordPress function 'get_terms'
112
  * Bug correction: search for empty string in default language displays posts in all languages when hiding the URL language information for default language
113
  * Bug correction: completely reworked the canonical redirection introduced in 0.9.5 which created more problems than it solved
114
  * Bug correction: ajax for media translations does not work
115
+ * Started tests with WordPress 3.5 beta RC1 and Twenty Twelve
116
 
117
  = 0.9.5 (2012-11-13) =
118