Version Description
(2015-04-11) =
- the transient 'pll_languages_list' now stores an array of arrays instead of an array of PLL_Language objects
- fix: fatal error for users hosted at GoDaddy (due to PLL_Language objects stored in a transient)
- fix: additional query vars are removed from home page
- fix: categories are not filtered by the admin language switcher in posts list table (introduced in 1.7)
- fix: when using multiple domains, the domain url is lost when modifying the language slug
- fix: the queried object is incorrectly set for author archives (introduced in 1.6.5)
- fix: notice when a nav menu assigned to a translated nav menu location has been deleted
- fix: no canonical redirection when using pretty permalinks and querying default permalinks
Download this release
Release Info
Developer | Chouby |
Plugin | Polylang |
Version | 1.7.3 |
Comparing to | |
See all releases |
Code changes from version 1.7.2 to 1.7.3
- admin/admin-filters-columns.php +16 -5
- admin/admin-filters-media.php +4 -3
- admin/admin-filters-post-base.php +2 -2
- admin/admin-filters-post.php +16 -10
- admin/admin-filters-term.php +38 -24
- admin/admin-filters.php +3 -3
- admin/admin-model.php +8 -9
- admin/admin-nav-menu.php +23 -2
- admin/admin-strings.php +2 -2
- admin/admin-sync.php +10 -7
- admin/admin.php +0 -2
- admin/settings.php +11 -8
- admin/table-languages.php +17 -6
- frontend/choose-lang.php +1 -1
- frontend/frontend-links.php +16 -3
- frontend/frontend-nav-menu.php +1 -1
- frontend/frontend.php +2 -3
- include/language.php +24 -14
- include/model.php +33 -16
- include/switcher.php +1 -1
- include/wpml-compat.php +1 -1
- install/install-base.php +6 -7
- install/install.php +2 -2
- polylang.php +2 -2
- readme.txt +13 -2
admin/admin-filters-columns.php
CHANGED
@@ -205,14 +205,19 @@ class PLL_Admin_Filters_Columns {
|
|
205 |
|
206 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type']; // 2nd case for quick edit
|
207 |
$taxonomy = isset($GLOBALS['taxonomy']) ? $GLOBALS['taxonomy'] : $_REQUEST['taxonomy'];
|
|
|
|
|
|
|
|
|
|
|
208 |
$language = $this->model->get_language(substr($column, 9));
|
209 |
|
210 |
if ($column == $this->get_first_language_column()) {
|
211 |
-
$out = sprintf('<div class="hidden" id="lang_%d">%s</div>',
|
212 |
|
213 |
// identify the default categories to disable the language dropdown in js
|
214 |
if (in_array(get_option('default_category'), $this->model->get_translations('term', $term_id)))
|
215 |
-
$out .= sprintf('<div class="hidden" id="default_cat_%1$d">%1$d</div>',
|
216 |
}
|
217 |
|
218 |
// link to edit term (or a translation)
|
@@ -248,9 +253,12 @@ class PLL_Admin_Filters_Columns {
|
|
248 |
$x = new WP_Ajax_Response();
|
249 |
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
|
250 |
|
251 |
-
$post_type = $_POST['post_type']
|
|
|
|
|
252 |
$translations = empty($_POST['translations']) ? array() : explode(',', $_POST['translations']); // collect old translations
|
253 |
$translations = array_merge($translations, array($_POST['post_id'])); // add current post
|
|
|
254 |
|
255 |
foreach ($translations as $post_id) {
|
256 |
$level = is_post_type_hierarchical( $post_type ) ? count( get_ancestors( $post_id, $post_type ) ) : 0;
|
@@ -278,10 +286,13 @@ class PLL_Admin_Filters_Columns {
|
|
278 |
$x = new WP_Ajax_Response();
|
279 |
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
|
280 |
|
281 |
-
$taxonomy = $_POST['taxonomy']
|
|
|
|
|
282 |
$translations = empty($_POST['translations']) ? array() : explode(',', $_POST['translations']); // collect old translations
|
283 |
-
$translations = array_merge($translations, $this->model->get_translations('term', $_POST['term_id'])); // add current translations
|
284 |
$translations = array_unique($translations); // remove doublons
|
|
|
285 |
|
286 |
foreach ($translations as $term_id) {
|
287 |
$level = is_taxonomy_hierarchical($taxonomy) ? count( get_ancestors( $term_id, $taxonomy ) ) : 0;
|
205 |
|
206 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type']; // 2nd case for quick edit
|
207 |
$taxonomy = isset($GLOBALS['taxonomy']) ? $GLOBALS['taxonomy'] : $_REQUEST['taxonomy'];
|
208 |
+
|
209 |
+
if (!post_type_exists($post_type) || !taxonomy_exists($taxonomy))
|
210 |
+
return $out;
|
211 |
+
|
212 |
+
$term_id = (int) $term_id;
|
213 |
$language = $this->model->get_language(substr($column, 9));
|
214 |
|
215 |
if ($column == $this->get_first_language_column()) {
|
216 |
+
$out = sprintf('<div class="hidden" id="lang_%d">%s</div>', $term_id, esc_html($lang->slug));
|
217 |
|
218 |
// identify the default categories to disable the language dropdown in js
|
219 |
if (in_array(get_option('default_category'), $this->model->get_translations('term', $term_id)))
|
220 |
+
$out .= sprintf('<div class="hidden" id="default_cat_%1$d">%1$d</div>', $term_id);
|
221 |
}
|
222 |
|
223 |
// link to edit term (or a translation)
|
253 |
$x = new WP_Ajax_Response();
|
254 |
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
|
255 |
|
256 |
+
if (!post_type_exists($post_type = $_POST['post_type']))
|
257 |
+
die(0);
|
258 |
+
|
259 |
$translations = empty($_POST['translations']) ? array() : explode(',', $_POST['translations']); // collect old translations
|
260 |
$translations = array_merge($translations, array($_POST['post_id'])); // add current post
|
261 |
+
$translations = array_map('intval', $translations);
|
262 |
|
263 |
foreach ($translations as $post_id) {
|
264 |
$level = is_post_type_hierarchical( $post_type ) ? count( get_ancestors( $post_id, $post_type ) ) : 0;
|
286 |
$x = new WP_Ajax_Response();
|
287 |
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
|
288 |
|
289 |
+
if (!taxonomy_exists($taxonomy = $_POST['taxonomy']))
|
290 |
+
die(0);
|
291 |
+
|
292 |
$translations = empty($_POST['translations']) ? array() : explode(',', $_POST['translations']); // collect old translations
|
293 |
+
$translations = array_merge($translations, $this->model->get_translations('term', (int) $_POST['term_id'])); // add current translations
|
294 |
$translations = array_unique($translations); // remove doublons
|
295 |
+
$translations = array_map('intval', $translations);
|
296 |
|
297 |
foreach ($translations as $term_id) {
|
298 |
$level = is_taxonomy_hierarchical($taxonomy) ? count( get_ancestors( $term_id, $taxonomy ) ) : 0;
|
admin/admin-filters-media.php
CHANGED
@@ -100,12 +100,13 @@ class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
|
100 |
//security check
|
101 |
check_admin_referer('translate_media');
|
102 |
|
103 |
-
$post = get_post($_GET['from_media']);
|
104 |
$post_id = $post->ID;
|
|
|
105 |
|
106 |
// create a new attachment (translate attachment parent if exists)
|
107 |
$post->ID = null; // will force the creation
|
108 |
-
$post->post_parent = ($post->post_parent && $tr_parent = $this->model->get_translation('post', $post->post_parent, $
|
109 |
$tr_id = wp_insert_attachment($post);
|
110 |
add_post_meta($tr_id, '_wp_attachment_metadata', get_post_meta($post_id, '_wp_attachment_metadata', true));
|
111 |
add_post_meta($tr_id, '_wp_attached_file', get_post_meta($post_id, '_wp_attached_file', true));
|
@@ -118,7 +119,7 @@ class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
|
118 |
if (!$translations && $lang = $this->model->get_post_language($post_id))
|
119 |
$translations[$lang->slug] = $post_id;
|
120 |
|
121 |
-
$translations[$
|
122 |
$this->model->save_translations('post', $tr_id, $translations);
|
123 |
|
124 |
do_action('pll_translate_media', $tr_id, $post, $translations);
|
100 |
//security check
|
101 |
check_admin_referer('translate_media');
|
102 |
|
103 |
+
$post = get_post((int) $_GET['from_media']);
|
104 |
$post_id = $post->ID;
|
105 |
+
$new_lang = $this->model->get_language($_GET['new_lang']); // make sure we get a valid language slug
|
106 |
|
107 |
// create a new attachment (translate attachment parent if exists)
|
108 |
$post->ID = null; // will force the creation
|
109 |
+
$post->post_parent = ($post->post_parent && $tr_parent = $this->model->get_translation('post', $post->post_parent, $new_lang->slug)) ? $tr_parent : 0;
|
110 |
$tr_id = wp_insert_attachment($post);
|
111 |
add_post_meta($tr_id, '_wp_attachment_metadata', get_post_meta($post_id, '_wp_attachment_metadata', true));
|
112 |
add_post_meta($tr_id, '_wp_attached_file', get_post_meta($post_id, '_wp_attached_file', true));
|
119 |
if (!$translations && $lang = $this->model->get_post_language($post_id))
|
120 |
$translations[$lang->slug] = $post_id;
|
121 |
|
122 |
+
$translations[$new_lang->slug] = $tr_id;
|
123 |
$this->model->save_translations('post', $tr_id, $translations);
|
124 |
|
125 |
do_action('pll_translate_media', $tr_id, $post, $translations);
|
admin/admin-filters-post-base.php
CHANGED
@@ -30,8 +30,8 @@ abstract class PLL_Admin_Filters_Post_Base {
|
|
30 |
*/
|
31 |
public function set_default_language($post_id) {
|
32 |
if (!$this->model->get_post_language($post_id)) {
|
33 |
-
if (isset($_GET['new_lang']))
|
34 |
-
$this->model->set_post_language($post_id, $
|
35 |
|
36 |
elseif (($parent_id = wp_get_post_parent_id($post_id)) && $parent_lang = $this->model->get_post_language($parent_id))
|
37 |
$this->model->set_post_language($post_id, $parent_lang);
|
30 |
*/
|
31 |
public function set_default_language($post_id) {
|
32 |
if (!$this->model->get_post_language($post_id)) {
|
33 |
+
if (isset($_GET['new_lang']) && $lang = $this->model->get_language($_GET['new_lang']))
|
34 |
+
$this->model->set_post_language($post_id, $lang);
|
35 |
|
36 |
elseif (($parent_id = wp_get_post_parent_id($post_id)) && $parent_lang = $this->model->get_post_language($parent_id))
|
37 |
$this->model->set_post_language($post_id, $parent_lang);
|
admin/admin-filters-post.php
CHANGED
@@ -92,7 +92,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
92 |
|
93 |
if (isset($qvars['post_type']) && !isset($qvars['lang'])) {
|
94 |
// filters the list of media (or wp-links) by language when uploading from post
|
95 |
-
if (isset($_REQUEST['pll_post_id']) && $lang = $this->model->get_post_language($_REQUEST['pll_post_id']))
|
96 |
$query->set('lang', $lang->slug);
|
97 |
|
98 |
elseif (!empty($this->curlang))
|
@@ -161,7 +161,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
161 |
check_ajax_referer('pll_language', '_pll_nonce');
|
162 |
|
163 |
global $post_ID; // obliged to use the global variable for wp_popular_terms_checklist
|
164 |
-
$post_ID = $_POST['post_id'];
|
165 |
$post_type = get_post_type($post_ID);
|
166 |
$lang = $this->model->get_language($_POST['lang']);
|
167 |
|
@@ -231,9 +231,15 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
231 |
public function ajax_posts_not_translated() {
|
232 |
check_ajax_referer('pll_language', '_pll_nonce');
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
// don't order by title: see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
|
235 |
$args = array(
|
236 |
-
's' => $_REQUEST['term'],
|
237 |
'suppress_filters' => 0, // to make the post_fields filter work
|
238 |
'lang' => 0, // avoid admin language filter
|
239 |
'numberposts' => 20, // limit to 20 posts
|
@@ -242,7 +248,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
242 |
'tax_query' => array(array(
|
243 |
'taxonomy' => 'language',
|
244 |
'field' => 'term_taxonomy_id', // WP 3.5+
|
245 |
-
'terms' => $
|
246 |
))
|
247 |
);
|
248 |
|
@@ -253,12 +259,12 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
253 |
$return = array();
|
254 |
|
255 |
foreach ($posts as $key => $post) {
|
256 |
-
if (!$this->model->get_translation('post', $post->ID, $
|
257 |
$return[] = array('id' => $post->ID, 'value' => $post->post_title, 'link' => $this->edit_translation_link($post->ID));
|
258 |
}
|
259 |
|
260 |
// add current translation in list
|
261 |
-
if ($post_id = $this->model->get_translation('post', $_REQUEST['pll_post_id']
|
262 |
$post = get_post($post_id);
|
263 |
array_unshift($return, array(
|
264 |
'id' => $post_id,
|
@@ -286,7 +292,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
286 |
// edit post
|
287 |
if (isset($_REQUEST['post_lang_choice'])) {
|
288 |
check_admin_referer('pll_language', '_pll_nonce');
|
289 |
-
$this->model->set_post_language($post_id, $lang = $_REQUEST['post_lang_choice']);
|
290 |
}
|
291 |
|
292 |
// quick edit and bulk edit
|
@@ -301,14 +307,14 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
301 |
isset($_REQUEST['bulk_edit']) ? check_admin_referer('bulk-posts') : check_admin_referer('inlineeditnonce', '_inline_edit');
|
302 |
|
303 |
$old_lang = $this->model->get_post_language($post_id); // stores the old language
|
304 |
-
$this->model->set_post_language($post_id, $lang = $_REQUEST['inline_lang_choice']); // set new language
|
305 |
|
306 |
// checks if the new language already exists in the translation group
|
307 |
-
if ($old_lang && $old_lang->slug != $lang) {
|
308 |
$translations = $this->model->get_translations('post', $post_id);
|
309 |
|
310 |
// if yes, separate this post from the translation group
|
311 |
-
if (array_key_exists($lang, $translations)) {
|
312 |
$this->model->delete_translation('post', $post_id);
|
313 |
}
|
314 |
|
92 |
|
93 |
if (isset($qvars['post_type']) && !isset($qvars['lang'])) {
|
94 |
// filters the list of media (or wp-links) by language when uploading from post
|
95 |
+
if (isset($_REQUEST['pll_post_id']) && $lang = $this->model->get_post_language((int) $_REQUEST['pll_post_id']))
|
96 |
$query->set('lang', $lang->slug);
|
97 |
|
98 |
elseif (!empty($this->curlang))
|
161 |
check_ajax_referer('pll_language', '_pll_nonce');
|
162 |
|
163 |
global $post_ID; // obliged to use the global variable for wp_popular_terms_checklist
|
164 |
+
$post_ID = (int) $_POST['post_id'];
|
165 |
$post_type = get_post_type($post_ID);
|
166 |
$lang = $this->model->get_language($_POST['lang']);
|
167 |
|
231 |
public function ajax_posts_not_translated() {
|
232 |
check_ajax_referer('pll_language', '_pll_nonce');
|
233 |
|
234 |
+
if (!post_type_exists($_REQUEST['post_type']))
|
235 |
+
die(0);
|
236 |
+
|
237 |
+
$post_language = $this->model->get_language($_REQUEST['post_language']);
|
238 |
+
$translation_language = $this->model->get_language($_REQUEST['translation_language']);
|
239 |
+
|
240 |
// don't order by title: see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
|
241 |
$args = array(
|
242 |
+
's' => wp_unslash($_REQUEST['term']),
|
243 |
'suppress_filters' => 0, // to make the post_fields filter work
|
244 |
'lang' => 0, // avoid admin language filter
|
245 |
'numberposts' => 20, // limit to 20 posts
|
248 |
'tax_query' => array(array(
|
249 |
'taxonomy' => 'language',
|
250 |
'field' => 'term_taxonomy_id', // WP 3.5+
|
251 |
+
'terms' => $translation_language->term_taxonomy_id
|
252 |
))
|
253 |
);
|
254 |
|
259 |
$return = array();
|
260 |
|
261 |
foreach ($posts as $key => $post) {
|
262 |
+
if (!$this->model->get_translation('post', $post->ID, $post_language))
|
263 |
$return[] = array('id' => $post->ID, 'value' => $post->post_title, 'link' => $this->edit_translation_link($post->ID));
|
264 |
}
|
265 |
|
266 |
// add current translation in list
|
267 |
+
if ($post_id = $this->model->get_translation('post', (int) $_REQUEST['pll_post_id'], $translation_language)) {
|
268 |
$post = get_post($post_id);
|
269 |
array_unshift($return, array(
|
270 |
'id' => $post_id,
|
292 |
// edit post
|
293 |
if (isset($_REQUEST['post_lang_choice'])) {
|
294 |
check_admin_referer('pll_language', '_pll_nonce');
|
295 |
+
$this->model->set_post_language($post_id, $lang = $this->model->get_language($_REQUEST['post_lang_choice']));
|
296 |
}
|
297 |
|
298 |
// quick edit and bulk edit
|
307 |
isset($_REQUEST['bulk_edit']) ? check_admin_referer('bulk-posts') : check_admin_referer('inlineeditnonce', '_inline_edit');
|
308 |
|
309 |
$old_lang = $this->model->get_post_language($post_id); // stores the old language
|
310 |
+
$this->model->set_post_language($post_id, $lang = $this->model->get_language($_REQUEST['inline_lang_choice'])); // set new language
|
311 |
|
312 |
// checks if the new language already exists in the translation group
|
313 |
+
if ($old_lang && $old_lang->slug != $lang->slug) {
|
314 |
$translations = $this->model->get_translations('post', $post_id);
|
315 |
|
316 |
// if yes, separate this post from the translation group
|
317 |
+
if (array_key_exists($lang->slug, $translations)) {
|
318 |
$this->model->delete_translation('post', $post_id);
|
319 |
}
|
320 |
|
admin/admin-filters-term.php
CHANGED
@@ -64,6 +64,10 @@ class PLL_Admin_Filters_Term {
|
|
64 |
public function add_term_form() {
|
65 |
$taxonomy = $_GET['taxonomy'];
|
66 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
|
|
|
|
|
|
|
|
67 |
$lang = isset($_GET['new_lang']) ? $this->model->get_language($_GET['new_lang']) : $this->pref_lang;
|
68 |
$dropdown = new PLL_Walker_Dropdown();
|
69 |
|
@@ -105,6 +109,10 @@ class PLL_Admin_Filters_Term {
|
|
105 |
$lang = $this->model->get_term_language($term_id);
|
106 |
$taxonomy = $tag->taxonomy;
|
107 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
|
|
|
|
|
|
|
|
108 |
$dropdown = new PLL_Walker_Dropdown();
|
109 |
|
110 |
// disable the language dropdown and the translations input fields for default categories to prevent removal
|
@@ -148,8 +156,9 @@ class PLL_Admin_Filters_Term {
|
|
148 |
* @return string modified html
|
149 |
*/
|
150 |
public function wp_dropdown_cats($output) {
|
151 |
-
if (isset($_GET['taxonomy'], $_GET['from_tag'], $_GET['new_lang']) && $id = get_term($_GET['from_tag'], $_GET['taxonomy'])->parent) {
|
152 |
-
|
|
|
153 |
return str_replace('"'.$parent.'"', '"'.$parent.'" selected="selected"', $output);
|
154 |
}
|
155 |
return $output;
|
@@ -207,7 +216,7 @@ class PLL_Admin_Filters_Term {
|
|
207 |
else
|
208 |
check_admin_referer('pll_language', '_pll_nonce'); // edit tags or tags metabox
|
209 |
|
210 |
-
$this->model->set_term_language($term_id, $_POST['term_lang_choice']);
|
211 |
}
|
212 |
|
213 |
// *post* bulk edit, in case a new term is created
|
@@ -244,7 +253,7 @@ class PLL_Admin_Filters_Term {
|
|
244 |
}
|
245 |
|
246 |
else {
|
247 |
-
$this->model->set_term_language($term_id, $_GET['inline_lang_choice']);
|
248 |
}
|
249 |
}
|
250 |
|
@@ -256,12 +265,12 @@ class PLL_Admin_Filters_Term {
|
|
256 |
);
|
257 |
|
258 |
$old_lang = $this->model->get_term_language($term_id); // stores the old language
|
259 |
-
$lang = $_POST['inline_lang_choice']; // new language
|
260 |
$translations = $this->model->get_translations('term', $term_id);
|
261 |
|
262 |
// checks if the new language already exists in the translation group
|
263 |
-
if ($old_lang && $old_lang->slug != $lang) {
|
264 |
-
if (array_key_exists($lang, $translations)) {
|
265 |
$this->model->delete_translation('term', $term_id);
|
266 |
}
|
267 |
|
@@ -277,7 +286,7 @@ class PLL_Admin_Filters_Term {
|
|
277 |
// edit post
|
278 |
elseif (isset($_POST['post_lang_choice'])) {// FIXME should be useless now
|
279 |
check_admin_referer('pll_language', '_pll_nonce');
|
280 |
-
$this->model->set_term_language($term_id, $_POST['post_lang_choice']);
|
281 |
}
|
282 |
|
283 |
else
|
@@ -416,9 +425,12 @@ class PLL_Admin_Filters_Term {
|
|
416 |
check_ajax_referer('pll_language', '_pll_nonce');
|
417 |
|
418 |
$lang = $this->model->get_language($_POST['lang']);
|
419 |
-
$term_id = isset($_POST['term_id']) ? $_POST['term_id'] : null;
|
420 |
$taxonomy = $_POST['taxonomy'];
|
421 |
$post_type = $_POST['post_type'];
|
|
|
|
|
|
|
422 |
|
423 |
ob_start();
|
424 |
if ($lang)
|
@@ -469,30 +481,40 @@ class PLL_Admin_Filters_Term {
|
|
469 |
*/
|
470 |
public function ajax_terms_not_translated() {
|
471 |
check_ajax_referer('pll_language', '_pll_nonce');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
|
473 |
$return = array();
|
474 |
|
475 |
// it is more efficient to use one common query for all languages as soon as there are more than 2
|
476 |
// pll_get_terms_not_translated arg to identify this query in terms_clauses filter
|
477 |
-
foreach (get_terms($
|
478 |
$lang = $this->model->get_term_language($term->term_id);
|
479 |
|
480 |
-
if ($lang && $lang->slug == $
|
481 |
$return[] = array(
|
482 |
'id' => $term->term_id,
|
483 |
'value' => $term->name,
|
484 |
-
'link' => $this->edit_translation_link($term->term_id, $
|
485 |
);
|
486 |
}
|
487 |
|
488 |
// add current translation in list
|
489 |
// not in add term for as term_id is not set
|
490 |
-
if ('undefined' !== $_REQUEST['term_id'] && $term_id = $this->model->get_translation('term', $_REQUEST['term_id'], $
|
491 |
-
$term = get_term($term_id, $
|
492 |
array_unshift($return, array(
|
493 |
'id' => $term_id,
|
494 |
'value' => $term->name,
|
495 |
-
'link' => $this->edit_translation_link($term->term_id, $
|
496 |
));
|
497 |
}
|
498 |
|
@@ -522,10 +544,6 @@ class PLL_Admin_Filters_Term {
|
|
522 |
if (isset($screen) && 'nav-menus' == $screen->base && in_array('nav_menu', $taxonomies))
|
523 |
return $clauses;
|
524 |
|
525 |
-
// don't filter category checklist in post list table as this will be handled by js
|
526 |
-
if (isset($screen) && 'edit' == $screen->base)
|
527 |
-
return $clauses;
|
528 |
-
|
529 |
// if get_terms is queried with a 'lang' parameter
|
530 |
if (!empty($args['lang']))
|
531 |
return $this->model->terms_clauses($clauses, $args['lang']);
|
@@ -554,10 +572,6 @@ class PLL_Admin_Filters_Term {
|
|
554 |
if (isset($_POST['lang']))
|
555 |
$lang = $this->model->get_language($_POST['lang']);
|
556 |
|
557 |
-
// ajax tag search since WP 3.7
|
558 |
-
elseif (!empty($_GET['lang']) && isset($_GET['action']) && 'polylang-ajax-tag-search' == $_GET['action'])
|
559 |
-
$lang = $this->model->get_language($_GET['lang']);
|
560 |
-
|
561 |
// the post (or term) is created with the 'add new' (translation) link
|
562 |
// test of $args['page'] to avoid filtering the terms list table in edit-tags panel
|
563 |
elseif (!empty($_GET['new_lang']) && empty($args['page']))
|
@@ -582,7 +596,7 @@ class PLL_Admin_Filters_Term {
|
|
582 |
|
583 |
// for the parent dropdown list in edit term
|
584 |
elseif (isset($_GET['tag_ID']))
|
585 |
-
$lang = $this->model->get_term_language($_GET['tag_ID']);
|
586 |
|
587 |
// when a new category is created in the edit post panel
|
588 |
elseif (isset($_POST['term_lang_choice']))
|
64 |
public function add_term_form() {
|
65 |
$taxonomy = $_GET['taxonomy'];
|
66 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
67 |
+
|
68 |
+
if (!taxonomy_exists($taxonomy) || !post_type_exists($post_type))
|
69 |
+
return;
|
70 |
+
|
71 |
$lang = isset($_GET['new_lang']) ? $this->model->get_language($_GET['new_lang']) : $this->pref_lang;
|
72 |
$dropdown = new PLL_Walker_Dropdown();
|
73 |
|
109 |
$lang = $this->model->get_term_language($term_id);
|
110 |
$taxonomy = $tag->taxonomy;
|
111 |
$post_type = isset($GLOBALS['post_type']) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
|
112 |
+
|
113 |
+
if (!post_type_exists($post_type))
|
114 |
+
return;
|
115 |
+
|
116 |
$dropdown = new PLL_Walker_Dropdown();
|
117 |
|
118 |
// disable the language dropdown and the translations input fields for default categories to prevent removal
|
156 |
* @return string modified html
|
157 |
*/
|
158 |
public function wp_dropdown_cats($output) {
|
159 |
+
if (isset($_GET['taxonomy'], $_GET['from_tag'], $_GET['new_lang']) && taxonomy_exists($_GET['taxonomy']) && $id = get_term((int) $_GET['from_tag'], $_GET['taxonomy'])->parent) {
|
160 |
+
$lang = $this->model->get_language($_GET['new_lang']);
|
161 |
+
if ($parent = $this->model->get_translation('term', $id, $lang))
|
162 |
return str_replace('"'.$parent.'"', '"'.$parent.'" selected="selected"', $output);
|
163 |
}
|
164 |
return $output;
|
216 |
else
|
217 |
check_admin_referer('pll_language', '_pll_nonce'); // edit tags or tags metabox
|
218 |
|
219 |
+
$this->model->set_term_language($term_id, $this->model->get_language($_POST['term_lang_choice']));
|
220 |
}
|
221 |
|
222 |
// *post* bulk edit, in case a new term is created
|
253 |
}
|
254 |
|
255 |
else {
|
256 |
+
$this->model->set_term_language($term_id, $this->model->get_language($_GET['inline_lang_choice']));
|
257 |
}
|
258 |
}
|
259 |
|
265 |
);
|
266 |
|
267 |
$old_lang = $this->model->get_term_language($term_id); // stores the old language
|
268 |
+
$lang = $this->model->get_language($_POST['inline_lang_choice']); // new language
|
269 |
$translations = $this->model->get_translations('term', $term_id);
|
270 |
|
271 |
// checks if the new language already exists in the translation group
|
272 |
+
if ($old_lang && $old_lang->slug != $lang->slug) {
|
273 |
+
if (array_key_exists($lang->slug, $translations)) {
|
274 |
$this->model->delete_translation('term', $term_id);
|
275 |
}
|
276 |
|
286 |
// edit post
|
287 |
elseif (isset($_POST['post_lang_choice'])) {// FIXME should be useless now
|
288 |
check_admin_referer('pll_language', '_pll_nonce');
|
289 |
+
$this->model->set_term_language($term_id, $this->model->get_language($_POST['post_lang_choice']));
|
290 |
}
|
291 |
|
292 |
else
|
425 |
check_ajax_referer('pll_language', '_pll_nonce');
|
426 |
|
427 |
$lang = $this->model->get_language($_POST['lang']);
|
428 |
+
$term_id = isset($_POST['term_id']) ? (int) $_POST['term_id'] : null;
|
429 |
$taxonomy = $_POST['taxonomy'];
|
430 |
$post_type = $_POST['post_type'];
|
431 |
+
|
432 |
+
if (!post_type_exists($post_type) || ! taxonomy_exists($taxonomy))
|
433 |
+
die(0);
|
434 |
|
435 |
ob_start();
|
436 |
if ($lang)
|
481 |
*/
|
482 |
public function ajax_terms_not_translated() {
|
483 |
check_ajax_referer('pll_language', '_pll_nonce');
|
484 |
+
|
485 |
+
$s = wp_unslash($_REQUEST['term']);
|
486 |
+
$post_type = $_REQUEST['post_type'];
|
487 |
+
$taxonomy = $_REQUEST['taxonomy'];
|
488 |
+
|
489 |
+
if (!post_type_exists($post_type) || ! taxonomy_exists($taxonomy))
|
490 |
+
die(0);
|
491 |
+
|
492 |
+
$term_language = $this->model->get_language($_REQUEST['term_language']);
|
493 |
+
$translation_language = $this->model->get_language($_REQUEST['translation_language']);
|
494 |
|
495 |
$return = array();
|
496 |
|
497 |
// it is more efficient to use one common query for all languages as soon as there are more than 2
|
498 |
// pll_get_terms_not_translated arg to identify this query in terms_clauses filter
|
499 |
+
foreach (get_terms($taxonomy, 'hide_empty=0&pll_get_terms_not_translated=1&name__like=' . $s) as $term) {
|
500 |
$lang = $this->model->get_term_language($term->term_id);
|
501 |
|
502 |
+
if ($lang && $lang->slug == $translation_language->slug && !$this->model->get_translation('term', $term->term_id, $term_language))
|
503 |
$return[] = array(
|
504 |
'id' => $term->term_id,
|
505 |
'value' => $term->name,
|
506 |
+
'link' => $this->edit_translation_link($term->term_id, $taxonomy, $post_type)
|
507 |
);
|
508 |
}
|
509 |
|
510 |
// add current translation in list
|
511 |
// not in add term for as term_id is not set
|
512 |
+
if ('undefined' !== $_REQUEST['term_id'] && $term_id = $this->model->get_translation('term', (int) $_REQUEST['term_id'], $translation_language)) {
|
513 |
+
$term = get_term($term_id, $taxonomy);
|
514 |
array_unshift($return, array(
|
515 |
'id' => $term_id,
|
516 |
'value' => $term->name,
|
517 |
+
'link' => $this->edit_translation_link($term->term_id, $taxonomy, $post_type)
|
518 |
));
|
519 |
}
|
520 |
|
544 |
if (isset($screen) && 'nav-menus' == $screen->base && in_array('nav_menu', $taxonomies))
|
545 |
return $clauses;
|
546 |
|
|
|
|
|
|
|
|
|
547 |
// if get_terms is queried with a 'lang' parameter
|
548 |
if (!empty($args['lang']))
|
549 |
return $this->model->terms_clauses($clauses, $args['lang']);
|
572 |
if (isset($_POST['lang']))
|
573 |
$lang = $this->model->get_language($_POST['lang']);
|
574 |
|
|
|
|
|
|
|
|
|
575 |
// the post (or term) is created with the 'add new' (translation) link
|
576 |
// test of $args['page'] to avoid filtering the terms list table in edit-tags panel
|
577 |
elseif (!empty($_GET['new_lang']) && empty($args['page']))
|
596 |
|
597 |
// for the parent dropdown list in edit term
|
598 |
elseif (isset($_GET['tag_ID']))
|
599 |
+
$lang = $this->model->get_term_language((int) $_GET['tag_ID']);
|
600 |
|
601 |
// when a new category is created in the edit post panel
|
602 |
elseif (isset($_POST['term_lang_choice']))
|
admin/admin-filters.php
CHANGED
@@ -77,8 +77,8 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
77 |
* @return array widget options
|
78 |
*/
|
79 |
public function widget_update_callback($instance, $new_instance, $old_instance, $widget) {
|
80 |
-
if (!empty($_POST[$widget->id.'_lang_choice']))
|
81 |
-
$instance['pll_lang'] = $_POST[$
|
82 |
else
|
83 |
unset($instance['pll_lang']);
|
84 |
|
@@ -95,7 +95,7 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
95 |
public function personal_options_update($user_id) {
|
96 |
// admin language
|
97 |
$user_lang = in_array($_POST['user_lang'], $this->model->get_languages_list(array('fields' => 'locale'))) ? $_POST['user_lang'] : 0;
|
98 |
-
update_user_meta($user_id, 'user_lang', $
|
99 |
|
100 |
// biography translations
|
101 |
foreach ($this->model->get_languages_list() as $lang) {
|
77 |
* @return array widget options
|
78 |
*/
|
79 |
public function widget_update_callback($instance, $new_instance, $old_instance, $widget) {
|
80 |
+
if (!empty($_POST[$key = $widget->id.'_lang_choice']) && in_array($_POST[$key], $this->model->get_languages_list(array('fields' => 'slug'))))
|
81 |
+
$instance['pll_lang'] = $_POST[$key];
|
82 |
else
|
83 |
unset($instance['pll_lang']);
|
84 |
|
95 |
public function personal_options_update($user_id) {
|
96 |
// admin language
|
97 |
$user_lang = in_array($_POST['user_lang'], $this->model->get_languages_list(array('fields' => 'locale'))) ? $_POST['user_lang'] : 0;
|
98 |
+
update_user_meta($user_id, 'user_lang', $user_lang);
|
99 |
|
100 |
// biography translations
|
101 |
foreach ($this->model->get_languages_list() as $lang) {
|
admin/admin-model.php
CHANGED
@@ -31,14 +31,14 @@ class PLL_Admin_Model extends PLL_Model {
|
|
31 |
return false;
|
32 |
|
33 |
// first the language taxonomy
|
34 |
-
$description = serialize(array('locale' => $args['locale'], 'rtl' => $args['rtl']));
|
35 |
$r = wp_insert_term($args['name'], 'language', array('slug' => $args['slug'], 'description' => $description));
|
36 |
if (is_wp_error($r)) {
|
37 |
// avoid an ugly fatal error if something went wrong (reported once in the forum)
|
38 |
add_settings_error('general', 'pll_add_language', __('Impossible to add the language.', 'polylang'));
|
39 |
return false;
|
40 |
}
|
41 |
-
wp_update_term((int) $r['term_id'], 'language', array('term_group' => $args['term_group'])); // can't set the term group directly in wp_insert_term
|
42 |
|
43 |
// the term_language taxonomy
|
44 |
// don't want shared terms so use a different slug
|
@@ -96,7 +96,6 @@ class PLL_Admin_Model extends PLL_Model {
|
|
96 |
}
|
97 |
}
|
98 |
|
99 |
-
|
100 |
// delete menus locations
|
101 |
if (!empty($this->options['nav_menus'])) {
|
102 |
foreach ($this->options['nav_menus'] as $theme => $locations) {
|
@@ -171,7 +170,6 @@ class PLL_Admin_Model extends PLL_Model {
|
|
171 |
$slug = $args['slug'];
|
172 |
$old_slug = $lang->slug;
|
173 |
|
174 |
-
// FIXME should do this in an action 'edit_term' to prevent translations to break when sharing a term with nav_menu?
|
175 |
if ($old_slug != $slug) {
|
176 |
// update the language slug in translations
|
177 |
$this->update_translations($old_slug, $slug);
|
@@ -199,7 +197,6 @@ class PLL_Admin_Model extends PLL_Model {
|
|
199 |
$this->options['nav_menus'][$theme][$location][$slug] = $this->options['nav_menus'][$theme][$location][$old_slug];
|
200 |
unset($this->options['nav_menus'][$theme][$location][$old_slug]);
|
201 |
}
|
202 |
-
|
203 |
}
|
204 |
}
|
205 |
}
|
@@ -207,7 +204,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
207 |
// update domains
|
208 |
if (!empty($this->options['domains'][$old_slug])) {
|
209 |
$this->options['domains'][$slug] = $this->options['domains'][$old_slug];
|
210 |
-
unset($this->options['domains'][$
|
211 |
}
|
212 |
|
213 |
// update the default language option if necessary
|
@@ -218,8 +215,8 @@ class PLL_Admin_Model extends PLL_Model {
|
|
218 |
update_option('polylang', $this->options);
|
219 |
|
220 |
// and finally update the language itself
|
221 |
-
$description = serialize(array('locale' => $args['locale'], 'rtl' => $args['rtl']));
|
222 |
-
wp_update_term((int) $lang->term_id, 'language', array('slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => $args['term_group']));
|
223 |
wp_update_term((int) $lang->tl_term_id, 'term_language', array('slug' => 'pll_' . $slug, 'name' => $args['name']));
|
224 |
|
225 |
$this->clean_languages_cache();
|
@@ -252,7 +249,8 @@ class PLL_Admin_Model extends PLL_Model {
|
|
252 |
add_settings_error('general', 'pll_non_unique_slug', __('The language code must be unique', 'polylang'));
|
253 |
|
254 |
// validate name
|
255 |
-
|
|
|
256 |
add_settings_error('general', 'pll_invalid_name', __('The language must have a name', 'polylang'));
|
257 |
|
258 |
return get_settings_errors() ? false : true;
|
@@ -270,6 +268,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
270 |
public function set_language_in_mass($type, $ids, $lang) {
|
271 |
global $wpdb;
|
272 |
|
|
|
273 |
$lang = $this->get_language($lang);
|
274 |
$tt_id = 'term' == $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
275 |
|
31 |
return false;
|
32 |
|
33 |
// first the language taxonomy
|
34 |
+
$description = serialize(array('locale' => $args['locale'], 'rtl' => (int) $args['rtl']));
|
35 |
$r = wp_insert_term($args['name'], 'language', array('slug' => $args['slug'], 'description' => $description));
|
36 |
if (is_wp_error($r)) {
|
37 |
// avoid an ugly fatal error if something went wrong (reported once in the forum)
|
38 |
add_settings_error('general', 'pll_add_language', __('Impossible to add the language.', 'polylang'));
|
39 |
return false;
|
40 |
}
|
41 |
+
wp_update_term((int) $r['term_id'], 'language', array('term_group' => (int) $args['term_group'])); // can't set the term group directly in wp_insert_term
|
42 |
|
43 |
// the term_language taxonomy
|
44 |
// don't want shared terms so use a different slug
|
96 |
}
|
97 |
}
|
98 |
|
|
|
99 |
// delete menus locations
|
100 |
if (!empty($this->options['nav_menus'])) {
|
101 |
foreach ($this->options['nav_menus'] as $theme => $locations) {
|
170 |
$slug = $args['slug'];
|
171 |
$old_slug = $lang->slug;
|
172 |
|
|
|
173 |
if ($old_slug != $slug) {
|
174 |
// update the language slug in translations
|
175 |
$this->update_translations($old_slug, $slug);
|
197 |
$this->options['nav_menus'][$theme][$location][$slug] = $this->options['nav_menus'][$theme][$location][$old_slug];
|
198 |
unset($this->options['nav_menus'][$theme][$location][$old_slug]);
|
199 |
}
|
|
|
200 |
}
|
201 |
}
|
202 |
}
|
204 |
// update domains
|
205 |
if (!empty($this->options['domains'][$old_slug])) {
|
206 |
$this->options['domains'][$slug] = $this->options['domains'][$old_slug];
|
207 |
+
unset($this->options['domains'][$old_slug]);
|
208 |
}
|
209 |
|
210 |
// update the default language option if necessary
|
215 |
update_option('polylang', $this->options);
|
216 |
|
217 |
// and finally update the language itself
|
218 |
+
$description = serialize(array('locale' => $args['locale'], 'rtl' => (int) $args['rtl']));
|
219 |
+
wp_update_term((int) $lang->term_id, 'language', array('slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => (int) $args['term_group']));
|
220 |
wp_update_term((int) $lang->tl_term_id, 'term_language', array('slug' => 'pll_' . $slug, 'name' => $args['name']));
|
221 |
|
222 |
$this->clean_languages_cache();
|
249 |
add_settings_error('general', 'pll_non_unique_slug', __('The language code must be unique', 'polylang'));
|
250 |
|
251 |
// validate name
|
252 |
+
// no need to sanitize it as wp_insert_term will do it for us
|
253 |
+
if (empty($args['name']))
|
254 |
add_settings_error('general', 'pll_invalid_name', __('The language must have a name', 'polylang'));
|
255 |
|
256 |
return get_settings_errors() ? false : true;
|
268 |
public function set_language_in_mass($type, $ids, $lang) {
|
269 |
global $wpdb;
|
270 |
|
271 |
+
$ids = array_map('intval', $ids);
|
272 |
$lang = $this->get_language($lang);
|
273 |
$tt_id = 'term' == $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
274 |
|
admin/admin-nav-menu.php
CHANGED
@@ -44,7 +44,8 @@ class PLL_Admin_Nav_Menu {
|
|
44 |
|
45 |
// translation of menus based on chosen locations
|
46 |
add_filter('pre_update_option_theme_mods_' . $this->theme, array($this, 'update_nav_menu_locations'));
|
47 |
-
add_filter('theme_mod_nav_menu_locations', array($this, 'nav_menu_locations'), 20);
|
|
|
48 |
|
49 |
// filter _wp_auto_add_pages_to_menu by language
|
50 |
add_action('transition_post_status', array(&$this, 'auto_add_pages_to_menu'), 5, 3); // before _wp_auto_add_pages_to_menu
|
@@ -252,7 +253,7 @@ class PLL_Admin_Nav_Menu {
|
|
252 |
if (is_array($menus)) {
|
253 |
foreach ($menus as $loc => $menu) {
|
254 |
foreach ($this->model->get_languages_list() as $lang) {
|
255 |
-
if (pll_default_language() != $lang->slug && !empty($this->options['nav_menus'][$this->theme][$loc][$lang->slug]))
|
256 |
$menus[$loc . '___' . $lang->slug] = $this->options['nav_menus'][$this->theme][$loc][$lang->slug];
|
257 |
}
|
258 |
}
|
@@ -261,6 +262,26 @@ class PLL_Admin_Nav_Menu {
|
|
261 |
return $menus;
|
262 |
}
|
263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
/*
|
265 |
* filters _wp_auto_add_pages_to_menu by language
|
266 |
*
|
44 |
|
45 |
// translation of menus based on chosen locations
|
46 |
add_filter('pre_update_option_theme_mods_' . $this->theme, array($this, 'update_nav_menu_locations'));
|
47 |
+
add_filter('theme_mod_nav_menu_locations', array($this, 'nav_menu_locations'), 20);
|
48 |
+
add_action('delete_nav_menu', array(&$this, 'delete_nav_menu'));
|
49 |
|
50 |
// filter _wp_auto_add_pages_to_menu by language
|
51 |
add_action('transition_post_status', array(&$this, 'auto_add_pages_to_menu'), 5, 3); // before _wp_auto_add_pages_to_menu
|
253 |
if (is_array($menus)) {
|
254 |
foreach ($menus as $loc => $menu) {
|
255 |
foreach ($this->model->get_languages_list() as $lang) {
|
256 |
+
if (pll_default_language() != $lang->slug && !empty($this->options['nav_menus'][$this->theme][$loc][$lang->slug]) && term_exists($this->options['nav_menus'][$this->theme][$loc][$lang->slug], 'nav_menu'))
|
257 |
$menus[$loc . '___' . $lang->slug] = $this->options['nav_menus'][$this->theme][$loc][$lang->slug];
|
258 |
}
|
259 |
}
|
262 |
return $menus;
|
263 |
}
|
264 |
|
265 |
+
/*
|
266 |
+
* removes the nav menu term_id from the locations stored in Polylang options when a nav menu is deleted
|
267 |
+
*
|
268 |
+
* @since 1.7.3
|
269 |
+
*
|
270 |
+
* @param int nav menu id
|
271 |
+
*/
|
272 |
+
function delete_nav_menu($term_id) {
|
273 |
+
foreach ($this->options['nav_menus'] as $theme => $locations) {
|
274 |
+
foreach ($locations as $loc => $languages) {
|
275 |
+
foreach ($languages as $lang => $menu_id) {
|
276 |
+
if ($menu_id === $term_id)
|
277 |
+
unset($this->options['nav_menus'][$theme][$loc][$lang]);
|
278 |
+
}
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
update_option('polylang', $this->options);
|
283 |
+
}
|
284 |
+
|
285 |
/*
|
286 |
* filters _wp_auto_add_pages_to_menu by language
|
287 |
*
|
admin/admin-strings.php
CHANGED
@@ -106,7 +106,7 @@ class PLL_Admin_Strings {
|
|
106 |
* @return string
|
107 |
*/
|
108 |
static public function sanitize_string_translation($translation, $name) {
|
109 |
-
$translation =
|
110 |
|
111 |
if (false !== ($option = array_search($name, self::$default_strings['options'], true)))
|
112 |
$translation = sanitize_option($option, $translation);
|
@@ -115,7 +115,7 @@ class PLL_Admin_Strings {
|
|
115 |
$translation = strip_tags($translation);
|
116 |
|
117 |
if ($name == self::$default_strings['widget_text'] && !current_user_can('unfiltered_html'))
|
118 |
-
$translation =
|
119 |
|
120 |
return $translation;
|
121 |
}
|
106 |
* @return string
|
107 |
*/
|
108 |
static public function sanitize_string_translation($translation, $name) {
|
109 |
+
$translation = wp_unslash(trim($translation));
|
110 |
|
111 |
if (false !== ($option = array_search($name, self::$default_strings['options'], true)))
|
112 |
$translation = sanitize_option($option, $translation);
|
115 |
$translation = strip_tags($translation);
|
116 |
|
117 |
if ($name == self::$default_strings['widget_text'] && !current_user_can('unfiltered_html'))
|
118 |
+
$translation = wp_unslash( wp_filter_post_kses( addslashes($translation) ) ); // wp_filter_post_kses() expects slashed
|
119 |
|
120 |
return $translation;
|
121 |
}
|
admin/admin-sync.php
CHANGED
@@ -31,7 +31,7 @@ class PLL_Admin_Sync {
|
|
31 |
* @since 0.6
|
32 |
*/
|
33 |
function wp_insert_post_parent($post_parent) {
|
34 |
-
return isset($_GET['from_post'], $_GET['new_lang']) && ($id = wp_get_post_parent_id($_GET['from_post'])) && ($parent = $this->model->get_translation('post', $id, $_GET['new_lang'])) ? $parent : $post_parent;
|
35 |
}
|
36 |
|
37 |
/*
|
@@ -47,15 +47,18 @@ class PLL_Admin_Sync {
|
|
47 |
if ('post-new.php' == $GLOBALS['pagenow'] && isset($_GET['from_post'], $_GET['new_lang'])) {
|
48 |
if (!$this->model->is_translated_post_type($post->post_type))
|
49 |
return;
|
50 |
-
|
51 |
// capability check already done in post-new.php
|
52 |
-
$
|
|
|
|
|
|
|
53 |
|
54 |
-
$from_post = get_post($
|
55 |
foreach (array('menu_order', 'comment_status', 'ping_status') as $property)
|
56 |
$post->$property = $from_post->$property;
|
57 |
|
58 |
-
if (in_array('sticky_posts', $this->options['sync']) && is_sticky($
|
59 |
stick_post($post->ID);
|
60 |
}
|
61 |
}
|
@@ -255,12 +258,12 @@ class PLL_Admin_Sync {
|
|
255 |
continue;
|
256 |
|
257 |
if (isset($_POST['parent']) && $_POST['parent'] != -1) // since WP 3.1
|
258 |
-
$term_parent = $this->model->get_translation('term', $_POST['parent'], $lang);
|
259 |
|
260 |
global $wpdb;
|
261 |
$wpdb->update($wpdb->term_taxonomy,
|
262 |
array('parent'=> isset($term_parent) ? $term_parent : 0),
|
263 |
-
array('term_taxonomy_id' => get_term($tr_id, $taxonomy)->term_taxonomy_id));
|
264 |
}
|
265 |
}
|
266 |
}
|
31 |
* @since 0.6
|
32 |
*/
|
33 |
function wp_insert_post_parent($post_parent) {
|
34 |
+
return isset($_GET['from_post'], $_GET['new_lang']) && ($id = wp_get_post_parent_id((int) $_GET['from_post'])) && ($parent = $this->model->get_translation('post', $id, $_GET['new_lang'])) ? $parent : $post_parent;
|
35 |
}
|
36 |
|
37 |
/*
|
47 |
if ('post-new.php' == $GLOBALS['pagenow'] && isset($_GET['from_post'], $_GET['new_lang'])) {
|
48 |
if (!$this->model->is_translated_post_type($post->post_type))
|
49 |
return;
|
50 |
+
|
51 |
// capability check already done in post-new.php
|
52 |
+
$from_post_id = (int) $_GET['from_post'];
|
53 |
+
$lang = $this->model->get_language($_GET['new_lang']);
|
54 |
+
|
55 |
+
$this->copy_post_metas($from_post_id, $post->ID, $lang->slug);
|
56 |
|
57 |
+
$from_post = get_post($from_post_id);
|
58 |
foreach (array('menu_order', 'comment_status', 'ping_status') as $property)
|
59 |
$post->$property = $from_post->$property;
|
60 |
|
61 |
+
if (in_array('sticky_posts', $this->options['sync']) && is_sticky($from_post_id))
|
62 |
stick_post($post->ID);
|
63 |
}
|
64 |
}
|
258 |
continue;
|
259 |
|
260 |
if (isset($_POST['parent']) && $_POST['parent'] != -1) // since WP 3.1
|
261 |
+
$term_parent = $this->model->get_translation('term', (int) $_POST['parent'], $lang);
|
262 |
|
263 |
global $wpdb;
|
264 |
$wpdb->update($wpdb->term_taxonomy,
|
265 |
array('parent'=> isset($term_parent) ? $term_parent : 0),
|
266 |
+
array('term_taxonomy_id' => get_term((int) $tr_id, $taxonomy)->term_taxonomy_id));
|
267 |
}
|
268 |
}
|
269 |
}
|
admin/admin.php
CHANGED
@@ -293,8 +293,6 @@ class PLL_Admin extends PLL_Base {
|
|
293 |
if ($selected->slug == $lang->slug)
|
294 |
continue;
|
295 |
|
296 |
-
$img = empty($lang->flag) ? '' : (false !== strpos($lang->flag, 'img') ? $lang->flag . ' ' : $lang->flag);
|
297 |
-
|
298 |
$wp_admin_bar->add_menu(array(
|
299 |
'parent' => 'languages',
|
300 |
'id' => $lang->slug,
|
293 |
if ($selected->slug == $lang->slug)
|
294 |
continue;
|
295 |
|
|
|
|
|
296 |
$wp_admin_bar->add_menu(array(
|
297 |
'parent' => 'languages',
|
298 |
'id' => $lang->slug,
|
admin/settings.php
CHANGED
@@ -115,17 +115,20 @@ class PLL_Settings {
|
|
115 |
// get the strings to translate
|
116 |
$data = PLL_Admin_Strings::get_strings();
|
117 |
|
118 |
-
|
119 |
-
foreach ($data as $key
|
120 |
-
$groups[] = $row['context'];
|
121 |
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
124 |
unset ($data[$key]);
|
125 |
}
|
126 |
|
127 |
-
$groups = array_unique($groups);
|
128 |
-
|
129 |
// load translations
|
130 |
foreach ($listlanguages as $language) {
|
131 |
// filters by language if requested
|
@@ -215,7 +218,7 @@ class PLL_Settings {
|
|
215 |
$strings = PLL_Admin_Strings::get_strings();
|
216 |
|
217 |
foreach ($this->model->get_languages_list() as $language) {
|
218 |
-
if(empty($_POST['translation'][$language->slug])) // in case the language filter is active (thanks to John P. Bloch)
|
219 |
continue;
|
220 |
|
221 |
$mo = new PLL_MO();
|
115 |
// get the strings to translate
|
116 |
$data = PLL_Admin_Strings::get_strings();
|
117 |
|
118 |
+
// get the groups
|
119 |
+
foreach ($data as $key => $row)
|
120 |
+
$groups[] = $row['context'];
|
121 |
|
122 |
+
$groups = array_unique($groups);
|
123 |
+
$selected = empty($_REQUEST['group']) || !in_array($_REQUEST['group'], $groups) ? -1 : $_REQUEST['group'];
|
124 |
+
$s = empty($_REQUEST['s']) ? '' : wp_unslash($_REQUEST['s']);
|
125 |
+
|
126 |
+
// filter for search string
|
127 |
+
foreach ($data as $key => $row) {
|
128 |
+
if (($selected !=-1 && $row['context'] != $selected) || (!empty($s) && stripos($row['name'], $s) === false && stripos($row['string'], $s) === false))
|
129 |
unset ($data[$key]);
|
130 |
}
|
131 |
|
|
|
|
|
132 |
// load translations
|
133 |
foreach ($listlanguages as $language) {
|
134 |
// filters by language if requested
|
218 |
$strings = PLL_Admin_Strings::get_strings();
|
219 |
|
220 |
foreach ($this->model->get_languages_list() as $language) {
|
221 |
+
if (empty($_POST['translation'][$language->slug])) // in case the language filter is active (thanks to John P. Bloch)
|
222 |
continue;
|
223 |
|
224 |
$mo = new PLL_MO();
|
admin/table-languages.php
CHANGED
@@ -34,7 +34,18 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
34 |
* @return string
|
35 |
*/
|
36 |
function column_default($item, $column_name) {
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
39 |
|
40 |
/*
|
@@ -47,7 +58,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
47 |
* @return string
|
48 |
*/
|
49 |
function column_name($item) {
|
50 |
-
return $item->name . $this->row_actions(array(
|
51 |
'edit' => sprintf(
|
52 |
'<a href="%s">%s</a>',
|
53 |
esc_url(admin_url('admin.php?page=mlang&pll_action=edit&lang=' . $item->term_id)),
|
@@ -89,11 +100,11 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
89 |
*/
|
90 |
function get_sortable_columns() {
|
91 |
return array(
|
92 |
-
'name'
|
93 |
-
'locale'
|
94 |
-
'slug'
|
95 |
'term_group' => array('term_group', false),
|
96 |
-
'count'
|
97 |
);
|
98 |
}
|
99 |
|
34 |
* @return string
|
35 |
*/
|
36 |
function column_default($item, $column_name) {
|
37 |
+
switch($column_name) {
|
38 |
+
case 'locale':
|
39 |
+
case 'slug':
|
40 |
+
return esc_html($item->$column_name);
|
41 |
+
|
42 |
+
case 'term_group':
|
43 |
+
case 'count':
|
44 |
+
return (int) $item->$column_name;
|
45 |
+
|
46 |
+
default:
|
47 |
+
return $item->$column_name; // flag
|
48 |
+
}
|
49 |
}
|
50 |
|
51 |
/*
|
58 |
* @return string
|
59 |
*/
|
60 |
function column_name($item) {
|
61 |
+
return esc_html($item->name) . $this->row_actions(array(
|
62 |
'edit' => sprintf(
|
63 |
'<a href="%s">%s</a>',
|
64 |
esc_url(admin_url('admin.php?page=mlang&pll_action=edit&lang=' . $item->term_id)),
|
100 |
*/
|
101 |
function get_sortable_columns() {
|
102 |
return array(
|
103 |
+
'name' => array('name', true), // sorted by name by default
|
104 |
+
'locale' => array('locale', false),
|
105 |
+
'slug' => array('slug', false),
|
106 |
'term_group' => array('term_group', false),
|
107 |
+
'count' => array('count', false)
|
108 |
);
|
109 |
}
|
110 |
|
frontend/choose-lang.php
CHANGED
@@ -224,7 +224,7 @@ abstract class PLL_Choose_Lang {
|
|
224 |
$query->set('page_id', $this->page_on_front);
|
225 |
$query->is_singular = $query->is_page = true;
|
226 |
$query->is_archive = $query->is_tax = false;
|
227 |
-
unset($query->queried_object); // reset queried object
|
228 |
}
|
229 |
|
230 |
// takes care of paged front page
|
224 |
$query->set('page_id', $this->page_on_front);
|
225 |
$query->is_singular = $query->is_page = true;
|
226 |
$query->is_archive = $query->is_tax = false;
|
227 |
+
unset($query->query_vars['lang'], $query->queried_object); // reset queried object
|
228 |
}
|
229 |
|
230 |
// takes care of paged front page
|
frontend/frontend-links.php
CHANGED
@@ -238,7 +238,16 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
238 |
public function redirect_canonical($redirect_url, $requested_url) {
|
239 |
global $wp_query;
|
240 |
if (is_page() && !is_feed() && isset($wp_query->queried_object) && $wp_query->queried_object->ID == $this->page_on_front) {
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
}
|
243 |
|
244 |
// protect against chained redirects
|
@@ -501,9 +510,13 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
501 |
$redirect_url = $requested_url;
|
502 |
}
|
503 |
else {
|
|
|
|
|
|
|
|
|
504 |
$redirect_url = $this->options['force_lang'] ?
|
505 |
-
$this->links_model->switch_language_in_link($
|
506 |
-
$this->links_model->remove_language_from_link($
|
507 |
}
|
508 |
|
509 |
// allow plugins to change the redirection or even cancel it by setting $redirect_url to false
|
238 |
public function redirect_canonical($redirect_url, $requested_url) {
|
239 |
global $wp_query;
|
240 |
if (is_page() && !is_feed() && isset($wp_query->queried_object) && $wp_query->queried_object->ID == $this->page_on_front) {
|
241 |
+
$url = is_paged() ? $this->links_model->add_paged_to_link($this->get_home_url(), $wp_query->query_vars['page']) : $this->get_home_url();
|
242 |
+
|
243 |
+
// don't forget additional query vars
|
244 |
+
$query = parse_url($redirect_url, PHP_URL_QUERY);
|
245 |
+
if (!empty($query)) {
|
246 |
+
parse_str($query, $query_vars);
|
247 |
+
$url = add_query_arg($query_vars, $url);
|
248 |
+
}
|
249 |
+
|
250 |
+
return $url;
|
251 |
}
|
252 |
|
253 |
// protect against chained redirects
|
510 |
$redirect_url = $requested_url;
|
511 |
}
|
512 |
else {
|
513 |
+
// first get the canonical url evaluated by WP
|
514 |
+
$redirect_url = (!$redirect_url = redirect_canonical($requested_url, false)) ? $requested_url : $redirect_url;
|
515 |
+
|
516 |
+
// then get the right language code in url
|
517 |
$redirect_url = $this->options['force_lang'] ?
|
518 |
+
$this->links_model->switch_language_in_link($redirect_url, $language) :
|
519 |
+
$this->links_model->remove_language_from_link($redirect_url); // works only for default permalinks
|
520 |
}
|
521 |
|
522 |
// allow plugins to change the redirection or even cancel it by setting $redirect_url to false
|
frontend/frontend-nav-menu.php
CHANGED
@@ -124,7 +124,7 @@ class PLL_Frontend_Nav_Menu {
|
|
124 |
*/
|
125 |
public function nav_menu_link_attributes($atts, $item, $args) {
|
126 |
if (isset($item->lang))
|
127 |
-
$atts['hreflang'] = $item->lang;
|
128 |
return $atts;
|
129 |
}
|
130 |
|
124 |
*/
|
125 |
public function nav_menu_link_attributes($atts, $item, $args) {
|
126 |
if (isset($item->lang))
|
127 |
+
$atts['hreflang'] = esc_attr($item->lang);
|
128 |
return $atts;
|
129 |
}
|
130 |
|
frontend/frontend.php
CHANGED
@@ -114,15 +114,14 @@ class PLL_Frontend extends PLL_Base {
|
|
114 |
// reset the queried object
|
115 |
if (empty($taxonomies) && ($query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search)) {
|
116 |
$query->is_tax = false;
|
117 |
-
unset($query->queried_object);
|
118 |
-
get_queried_object();
|
119 |
}
|
120 |
|
121 |
// move the language tax_query at the end to avoid it being the queried object
|
122 |
if (!empty($taxonomies) && 'language' == reset( $queried_taxonomies )) {
|
123 |
$query->tax_query->queried_terms['language'] = array_shift($query->tax_query->queried_terms);
|
124 |
unset($query->queried_object);
|
125 |
-
get_queried_object();
|
126 |
}
|
127 |
}
|
128 |
}
|
114 |
// reset the queried object
|
115 |
if (empty($taxonomies) && ($query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search)) {
|
116 |
$query->is_tax = false;
|
117 |
+
unset($query->queried_object); // FIXME useless?
|
|
|
118 |
}
|
119 |
|
120 |
// move the language tax_query at the end to avoid it being the queried object
|
121 |
if (!empty($taxonomies) && 'language' == reset( $queried_taxonomies )) {
|
122 |
$query->tax_query->queried_terms['language'] = array_shift($query->tax_query->queried_terms);
|
123 |
unset($query->queried_object);
|
124 |
+
get_queried_object(); // necessary to avoid the language being the queried object
|
125 |
}
|
126 |
}
|
127 |
}
|
include/language.php
CHANGED
@@ -43,26 +43,36 @@ class PLL_Language {
|
|
43 |
*
|
44 |
* @since 1.2
|
45 |
*
|
46 |
-
* @param object $language 'language' term
|
47 |
* @param object $term_language corresponding 'term_language' term
|
48 |
*/
|
49 |
-
public function __construct($language, $term_language) {
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
|
63 |
-
|
64 |
|
65 |
-
|
|
|
|
|
66 |
}
|
67 |
|
68 |
/*
|
43 |
*
|
44 |
* @since 1.2
|
45 |
*
|
46 |
+
* @param object|array $language 'language' term or language object properties stored as an array
|
47 |
* @param object $term_language corresponding 'term_language' term
|
48 |
*/
|
49 |
+
public function __construct($language, $term_language = null) {
|
50 |
+
// build the object from all properties stored as an array
|
51 |
+
if (empty($term_language)) {
|
52 |
+
foreach ($language as $prop => $value)
|
53 |
+
$this->$prop = $value;
|
54 |
+
}
|
55 |
+
|
56 |
+
// build the object from taxonomies
|
57 |
+
else {
|
58 |
+
foreach ($language as $prop => $value)
|
59 |
+
$this->$prop = in_array($prop, array('term_id', 'term_taxonomy_id', 'count')) ? (int) $language->$prop : $language->$prop;
|
60 |
|
61 |
+
// although it would be convenient here, don't assume the term is shared between taxonomies as it may not be the case in future
|
62 |
+
// http://make.wordpress.org/core/2013/07/28/potential-roadmap-for-taxonomy-meta-and-post-relationships/
|
63 |
+
$this->tl_term_id = (int) $term_language->term_id;
|
64 |
+
$this->tl_term_taxonomy_id = (int) $term_language->term_taxonomy_id;
|
65 |
+
$this->tl_count = (int) $term_language->count;
|
66 |
|
67 |
+
$description = maybe_unserialize($language->description);
|
68 |
+
$this->locale = $description['locale'];
|
69 |
+
$this->is_rtl = $description['rtl'];
|
70 |
|
71 |
+
$this->description = &$this->locale; // backward compatibility with Polylang < 1.2
|
72 |
|
73 |
+
$this->mo_id = PLL_MO::get_id($this);
|
74 |
+
$this->set_flag();
|
75 |
+
}
|
76 |
}
|
77 |
|
78 |
/*
|
include/model.php
CHANGED
@@ -61,7 +61,7 @@ class PLL_Model {
|
|
61 |
public function _prime_terms_cache($terms, $taxonomies) {
|
62 |
if ($this->is_translated_taxonomy($taxonomies)) {
|
63 |
foreach ($terms as $term) {
|
64 |
-
$term_ids[] = is_object($term) ? $term->term_id : $term;
|
65 |
}
|
66 |
}
|
67 |
|
@@ -101,6 +101,7 @@ class PLL_Model {
|
|
101 |
if (empty($object_id))
|
102 |
return false;
|
103 |
|
|
|
104 |
$term = get_object_term_cache($object_id, $taxonomy);
|
105 |
|
106 |
if (false === $term) {
|
@@ -146,6 +147,8 @@ class PLL_Model {
|
|
146 |
*/
|
147 |
public function get_languages_list($args = array()) {
|
148 |
if (false === $languages = $this->cache->get('languages')) {
|
|
|
|
|
149 |
if ((defined('PLL_CACHE_LANGUAGES') && !PLL_CACHE_LANGUAGES) || false === ($languages = get_transient('pll_languages_list'))) {
|
150 |
$languages = get_terms('language', array('hide_empty' => false, 'orderby'=> 'term_group'));
|
151 |
$languages = empty($languages) || is_wp_error($languages) ? array() : $languages;
|
@@ -164,6 +167,13 @@ class PLL_Model {
|
|
164 |
$languages = array(); // in case something went wrong
|
165 |
}
|
166 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
$this->cache->set('languages', $languages);
|
169 |
|
@@ -188,21 +198,20 @@ class PLL_Model {
|
|
188 |
* @since 1.4
|
189 |
*/
|
190 |
public function _languages_list() {
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
if (!defined('PLL_CACHE_HOME_URL') || PLL_CACHE_HOME_URL) {
|
196 |
-
$language->set_home_url();
|
197 |
-
}
|
198 |
-
}
|
199 |
|
200 |
-
|
201 |
-
|
|
|
|
|
202 |
}
|
203 |
|
204 |
foreach ($this->cache->get('languages') as $language) {
|
205 |
-
|
|
|
206 |
$language->set_home_url();
|
207 |
|
208 |
// ensures that the (possibly cached) home url uses the right scheme http or https
|
@@ -272,10 +281,14 @@ class PLL_Model {
|
|
272 |
* @param array $translations: an associative array of translations with language code as key and translation id as value
|
273 |
*/
|
274 |
public function save_translations($type, $id, $translations) {
|
275 |
-
|
276 |
|
|
|
|
|
|
|
277 |
$translations = array_merge(array($lang->slug => $id), $translations); // make sure this object is in translations
|
278 |
$translations = array_diff($translations, array(0)); // don't keep non translated languages
|
|
|
279 |
|
280 |
// unlink removed translations
|
281 |
$old_translations = $this->get_translations($type, $id);
|
@@ -324,6 +337,7 @@ class PLL_Model {
|
|
324 |
*/
|
325 |
public function delete_translation($type, $id) {
|
326 |
global $wpdb;
|
|
|
327 |
$term = $this->get_object_term($id, $type . '_translations');
|
328 |
|
329 |
if (!empty($term)) {
|
@@ -364,7 +378,7 @@ class PLL_Model {
|
|
364 |
|
365 |
$translations = $this->get_translations($type, $id);
|
366 |
|
367 |
-
return isset($translations[$lang->slug]) ?
|
368 |
}
|
369 |
|
370 |
/*
|
@@ -393,7 +407,7 @@ class PLL_Model {
|
|
393 |
* @param int|string|object language (term_id or slug or object)
|
394 |
*/
|
395 |
public function set_post_language($post_id, $lang) {
|
396 |
-
wp_set_post_terms($post_id, $lang ? $this->get_language($lang)->slug : '', 'language' );
|
397 |
}
|
398 |
|
399 |
/*
|
@@ -419,7 +433,7 @@ class PLL_Model {
|
|
419 |
* @return bool|int the translation post id if exists, otherwise the post id, false if the post has no language
|
420 |
*/
|
421 |
public function get_post($post_id, $lang) {
|
422 |
-
$post_lang = $this->get_post_language($post_id);
|
423 |
if (!$lang || !$post_lang)
|
424 |
return false;
|
425 |
|
@@ -436,6 +450,7 @@ class PLL_Model {
|
|
436 |
* @param int|string|object language (term_id or slug or object)
|
437 |
*/
|
438 |
public function set_term_language($term_id, $lang) {
|
|
|
439 |
wp_set_object_terms($term_id, $lang ? $this->get_language($lang)->tl_term_id : '', 'term_language');
|
440 |
|
441 |
// add translation group for correct WXR export
|
@@ -765,6 +780,8 @@ class PLL_Model {
|
|
765 |
public function term_exists($term_name, $taxonomy, $parent, $language) {
|
766 |
global $wpdb;
|
767 |
|
|
|
|
|
768 |
$select = "SELECT t.term_id FROM $wpdb->terms AS t";
|
769 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
770 |
$join .= $this->join_clause('term');
|
61 |
public function _prime_terms_cache($terms, $taxonomies) {
|
62 |
if ($this->is_translated_taxonomy($taxonomies)) {
|
63 |
foreach ($terms as $term) {
|
64 |
+
$term_ids[] = is_object($term) ? $term->term_id : (int) $term;
|
65 |
}
|
66 |
}
|
67 |
|
101 |
if (empty($object_id))
|
102 |
return false;
|
103 |
|
104 |
+
$object_id = (int) $object_id;
|
105 |
$term = get_object_term_cache($object_id, $taxonomy);
|
106 |
|
107 |
if (false === $term) {
|
147 |
*/
|
148 |
public function get_languages_list($args = array()) {
|
149 |
if (false === $languages = $this->cache->get('languages')) {
|
150 |
+
|
151 |
+
// create the languages from taxonomies
|
152 |
if ((defined('PLL_CACHE_LANGUAGES') && !PLL_CACHE_LANGUAGES) || false === ($languages = get_transient('pll_languages_list'))) {
|
153 |
$languages = get_terms('language', array('hide_empty' => false, 'orderby'=> 'term_group'));
|
154 |
$languages = empty($languages) || is_wp_error($languages) ? array() : $languages;
|
167 |
$languages = array(); // in case something went wrong
|
168 |
}
|
169 |
}
|
170 |
+
|
171 |
+
// create the languages directly from arrays stored in transients
|
172 |
+
else {
|
173 |
+
foreach ($languages as $k => $v) {
|
174 |
+
$languages[$k] = new PLL_Language($v);
|
175 |
+
}
|
176 |
+
}
|
177 |
|
178 |
$this->cache->set('languages', $languages);
|
179 |
|
198 |
* @since 1.4
|
199 |
*/
|
200 |
public function _languages_list() {
|
201 |
+
// cache the languages after getting the home urls
|
202 |
+
if ((!defined('PLL_CACHE_LANGUAGES') || PLL_CACHE_LANGUAGES) && false === get_transient('pll_languages_list')) {
|
203 |
+
foreach ($languages = $this->cache->get('languages') as $language)
|
204 |
+
$language->set_home_url();
|
|
|
|
|
|
|
|
|
205 |
|
206 |
+
// don't store directly objects as it badly break with some hosts (GoDaddy) due to race conditions when using object cache
|
207 |
+
// thanks to captin411 for catching this!
|
208 |
+
// see https://wordpress.org/support/topic/fatal-error-pll_model_languages_list?replies=8#post-6782255
|
209 |
+
set_transient('pll_languages_list', array_map(create_function('$o', 'return (array) $o;'), $languages));
|
210 |
}
|
211 |
|
212 |
foreach ($this->cache->get('languages') as $language) {
|
213 |
+
// get the home urls when not cached
|
214 |
+
if ((defined('PLL_CACHE_LANGUAGES') && !PLL_CACHE_LANGUAGES) || (defined('PLL_CACHE_HOME_URL') && !PLL_CACHE_HOME_URL))
|
215 |
$language->set_home_url();
|
216 |
|
217 |
// ensures that the (possibly cached) home url uses the right scheme http or https
|
281 |
* @param array $translations: an associative array of translations with language code as key and translation id as value
|
282 |
*/
|
283 |
public function save_translations($type, $id, $translations) {
|
284 |
+
$id = (int) $id;
|
285 |
|
286 |
+
if (($lang = call_user_func(array(&$this, 'get_'.$type.'_language'), $id)) && isset($translations) && is_array($translations)) {
|
287 |
+
// sanitize the translations array
|
288 |
+
$translations = array_map('intval', $translations);
|
289 |
$translations = array_merge(array($lang->slug => $id), $translations); // make sure this object is in translations
|
290 |
$translations = array_diff($translations, array(0)); // don't keep non translated languages
|
291 |
+
$translations = array_intersect_key($translations, array_flip($this->get_languages_list(array('fields' => 'slug')))); // keep only valid languages slugs as keys
|
292 |
|
293 |
// unlink removed translations
|
294 |
$old_translations = $this->get_translations($type, $id);
|
337 |
*/
|
338 |
public function delete_translation($type, $id) {
|
339 |
global $wpdb;
|
340 |
+
$id = (int) $id;
|
341 |
$term = $this->get_object_term($id, $type . '_translations');
|
342 |
|
343 |
if (!empty($term)) {
|
378 |
|
379 |
$translations = $this->get_translations($type, $id);
|
380 |
|
381 |
+
return isset($translations[$lang->slug]) ? $translations[$lang->slug] : false;
|
382 |
}
|
383 |
|
384 |
/*
|
407 |
* @param int|string|object language (term_id or slug or object)
|
408 |
*/
|
409 |
public function set_post_language($post_id, $lang) {
|
410 |
+
wp_set_post_terms((int) $post_id, $lang ? $this->get_language($lang)->slug : '', 'language' );
|
411 |
}
|
412 |
|
413 |
/*
|
433 |
* @return bool|int the translation post id if exists, otherwise the post id, false if the post has no language
|
434 |
*/
|
435 |
public function get_post($post_id, $lang) {
|
436 |
+
$post_lang = $this->get_post_language($post_id);
|
437 |
if (!$lang || !$post_lang)
|
438 |
return false;
|
439 |
|
450 |
* @param int|string|object language (term_id or slug or object)
|
451 |
*/
|
452 |
public function set_term_language($term_id, $lang) {
|
453 |
+
$term_id = (int) $term_id;
|
454 |
wp_set_object_terms($term_id, $lang ? $this->get_language($lang)->tl_term_id : '', 'term_language');
|
455 |
|
456 |
// add translation group for correct WXR export
|
780 |
public function term_exists($term_name, $taxonomy, $parent, $language) {
|
781 |
global $wpdb;
|
782 |
|
783 |
+
$term_name = trim(wp_unslash($term_name));
|
784 |
+
|
785 |
$select = "SELECT t.term_id FROM $wpdb->terms AS t";
|
786 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
787 |
$join .= $this->join_clause('term');
|
include/switcher.php
CHANGED
@@ -48,7 +48,7 @@ class PLL_Switcher {
|
|
48 |
foreach ($links->model->get_languages_list(array('hide_empty' => $args['hide_if_empty'])) as $language) {
|
49 |
$id = (int) $language->term_id;
|
50 |
$slug = $language->slug;
|
51 |
-
$classes = array('lang-item', 'lang-item-' .
|
52 |
|
53 |
if ($current_lang = pll_current_language() == $slug) {
|
54 |
if ($args['hide_current'] && !$args['dropdown'])
|
48 |
foreach ($links->model->get_languages_list(array('hide_empty' => $args['hide_if_empty'])) as $language) {
|
49 |
$id = (int) $language->term_id;
|
50 |
$slug = $language->slug;
|
51 |
+
$classes = array('lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr($slug));
|
52 |
|
53 |
if ($current_lang = pll_current_language() == $slug) {
|
54 |
if ($args['hide_current'] && !$args['dropdown'])
|
include/wpml-compat.php
CHANGED
@@ -256,7 +256,7 @@ if (!function_exists('wpml_get_copied_fields_for_post_edit')) {
|
|
256 |
return array();
|
257 |
|
258 |
// don't know what WPML does but Polylang does copy all public meta keys by default
|
259 |
-
foreach ($keys = array_unique(array_keys(get_post_custom($_GET['from_post']))) as $k => $meta_key)
|
260 |
if (is_protected_meta($meta_key))
|
261 |
unset ($keys[$k]);
|
262 |
|
256 |
return array();
|
257 |
|
258 |
// don't know what WPML does but Polylang does copy all public meta keys by default
|
259 |
+
foreach ($keys = array_unique(array_keys(get_post_custom((int) $_GET['from_post']))) as $k => $meta_key)
|
260 |
if (is_protected_meta($meta_key))
|
261 |
unset ($keys[$k]);
|
262 |
|
install/install-base.php
CHANGED
@@ -24,7 +24,6 @@ class PLL_Install_Base {
|
|
24 |
add_action('wpmu_new_blog', array(&$this, 'wpmu_new_blog'), 5); // before WP attempts to send mails which can break on some PHP versions
|
25 |
}
|
26 |
|
27 |
-
|
28 |
/*
|
29 |
* allows to detect plugin deactivation
|
30 |
*
|
@@ -43,9 +42,9 @@ class PLL_Install_Base {
|
|
43 |
*
|
44 |
* @param string $what either 'activate' or 'deactivate'
|
45 |
*/
|
46 |
-
protected function do_for_all_blogs($what) {
|
47 |
// network
|
48 |
-
if (is_multisite() &&
|
49 |
global $wpdb;
|
50 |
|
51 |
foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $blog_id) {
|
@@ -65,8 +64,8 @@ class PLL_Install_Base {
|
|
65 |
*
|
66 |
* @since 1.7
|
67 |
*/
|
68 |
-
public function activate() {
|
69 |
-
$this->do_for_all_blogs('activate');
|
70 |
}
|
71 |
|
72 |
/*
|
@@ -83,8 +82,8 @@ class PLL_Install_Base {
|
|
83 |
*
|
84 |
* @since 0.1
|
85 |
*/
|
86 |
-
public function deactivate() {
|
87 |
-
$this->do_for_all_blogs('deactivate');
|
88 |
}
|
89 |
|
90 |
/*
|
24 |
add_action('wpmu_new_blog', array(&$this, 'wpmu_new_blog'), 5); // before WP attempts to send mails which can break on some PHP versions
|
25 |
}
|
26 |
|
|
|
27 |
/*
|
28 |
* allows to detect plugin deactivation
|
29 |
*
|
42 |
*
|
43 |
* @param string $what either 'activate' or 'deactivate'
|
44 |
*/
|
45 |
+
protected function do_for_all_blogs($what, $networkwide) {
|
46 |
// network
|
47 |
+
if (is_multisite() && $networkwide) {
|
48 |
global $wpdb;
|
49 |
|
50 |
foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $blog_id) {
|
64 |
*
|
65 |
* @since 1.7
|
66 |
*/
|
67 |
+
public function activate($networkwide) {
|
68 |
+
$this->do_for_all_blogs('activate', $networkwide);
|
69 |
}
|
70 |
|
71 |
/*
|
82 |
*
|
83 |
* @since 0.1
|
84 |
*/
|
85 |
+
public function deactivate($networkwide) {
|
86 |
+
$this->do_for_all_blogs('deactivate', $networkwide);
|
87 |
}
|
88 |
|
89 |
/*
|
install/install.php
CHANGED
@@ -12,7 +12,7 @@ class PLL_Install extends PLL_Install_Base {
|
|
12 |
*
|
13 |
* @since 0.1
|
14 |
*/
|
15 |
-
public function activate() {
|
16 |
global $wp_version;
|
17 |
|
18 |
Polylang::define_constants();
|
@@ -27,7 +27,7 @@ class PLL_Install extends PLL_Install_Base {
|
|
27 |
)
|
28 |
));
|
29 |
|
30 |
-
$this->do_for_all_blogs('activate');
|
31 |
}
|
32 |
|
33 |
/*
|
12 |
*
|
13 |
* @since 0.1
|
14 |
*/
|
15 |
+
public function activate($networkwide) {
|
16 |
global $wp_version;
|
17 |
|
18 |
Polylang::define_constants();
|
27 |
)
|
28 |
));
|
29 |
|
30 |
+
$this->do_for_all_blogs('activate', $networkwide);
|
31 |
}
|
32 |
|
33 |
/*
|
polylang.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Polylang
|
4 |
Plugin URI: http://polylang.wordpress.com/
|
5 |
-
Version: 1.7.
|
6 |
Author: Frédéric Demarle
|
7 |
Description: Adds multilingual capability to WordPress
|
8 |
Text Domain: polylang
|
@@ -33,7 +33,7 @@ Domain Path: /languages
|
|
33 |
if (!function_exists('add_action'))
|
34 |
exit();
|
35 |
|
36 |
-
define('POLYLANG_VERSION', '1.7.
|
37 |
define('PLL_MIN_WP_VERSION', '3.8');
|
38 |
|
39 |
define('POLYLANG_BASENAME', plugin_basename(__FILE__)); // plugin name as known by WP
|
2 |
/*
|
3 |
Plugin Name: Polylang
|
4 |
Plugin URI: http://polylang.wordpress.com/
|
5 |
+
Version: 1.7.3
|
6 |
Author: Frédéric Demarle
|
7 |
Description: Adds multilingual capability to WordPress
|
8 |
Text Domain: polylang
|
33 |
if (!function_exists('add_action'))
|
34 |
exit();
|
35 |
|
36 |
+
define('POLYLANG_VERSION', '1.7.3');
|
37 |
define('PLL_MIN_WP_VERSION', '3.8');
|
38 |
|
39 |
define('POLYLANG_BASENAME', plugin_basename(__FILE__)); // plugin name as known by WP
|
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, international, localization
|
5 |
Requires at least: 3.8
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag: 1.7.
|
8 |
License: GPLv2 or later
|
9 |
|
10 |
Polylang adds multilingual content management support to WordPress.
|
@@ -67,6 +67,17 @@ See http://polylang.wordpress.com/documentation/contribute/
|
|
67 |
|
68 |
== Changelog ==
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
= 1.7.2 (2015-03-23) =
|
71 |
|
72 |
* fix: comments are filtered for posts in a post type not managed by Polylang
|
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, international, localization
|
5 |
Requires at least: 3.8
|
6 |
+
Tested up to: 4.2
|
7 |
+
Stable tag: 1.7.3
|
8 |
License: GPLv2 or later
|
9 |
|
10 |
Polylang adds multilingual content management support to WordPress.
|
67 |
|
68 |
== Changelog ==
|
69 |
|
70 |
+
= 1.7.3 (2015-04-11) =
|
71 |
+
|
72 |
+
* the transient 'pll_languages_list' now stores an array of arrays instead of an array of PLL_Language objects
|
73 |
+
* fix: fatal error for users hosted at GoDaddy (due to PLL_Language objects stored in a transient)
|
74 |
+
* fix: additional query vars are removed from home page
|
75 |
+
* fix: categories are not filtered by the admin language switcher in posts list table (introduced in 1.7)
|
76 |
+
* fix: when using multiple domains, the domain url is lost when modifying the language slug
|
77 |
+
* fix: the queried object is incorrectly set for author archives (introduced in 1.6.5)
|
78 |
+
* fix: notice when a nav menu assigned to a translated nav menu location has been deleted
|
79 |
+
* fix: no canonical redirection when using pretty permalinks and querying default permalinks
|
80 |
+
|
81 |
= 1.7.2 (2015-03-23) =
|
82 |
|
83 |
* fix: comments are filtered for posts in a post type not managed by Polylang
|