| 1 |
<?php |
| 2 |
|
| 3 |
require_once(dirname(__FILE__).'/list-table.php'); |
| 4 |
|
| 5 |
class Polylang_Admin extends Polylang_Base { |
| 6 |
function __construct() { |
| 7 |
// adds a 'settings' link in the plugins table |
| 8 |
$plugin_file = basename( dirname( __FILE__ ) ).'/polylang.php'; |
| 9 |
add_filter('plugin_action_links_'.$plugin_file, array(&$this, 'plugin_action_links')); |
| 10 |
|
| 11 |
// adds the link to the languages panel in the wordpress admin menu |
| 12 |
add_action('admin_menu', array(&$this, 'add_menus')); |
| 13 |
|
| 14 |
// add the language column (as well as a filter by language) in 'All Posts' an 'All Pages' panels |
| 15 |
add_filter('manage_posts_columns', array(&$this, 'add_post_column'), 10, 2); |
| 16 |
add_filter('manage_pages_columns', array(&$this, 'add_post_column')); |
| 17 |
add_action('manage_posts_custom_column', array(&$this, 'post_column'), 10, 2); |
| 18 |
add_action('manage_pages_custom_column', array(&$this, 'post_column'), 10, 2); |
| 19 |
add_filter('parse_query',array(&$this,'parse_query')); |
| 20 |
add_action('restrict_manage_posts', array(&$this, 'restrict_manage_posts')); |
| 21 |
|
| 22 |
// adds the Languages box in the 'Edit Post' and 'Edit Page' panels |
| 23 |
add_action('add_meta_boxes', array(&$this, 'add_meta_boxes')); |
| 24 |
|
| 25 |
// adds actions related to languages when saving aor deleting posts and pages |
| 26 |
add_action('save_post', array(&$this, 'save_post')); |
| 27 |
add_action('before_delete_post', array(&$this, 'delete_post')); |
| 28 |
|
| 29 |
// adds the language field in the 'Categories' and 'Post Tags' panels |
| 30 |
add_action('category_add_form_fields', array(&$this, 'add_term_form')); |
| 31 |
add_action('post_tag_add_form_fields', array(&$this, 'add_term_form')); |
| 32 |
|
| 33 |
// adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels |
| 34 |
add_action('category_edit_form_fields', array(&$this, 'edit_term_form')); |
| 35 |
add_action('post_tag_edit_form_fields', array(&$this, 'edit_term_form')); |
| 36 |
|
| 37 |
// adds the language column in the 'Categories' and 'Post Tags' tables |
| 38 |
add_filter('manage_edit-category_columns', array(&$this, 'add_term_column')); |
| 39 |
add_filter('manage_edit-post_tag_columns', array(&$this, 'add_term_column')); |
| 40 |
add_action('manage_category_custom_column', array(&$this, 'term_column'), 10, 3); |
| 41 |
add_action('manage_post_tag_custom_column', array(&$this, 'term_column'), 10, 3); |
| 42 |
|
| 43 |
// adds actions related to languages when saving or deleting categories and post tags |
| 44 |
add_action('created_category', array(&$this,'save_term')); |
| 45 |
add_action('created_post_tag', array(&$this,'save_term')); |
| 46 |
add_action('edited_category', array(&$this,'save_term')); |
| 47 |
add_action('edited_post_tag', array(&$this,'save_term')); |
| 48 |
add_action('delete_category', array(&$this,'delete_term')); |
| 49 |
add_action('delete_post_tag', array(&$this,'delete_term')); |
| 50 |
|
| 51 |
// refresh rewrite rules if the 'page_on_front' option is modified |
| 52 |
add_action('update_option', array(&$this,'update_option')); |
| 53 |
} |
| 54 |
|
| 55 |
// adds a 'settings' link in the plugins table |
| 56 |
function plugin_action_links($links) { |
| 57 |
$settings_link = '<a href="admin.php?page=mlang">' . __('Settings') . '</a>'; |
| 58 |
array_unshift( $links, $settings_link ); |
| 59 |
return $links; |
| 60 |
} |
| 61 |
|
| 62 |
// adds the link to the languages panel in the wordpress admin menu |
| 63 |
function add_menus() { |
| 64 |
add_submenu_page('options-general.php', __('Languages','polylang'), __('Languages','polylang'), 'manage_options', 'mlang', array($this, 'languages_page')); |
| 65 |
} |
| 66 |
|
| 67 |
// the languages panel |
| 68 |
function languages_page() { |
| 69 |
global $wp_rewrite; |
| 70 |
$options = get_option('polylang'); |
| 71 |
|
| 72 |
$listlanguages = $this->get_languages_list(); |
| 73 |
$list_table = new Polylang_List_Table(); |
| 74 |
|
| 75 |
$action = ''; |
| 76 |
if (isset($_REQUEST['action'])) |
| 77 |
$action = $_REQUEST['action']; |
| 78 |
|
| 79 |
switch ($action) { |
| 80 |
case 'add': |
| 81 |
check_admin_referer( 'add-lang', '_wpnonce_add-lang' ); |
| 82 |
|
| 83 |
if (isset($_POST['name']) && isset($_POST['description'])) { |
| 84 |
wp_insert_term($_POST['name'],'language',array('slug'=>$_POST['slug'], 'description'=>$_POST['description'])); |
| 85 |
$wp_rewrite->flush_rules(); // refresh rewrite rules |
| 86 |
} |
| 87 |
if (!isset($options['default_lang'])) { // if this is the first language created, set it as default language |
| 88 |
$options['default_lang'] = $_POST['slug']; |
| 89 |
update_option('polylang', $options); |
| 90 |
} |
| 91 |
wp_redirect('admin.php?page=mlang'); // to refresh the page (possible thanks to the $_GET['noheader']=true) |
| 92 |
exit; |
| 93 |
break; |
| 94 |
|
| 95 |
case 'delete': |
| 96 |
check_admin_referer( 'delete-lang'); |
| 97 |
|
| 98 |
if (isset($_GET['lang'])) { |
| 99 |
$lang = $this->get_language($_GET['lang']); |
| 100 |
$lang_slug = $lang->slug; |
| 101 |
|
| 102 |
// delete all translations in posts in this language |
| 103 |
$args = array('numberposts'=>-1, 'taxonomy' => 'language', 'term' => $lang_slug, 'post_type'=>'any', 'post_status'=>'any'); |
| 104 |
$posts = get_posts($args); |
| 105 |
foreach ($posts as $post) { |
| 106 |
foreach ($languages as $language) { |
| 107 |
delete_post_meta($post->ID, '_lang-'.$language->slug); |
| 108 |
} |
| 109 |
} |
| 110 |
|
| 111 |
// delete references to this language in all posts |
| 112 |
$args = array('numberposts'=>-1, 'meta_key'=>'_lang-'.$lang_slug, 'post_type'=>'any', 'post_status'=>'any'); |
| 113 |
$posts = get_posts($args); |
| 114 |
foreach ($posts as $post) { |
| 115 |
delete_post_meta($post->ID, '_lang-'.$lang_slug); |
| 116 |
} |
| 117 |
|
| 118 |
// delete references to this language in categories & post tags |
| 119 |
$terms = get_terms(array('category', 'post_tag'), 'get=all'); |
| 120 |
foreach ($terms as $term) { |
| 121 |
if ($this->get_term_language($term->term_id) == $lang) { |
| 122 |
foreach ($languages as $language) { |
| 123 |
delete_metadata('term', $term->term_id, '_lang-'.$language->slug); // deletes translations of this term |
| 124 |
} |
| 125 |
delete_metadata('term', $term->term_id, '_language', $_GET['lang']); // delete language of this term |
| 126 |
} |
| 127 |
delete_metadata('term', $term->term_id, '_lang-'.$lang_slug); // deletes references to this term in translated term |
| 128 |
} |
| 129 |
|
| 130 |
// delete the language itself |
| 131 |
wp_delete_term($_GET['lang'], 'language'); |
| 132 |
$wp_rewrite->flush_rules(); // refresh rewrite rules |
| 133 |
|
| 134 |
// oops ! we deleted the default language... |
| 135 |
if ($options['default_lang'] == $lang_slug) { |
| 136 |
if (!empty($languages)) |
| 137 |
$options['default_lang'] = $languages[0]->slug; // arbitrary choice... |
| 138 |
else |
| 139 |
unset($options['default_lang']); |
| 140 |
update_option('polylang', $options); |
| 141 |
} |
| 142 |
} |
| 143 |
wp_redirect('admin.php?page=mlang'); // to refresh the page (possible thanks to the $_GET['noheader']=true) |
| 144 |
exit; |
| 145 |
break; |
| 146 |
|
| 147 |
case 'edit': |
| 148 |
if (isset($_GET['lang'])) |
| 149 |
$edit_lang = $this->get_language($_GET['lang']); |
| 150 |
break; |
| 151 |
|
| 152 |
case 'update': |
| 153 |
check_admin_referer( 'add-lang', '_wpnonce_add-lang' ); |
| 154 |
|
| 155 |
if (isset($_POST['lang'])) { |
| 156 |
// Update links to this language in posts and terms in case the slug has been modified |
| 157 |
$lang = $this->get_language($_POST['lang']); |
| 158 |
$old_slug = $lang->slug; |
| 159 |
|
| 160 |
if ($old_slug != $_POST['slug']) { |
| 161 |
// update the language slug in posts meta |
| 162 |
$args = array('numberposts'=>-1, 'meta_key'=>'_lang-'.$old_slug, 'post_type'=>'any', 'post_status'=>'any'); |
| 163 |
$posts = get_posts($args); |
| 164 |
foreach ($posts as $post) { |
| 165 |
$post_id = get_post_meta($post->ID, '_lang-'.$old_slug, true); |
| 166 |
delete_post_meta($post->ID, '_lang-'.$old_slug); |
| 167 |
update_post_meta($post->ID, '_lang-'.$_POST['slug'], $post_id); |
| 168 |
} |
| 169 |
|
| 170 |
// update the language slug in categories & post tags meta |
| 171 |
$terms = get_terms(array('category', 'post_tag'), 'get=all'); |
| 172 |
foreach ($terms as $term) { |
| 173 |
$term_id = get_metadata('term', $term->term_id, '_lang-'.$old_slug, true); |
| 174 |
if ($term_id) { |
| 175 |
delete_metadata('term', $term->term_id, '_lang-'.$old_slug); |
| 176 |
update_metadata('term', $term->term_id, '_lang-'.$_POST['slug'], $term_id); |
| 177 |
} |
| 178 |
} |
| 179 |
} |
| 180 |
|
| 181 |
// and finally update the language itself |
| 182 |
wp_update_term($_POST['lang'], 'language', array('name'=>$_POST['name'], 'slug'=>$_POST['slug'], 'description'=>$_POST['description'])); |
| 183 |
$wp_rewrite->flush_rules(); // refresh rewrite rules |
| 184 |
} |
| 185 |
wp_redirect('admin.php?page=mlang'); // to refresh the page (possible thanks to the $_GET['noheader']=true) |
| 186 |
exit; |
| 187 |
break; |
| 188 |
|
| 189 |
case 'options': |
| 190 |
check_admin_referer( 'options-lang', '_wpnonce_options-lang' ); |
| 191 |
|
| 192 |
$options['rewrite'] = $_POST['rewrite']; |
| 193 |
isset($_POST['browser']) ? $options['browser'] = 1 : $options['browser'] = 0; |
| 194 |
$options['default_lang'] = $_POST['default_lang']; |
| 195 |
update_option('polylang', $options); |
| 196 |
|
| 197 |
// refresh refresh permalink structure and rewrite rules in case rewrite option has been modified |
| 198 |
$wp_rewrite->extra_permastructs['language'][0] = $options['rewrite'] ? '%language%' : '/language/%language%'; |
| 199 |
$wp_rewrite->flush_rules(); |
| 200 |
break; |
| 201 |
|
| 202 |
default: |
| 203 |
} |
| 204 |
|
| 205 |
// prepare the list table of languages |
| 206 |
$data = array(); |
| 207 |
foreach ($listlanguages as $lang) |
| 208 |
$data[] = (array) $lang; |
| 209 |
|
| 210 |
$list_table->prepare_items($data); |
| 211 |
|
| 212 |
// displays the page |
| 213 |
include(dirname(__FILE__).'/languages-form.php'); |
| 214 |
} |
| 215 |
|
| 216 |
// adds the language column (before the date column) in the posts and pages list table |
| 217 |
function add_post_column($columns, $post_type ='') { |
| 218 |
if (in_array($post_type, array('', 'post', 'page'))) { |
| 219 |
$keys = array( 'date', 'comments' ); |
| 220 |
foreach ($keys as $k) { |
| 221 |
if (array_key_exists($k, $columns)) |
| 222 |
$end[$k] = array_pop($columns); |
| 223 |
} |
| 224 |
|
| 225 |
$columns['language'] = __('Language', 'polylang'); |
| 226 |
|
| 227 |
if (isset($end)) |
| 228 |
$columns = array_merge($columns, $end); |
| 229 |
} |
| 230 |
return $columns; |
| 231 |
} |
| 232 |
|
| 233 |
// fills the language column in the posts table |
| 234 |
function post_column($column, $post_id) { |
| 235 |
$lang = $this->get_post_language($post_id); |
| 236 |
if ($lang && $column == 'language') |
| 237 |
echo $lang->name; |
| 238 |
} |
| 239 |
|
| 240 |
// converts language term_id to slug in $query |
| 241 |
// needed to filter the posts by language with wp_dropdown_categories in restrict_manage_posts |
| 242 |
function parse_query($query) { |
| 243 |
global $pagenow; |
| 244 |
$qvars = &$query->query_vars; |
| 245 |
if ($pagenow=='edit.php' && isset($qvars['lang']) && is_numeric($qvars['lang'])) { |
| 246 |
$lang = $this->get_language($qvars['lang']); |
| 247 |
if ($lang) |
| 248 |
$qvars['lang'] = $lang->slug; |
| 249 |
} |
| 250 |
} |
| 251 |
|
| 252 |
// adds a filter for languages in the Posts and Pages panels |
| 253 |
function restrict_manage_posts() { |
| 254 |
global $typenow; |
| 255 |
global $wp_query; |
| 256 |
$languages = $this->get_languages_list(); |
| 257 |
|
| 258 |
if (!empty($languages) && in_array($typenow, array('', 'post', 'page'))) { |
| 259 |
$qvars = $wp_query->query; |
| 260 |
wp_dropdown_categories(array( |
| 261 |
'show_option_all' => __('Show all languages', 'polylang'), |
| 262 |
'name' => 'lang', |
| 263 |
'selected' => isset($qvars['lang']) ? $qvars['lang'] : 0, |
| 264 |
'taxonomy' => 'language')); |
| 265 |
} |
| 266 |
} |
| 267 |
|
| 268 |
// adds the Languages box in the 'Edit Post' and 'Edit Page' panels |
| 269 |
function add_meta_boxes() { |
| 270 |
add_meta_box('ml_box', __('Languages','multiLang'), array(&$this,'post_language'), 'post', 'side','high'); |
| 271 |
add_meta_box('ml_box', __('Languages','multiLang'), array(&$this,'post_language'), 'page', 'side','high'); |
| 272 |
} |
| 273 |
|
| 274 |
// the Languages metabox in the 'Edit Post' and 'Edit Page' panels |
| 275 |
function post_language() { |
| 276 |
global $post_ID; |
| 277 |
$post_type = get_post_type($post_ID); |
| 278 |
|
| 279 |
$lang = $this->get_post_language($post_ID); |
| 280 |
if (isset($_GET['new_lang'])) |
| 281 |
$lang = $this->get_language($_GET['new_lang']); |
| 282 |
|
| 283 |
include(dirname(__FILE__).'/post-metabox.php'); |
| 284 |
} |
| 285 |
|
| 286 |
// called when a post (or page) is saved, published or updated |
| 287 |
// the underscore in '_lang' hides the post meta in the Custom Fields metabox in the Edit Post screen |
| 288 |
function save_post($post_id) { |
| 289 |
$id = wp_is_post_revision($post_id); |
| 290 |
if ($id) |
| 291 |
$post_id = $id; |
| 292 |
|
| 293 |
if (isset($_POST['lang_choice'])) |
| 294 |
wp_set_object_terms($post_id, $_POST['lang_choice'], 'language' ); |
| 295 |
|
| 296 |
$lang = $this->get_post_language($post_id); |
| 297 |
$listlanguages = $this->get_languages_list(); |
| 298 |
foreach ($listlanguages as $language) { |
| 299 |
if (isset($_POST[$language->slug])) { |
| 300 |
$value = $_POST[$language->slug]; |
| 301 |
if ($value) |
| 302 |
update_post_meta($post_id, '_lang-'.$language->slug, $value); // saves the links to translated posts |
| 303 |
} |
| 304 |
if ($lang && $language != $lang){ |
| 305 |
update_post_meta($this->get_translated_post($post_id, $language), '_lang-'.$lang->slug, $post_id); // tells the translated to link to this post |
| 306 |
} |
| 307 |
} |
| 308 |
|
| 309 |
// propagates translations between them |
| 310 |
foreach ($listlanguages as $language) { |
| 311 |
foreach ($listlanguages as $lg) { |
| 312 |
$id = $this->get_translated_post($post_id, $lg); |
| 313 |
if ($lg != $lang && $lg != $language && $id) |
| 314 |
update_post_meta($this->get_translated_post($post_id, $language), '_lang-'.$lg->slug, $id); |
| 315 |
} |
| 316 |
} |
| 317 |
} |
| 318 |
|
| 319 |
// called when a post (or page) is deleted |
| 320 |
function delete_post($post_id) { |
| 321 |
$id = wp_is_post_revision($post_id); |
| 322 |
if ($id) |
| 323 |
$post_id = $id; |
| 324 |
|
| 325 |
$lang = $this->get_post_language($post_id); |
| 326 |
if($lang) { |
| 327 |
$listlanguages = $this->get_languages_list(); |
| 328 |
foreach ($listlanguages as $language) { |
| 329 |
delete_post_meta($this->get_translated_post($post_id, $language), '_lang-'.$lang->slug); // delete links to this post |
| 330 |
// WP deletes post metas linked to this post so it is useless to do it before |
| 331 |
} |
| 332 |
} |
| 333 |
} |
| 334 |
|
| 335 |
// adds the language field in the 'Categories' and 'Post Tags' panels |
| 336 |
function add_term_form() { |
| 337 |
$lang = NULL; |
| 338 |
if (isset($_GET['new_lang'])) |
| 339 |
$lang = $this->get_language($_GET['new_lang']); |
| 340 |
|
| 341 |
$listlanguages = $this->get_languages_list(); |
| 342 |
|
| 343 |
// displays the language field |
| 344 |
include(dirname(__FILE__).'/add-term-form.php'); |
| 345 |
} |
| 346 |
|
| 347 |
// adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels |
| 348 |
function edit_term_form($tag) { |
| 349 |
$term_id = $tag->term_id; |
| 350 |
$lang = $this->get_term_language($term_id); |
| 351 |
|
| 352 |
$listlanguages = $this->get_languages_list(); |
| 353 |
$taxonomy = $tag->taxonomy; |
| 354 |
|
| 355 |
include(dirname(__FILE__).'/edit-term-form.php'); |
| 356 |
} |
| 357 |
|
| 358 |
// adds the language column (before the posts column) in the 'Categories' or Post Tags table |
| 359 |
function add_term_column($columns) { |
| 360 |
if (array_key_exists('posts', $columns)) |
| 361 |
$end = array_pop($columns); |
| 362 |
|
| 363 |
$columns['language'] = __('Language', 'polylang'); |
| 364 |
|
| 365 |
if (isset($end)) |
| 366 |
$columns['posts'] = $end; |
| 367 |
|
| 368 |
return $columns; |
| 369 |
} |
| 370 |
|
| 371 |
// fills the language column in the 'Categories' or Post Tags table |
| 372 |
function term_column($empty, $column, $term_id) { |
| 373 |
$lang = $this->get_term_language($term_id); |
| 374 |
if ($lang && $column == 'language') |
| 375 |
echo $lang->name; |
| 376 |
} |
| 377 |
|
| 378 |
// called when a category or post tag is created or edited |
| 379 |
function save_term($term_id) { |
| 380 |
if (isset($_POST['lang_choice']) && $_POST['lang_choice'] != -1 ) { |
| 381 |
update_metadata('term', $term_id, '_language', $_POST['lang_choice'] ); |
| 382 |
$lang = $this->get_language($_POST['lang_choice']); |
| 383 |
|
| 384 |
$listlanguages = $this->get_languages_list(); |
| 385 |
foreach ($listlanguages as $language) { |
| 386 |
$slug = '_lang-'.$language->slug; |
| 387 |
if (isset($_POST[$slug]) && $_POST[$slug] != -1) { |
| 388 |
update_metadata('term', $term_id, $slug, $_POST[$slug] ); |
| 389 |
update_metadata('term', $_POST[$slug], '_lang-'.$lang->slug, $term_id ); |
| 390 |
} |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
$qvars = $this->get_referer_vars(); |
| 395 |
if (isset($qvars['from_tag']) && isset($qvars['from_lang']) && isset($qvars['new_lang'])) { |
| 396 |
$from_lang = $this->get_language($qvars['from_lang']); |
| 397 |
update_metadata('term', $term_id, '_lang-'.$from_lang->slug, $qvars['from_tag'] ); |
| 398 |
$new_lang = $this->get_language($qvars['new_lang']); |
| 399 |
update_metadata('term', $qvars['from_tag'], '_lang-'.$new_lang->slug, $term_id ); |
| 400 |
} |
| 401 |
|
| 402 |
// propagates translations between them |
| 403 |
foreach ($listlanguages as $language) { |
| 404 |
foreach ($listlanguages as $lg) { |
| 405 |
$id = $this->get_translated_term($term_id, $lg); |
| 406 |
if ($lg != $lang && $lg != $language && $id) |
| 407 |
update_metadata('term',$this->get_translated_term($term_id, $language), '_lang-'.$lg->slug, $id); |
| 408 |
} |
| 409 |
} |
| 410 |
} |
| 411 |
|
| 412 |
// called when a category or post tag is deleted |
| 413 |
function delete_term($term_id) { |
| 414 |
$lang = $this->get_term_language($term_id); |
| 415 |
if($lang) { |
| 416 |
delete_metadata('term', $term_id, '_language' ); |
| 417 |
$listlanguages = $this->get_languages_list(); |
| 418 |
foreach ($listlanguages as $language) { |
| 419 |
delete_metadata('term', $this->get_translated_term($term_id, $language), '_lang-'.$lang->slug); // delete links to this term |
| 420 |
} |
| 421 |
foreach ($listlanguages as $language) { |
| 422 |
delete_metadata('term', $term_id, '_lang-'.$language->slug); |
| 423 |
} |
| 424 |
} |
| 425 |
} |
| 426 |
|
| 427 |
// returns all terms in the $taxonomy in the $term_language which have no translation in the $translation_language |
| 428 |
function get_terms_not_translated($taxonomy, $term_language, $translation_language) { |
| 429 |
$new_terms = array(); |
| 430 |
$terms = get_terms($taxonomy, 'hide_empty=0'); |
| 431 |
foreach ($terms as $term) { |
| 432 |
$lang = $this->get_term_language($term->term_id); |
| 433 |
if ($lang && $lang->name == $term_language->name) { |
| 434 |
$translated_term = $this->get_translated_term($term->term_id, $translation_language); |
| 435 |
if (!$translated_term) |
| 436 |
$new_terms[] = $term; |
| 437 |
} |
| 438 |
} |
| 439 |
return $new_terms; |
| 440 |
} |
| 441 |
|
| 442 |
// refresh rewrite rules if the 'page_on_front' option is modified |
| 443 |
function update_option($option) { |
| 444 |
global $wp_rewrite; |
| 445 |
if ($option == 'page_on_front') |
| 446 |
$wp_rewrite->flush_rules(); |
| 447 |
} |
| 448 |
} // class Polylang_Admin |
| 449 |
|
| 450 |
?> |
| 451 |
|